diff --git a/include/beman/optional26/optional.hpp b/include/beman/optional26/optional.hpp index 54ebd689..6fe745f6 100644 --- a/include/beman/optional26/optional.hpp +++ b/include/beman/optional26/optional.hpp @@ -424,8 +424,7 @@ inline constexpr optional::optional(const optional& rhs) requires std::is_copy_constructible_v && (!std::is_trivially_copy_constructible_v) { if (rhs.has_value()) { - std::construct_at(std::addressof(value_), rhs.value_); - engaged_ = true; + construct(rhs.value_); } } @@ -434,8 +433,7 @@ inline constexpr optional::optional(optional&& rhs) noexcept(std::is_nothrow_ requires std::is_move_constructible_v && (!std::is_trivially_move_constructible_v) { if (rhs.has_value()) { - std::construct_at(std::addressof(value_), std::move(rhs.value())); - engaged_ = true; + construct(std::move(rhs.value_)); } } @@ -466,8 +464,7 @@ inline constexpr optional::optional(const optional& rhs) requires detail::enable_from_other && std::is_convertible_v { if (rhs.has_value()) { - std::construct_at(std::addressof(value_), rhs.value()); - engaged_ = true; + construct(*rhs); } } @@ -524,7 +521,7 @@ inline constexpr optional& optional::operator=(const optional& rhs) else if (has_value()) value_ = rhs.value_; else - std::construct_at(std::addressof(value_), rhs.value_); + construct(rhs.value_); return *this; } @@ -539,7 +536,7 @@ optional::operator=(optional&& rhs) noexcept(std::is_nothrow_move_construc else if (has_value()) value_ = std::move(rhs.value_); else - std::construct_at(std::addressof(value_), std::move(rhs.value_)); + construct(std::move(rhs.value_)); return *this; } diff --git a/src/beman/optional26/tests/optional.t.cpp b/src/beman/optional26/tests/optional.t.cpp index ca883917..d0592fcb 100644 --- a/src/beman/optional26/tests/optional.t.cpp +++ b/src/beman/optional26/tests/optional.t.cpp @@ -208,8 +208,38 @@ TEST(OptionalTest, AssignmentValue) { */ beman::optional26::optional o5{5}; beman::optional26::optional o6; + + // Copy into empty optional. o6 = o5; - EXPECT_TRUE(o5->i_ == 5); + EXPECT_TRUE(o6); + EXPECT_TRUE(o6->i_ == 5); + + // Move into empty optional. + o6.reset(); + o6 = std::move(o5); + EXPECT_TRUE(o6); + EXPECT_TRUE(o6->i_ == 5); + + // Copy into engaged optional. + beman::optional26::optional o7{7}; + o6 = o7; + EXPECT_TRUE(o6); + EXPECT_TRUE(o6->i_ == 7); + + // Move into engaged optional. + beman::optional26::optional o8{8}; + o6 = std::move(o8); + EXPECT_TRUE(o6); + EXPECT_TRUE(o6->i_ == 8); + + // Copy from empty into engaged optional. + o5.reset(); + o7 = o5; + EXPECT_FALSE(o7); + + // Move from empty into engaged optional. + o8 = std::move(o5); + EXPECT_FALSE(o8); } TEST(OptionalTest, Triviality) {