diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-10-07 22:03:56 +0200 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2024-10-07 22:03:56 +0200 |
commit | 3f62112e3a1b180a9b931d6f43b3cdc74e7ba3b9 (patch) | |
tree | a8201bf501f2c9690e51109d8be31c2fb4af7e4a | |
parent | af7a61a5464c266426a20e7dacf6c52bb80b28e9 (diff) | |
download | cpp-utils-main.tar.gz cpp-utils-main.zip |
-rw-r--r-- | option.h | 37 | ||||
-rw-r--r-- | test/option.cc | 12 |
2 files changed, 46 insertions, 3 deletions
@@ -29,7 +29,7 @@ struct option { // -- CONSTRUCTOR - NONE ----------------------------------------------------- constexpr option() = default; - constexpr option(none) : option() {} + constexpr option(none) noexcept : option() {} // -- CONSTRUCTOR - VALUE ---------------------------------------------------- @@ -47,11 +47,40 @@ struct option { } } - template <typename U = T> - constexpr option(T&& val) : m_has_value{true} { + constexpr option(const T& val) : m_has_value{true} { + new (&m_value) T(val); + } + + constexpr option(T&& val) noexcept : m_has_value{true} { new (&m_value) T(std::move(val)); } + // -- ASSIGNMENT ------------------------------------------------------------- + + constexpr option& operator=(const option& op) { + if (this == &op) { + return *this; + } + reset(); + if (op.has_value()) { + new (&m_value) T(op.value()); + m_has_value = true; + } + return *this; + } + + constexpr option& operator=(option&& op) noexcept { + if (this == &op) { + return *this; + } + reset(); + if (op.has_value()) { + new (&m_value) T(std::move(op.take())); + m_has_value = true; + } + return *this; + } + // -- DESTRUCTOR ------------------------------------------------------------- ~option() { @@ -62,6 +91,8 @@ struct option { template <typename... Params> constexpr T& emplace(Params&&... params) { + static_assert(std::is_constructible<T, Params...>::value, + "T not constructible from Params..."); reset(); new (&m_value) T(std::forward<Params>(params)...); m_has_value = true; diff --git a/test/option.cc b/test/option.cc index 09c0fdf..4aa08a1 100644 --- a/test/option.cc +++ b/test/option.cc @@ -61,6 +61,18 @@ int main() { assert(!o2.has_value()); assert(o4.has_value()); + option<checker> o5; + // copy assign + o5 = o4; + assert(o4.has_value()); + assert(o5.has_value()); + + option<checker> o6; + // move assign + o6 = std::move(o5); + assert(!o5.has_value()); + assert(o6.has_value()); + // take reference to inner auto x = o3.value(); // take ownership of inner |