From 3f62112e3a1b180a9b931d6f43b3cdc74e7ba3b9 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Mon, 7 Oct 2024 22:03:56 +0200 Subject: option: assignment operator + minor cleanup --- option.h | 37 ++++++++++++++++++++++++++++++++++--- test/option.cc | 12 ++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/option.h b/option.h index 20104d7..cd12f88 100644 --- a/option.h +++ b/option.h @@ -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 - 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 constexpr T& emplace(Params&&... params) { + static_assert(std::is_constructible::value, + "T not constructible from Params..."); reset(); new (&m_value) T(std::forward(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 o5; + // copy assign + o5 = o4; + assert(o4.has_value()); + assert(o5.has_value()); + + option 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 -- cgit v1.2.3