handle: Support for releasing management of values
Sometimes we want to be able to break the value out of the container and
unmanage it.
Change-Id: I1ded8571561760f7adf8bbf9a24cf21c989e4898
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/stdplus/handle/managed.hpp b/src/stdplus/handle/managed.hpp
index 9b9bfb5..de6a9f1 100644
--- a/src/stdplus/handle/managed.hpp
+++ b/src/stdplus/handle/managed.hpp
@@ -161,6 +161,31 @@
reset(std::nullopt);
}
+ /** @brief Releases the managed value and transfers ownership
+ * to the caller.
+ *
+ * @throws std::bad_optional_access if it has no object
+ * @return The value that was managed
+ */
+ [[nodiscard]] constexpr T release()
+ {
+ T ret = std::move(maybeT.value());
+ maybeT = std::nullopt;
+ return ret;
+ }
+
+ /** @brief Releases the managed value and transfers ownership
+ * to the caller.
+ *
+ * @return Maybe the value that was managed
+ */
+ [[nodiscard]] constexpr std::optional<T> maybe_release() noexcept
+ {
+ std::optional<T> ret = std::move(maybeT);
+ maybeT = std::nullopt;
+ return ret;
+ }
+
/** @brief Reference the contained data
*
* @return A reference to the contained data
diff --git a/test/handle/managed.cpp b/test/handle/managed.cpp
index b3ba6a6..155ba59 100644
--- a/test/handle/managed.cpp
+++ b/test/handle/managed.cpp
@@ -48,10 +48,13 @@
SimpleHandle h(std::nullopt);
EXPECT_FALSE(h);
EXPECT_THROW(h.value(), std::bad_optional_access);
+ EXPECT_THROW((void)h.release(), std::bad_optional_access);
h.reset();
EXPECT_FALSE(h.has_value());
EXPECT_THROW(h.value(), std::bad_optional_access);
+ EXPECT_THROW((void)h.release(), std::bad_optional_access);
EXPECT_EQ(std::nullopt, h.maybe_value());
+ EXPECT_EQ(std::nullopt, h.maybe_release());
}
TEST_F(ManagedHandleTest, EmptyWithStorage)
@@ -164,6 +167,24 @@
dropped.clear();
}
+TEST_F(ManagedHandleTest, Release)
+{
+ constexpr int expected = 3;
+ int val = expected;
+ SimpleHandle h(std::move(val));
+ EXPECT_EQ(expected, h.release());
+ EXPECT_FALSE(h);
+}
+
+TEST_F(ManagedHandleTest, MaybeRelease)
+{
+ constexpr int expected = 3;
+ int val = expected;
+ SimpleHandle h(std::move(val));
+ EXPECT_EQ(expected, h.maybe_release());
+ EXPECT_FALSE(h);
+}
+
TEST_F(ManagedHandleTest, MoveConstructWithStorage)
{
constexpr int expected = 3;