diff --git a/include/beman/optional26/optional.hpp b/include/beman/optional26/optional.hpp index 54ebd68..99bf73d 100644 --- a/include/beman/optional26/optional.hpp +++ b/include/beman/optional26/optional.hpp @@ -299,6 +299,8 @@ class optional { requires(!std::is_trivially_destructible_v); // \ref{optional.assign}, assignment + constexpr optional& operator=(nullopt_t) noexcept; + constexpr optional& operator=(const optional& rhs) requires std::is_copy_constructible_v && std::is_copy_assignable_v && (!std::is_trivially_copy_assignable_v); @@ -514,6 +516,12 @@ inline constexpr optional::~optional() // 22.5.3.4 Assignment[optional.assign] +template +inline constexpr optional& optional::operator=(nullopt_t) noexcept { + reset(); + return *this; +} + template inline constexpr optional& optional::operator=(const optional& rhs) requires std::is_copy_constructible_v && std::is_copy_assignable_v && diff --git a/src/beman/optional26/tests/optional.t.cpp b/src/beman/optional26/tests/optional.t.cpp index ca88391..0a8b4c5 100644 --- a/src/beman/optional26/tests/optional.t.cpp +++ b/src/beman/optional26/tests/optional.t.cpp @@ -868,3 +868,23 @@ TEST(OptionalTest, HashTest) { EXPECT_EQ(h1, h2); } } + +TEST(OptionalTest, CanHoldValueOfImmovableType) { + struct immovable { + explicit immovable() = default; + immovable(const immovable&) = delete; + immovable& operator=(const immovable&) = delete; + }; + + beman::optional26::optional o1(beman::optional26::in_place); + EXPECT_TRUE(o1); + + // ...and can reset it with `nullopt`. + static_assert(noexcept(o1 = beman::optional26::nullopt)); + o1 = beman::optional26::nullopt; + EXPECT_FALSE(o1); + + // Also, can construct with `nullopt`. + beman::optional26::optional o2 = beman::optional26::nullopt; + EXPECT_FALSE(o2); +}