Skip to content

Commit

Permalink
Support construction/assignment from reference_wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Quuxplusone committed Sep 8, 2024
1 parent 3a1209d commit 1270624
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
14 changes: 6 additions & 8 deletions include/tl/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1936,11 +1936,10 @@ template <class T> class optional<T &> {
TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs) = default;

/// Constructs the stored value with `u`.
template <class U = T,
detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
template <class U,
detail::enable_if_t<std::is_convertible<U, T&>::value>
* = nullptr>
constexpr optional(U &&u) noexcept : m_value(std::addressof(u)) {
static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
constexpr optional(U &&u) noexcept : m_value(std::addressof(static_cast<T&>(u))) {
}

template <class U>
Expand All @@ -1964,12 +1963,11 @@ template <class T> class optional<T &> {
optional &operator=(const optional &rhs) = default;

/// Rebinds this optional to `u`.
template <class U = T,
detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
template <class U,
detail::enable_if_t<std::is_convertible<U, T&>::value>
* = nullptr>
optional &operator=(U &&u) {
static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
m_value = std::addressof(u);
m_value = std::addressof(static_cast<T&>(u));
return *this;
}

Expand Down
14 changes: 14 additions & 0 deletions tests/issues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,17 @@ TEST_CASE("issue 33") {
REQUIRE(*a == 42);
REQUIRE(a.has_value());
}

TEST_CASE("issue 66") {
int i = 42;
int j = 43;
tl::optional<std::reference_wrapper<int>> a = std::ref(i);
REQUIRE(&a.value().get() == &i);
a = std::ref(j);
REQUIRE(&a.value().get() == &j);

tl::optional<int&> b = std::ref(i);
REQUIRE(&b.value() == &i);
b = std::ref(j);
REQUIRE(&b.value() == &j);
}

0 comments on commit 1270624

Please sign in to comment.