summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2019-07-01 17:28:32 -0700
committerWilliam A. Kennington III <wak@google.com>2019-07-08 16:26:42 -0700
commit079cba7212a9a2e5eb7260492696675d67979346 (patch)
treef0e0c292fd67ee96883f76b004a26fa66f86657d
parentcbaeb1a38314cb92bfa487659ae9225e28421091 (diff)
downloadstdplus-079cba7212a9a2e5eb7260492696675d67979346.tar.gz
stdplus-079cba7212a9a2e5eb7260492696675d67979346.zip
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>
-rw-r--r--src/stdplus/handle/managed.hpp25
-rw-r--r--test/handle/managed.cpp21
2 files changed, 46 insertions, 0 deletions
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 @@ struct Managed
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 @@ TEST_F(ManagedHandleTest, EmptyNoStorage)
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 @@ TEST_F(ManagedHandleTest, ResetNewPopulatedWithStorage)
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;
OpenPOWER on IntegriCloud