73 template<
typename... Args>
74 void construct_from(Args &&... args)
76 new((
void *)std::addressof(data_)) T(
static_cast<Args &&
>(args)...);
79 void move_assign(T && t, std::true_type)
81 data_ = detail::move(t);
83 void move_assign(T && t, std::false_type)
86 construct_from(detail::move(t));
88 void copy_assign(T
const & t, std::true_type)
92 void copy_assign(T && t, std::false_type)
100 std::is_nothrow_default_constructible<T>::value)
117 bool engaged_{
false};
121 std::is_nothrow_default_constructible<T>::value ||
122 !std::is_default_constructible<T>::value)
126 std::is_nothrow_move_constructible<T>::value)
129 this->construct_from(detail::move(that.data_));
132 std::is_nothrow_copy_constructible<T>::value)
135 this->construct_from(that.data_);
137#if defined(__cpp_conditional_explicit) && 0 < __cpp_conditional_explicit
138 template(
typename U)(
140 constructible_from<T, U>)
142 noexcept(std::is_nothrow_constructible<T, U>::value)
146 template(
typename U)(
148 constructible_from<T, U> AND (!convertible_to<U, T>))
150 noexcept(std::is_nothrow_constructible<T, U>::value)
153 template(
typename U)(
155 constructible_from<T, U> AND convertible_to<U, T>)
157 noexcept(std::is_nothrow_constructible<T, U>::value)
161 template(
typename... Args)(
162 requires constructible_from<T, Args...>)
164 noexcept(std::is_nothrow_constructible<T, Args...>::value)
165 : data_(
static_cast<Args &&
>(args)...)
173 std::is_nothrow_move_constructible<T>::value &&
174 (!std::is_move_assignable<T>::value ||
175 std::is_nothrow_move_assignable<T>::value))
177 if(engaged_ && that.engaged_)
178 this->move_assign(detail::move(that.data_), std::is_move_assignable<T>());
179 else if(that.engaged_)
180 this->construct_from(detail::move(that.data_));
186 std::is_nothrow_copy_constructible<T>::value &&
187 (!std::is_copy_assignable<T>::value ||
188 std::is_nothrow_copy_assignable<T>::value))
190 if(engaged_ && that.engaged_)
191 this->copy_assign(that.data_, std::is_copy_assignable<T>());
192 else if(that.engaged_)
193 this->construct_from(that.data_);
198 constexpr T & get() &
noexcept
200 return RANGES_ENSURE(engaged_), data_;
202 constexpr T
const & get()
const &
noexcept
204 return RANGES_ENSURE(engaged_), data_;
206 constexpr T && get() &&
noexcept
208 return RANGES_ENSURE(engaged_), detail::move(data_);
210 T
const && get()
const && =
delete;
211 constexpr operator T &() &
noexcept
215 constexpr operator T
const &()
const &
noexcept
219 constexpr operator T &&() &&
noexcept
221 return detail::move(get());
223 operator T
const &&()
const && =
delete;
225 template(
typename... Args)(
227 constexpr decltype(
auto)
operator()(Args &&... args) &
228 noexcept(is_nothrow_invocable_v<T &, Args...>)
230 return invoke(data_,
static_cast<Args &&
>(args)...);
232 template(
typename... Args)(
234 constexpr decltype(
auto)
operator()(Args &&... args)
const &
235 noexcept(is_nothrow_invocable_v<T const &, Args...>)
237 return invoke(data_,
static_cast<Args &&
>(args)...);
239 template(
typename... Args)(
241 constexpr decltype(
auto)
operator()(Args &&... args) &&
242 noexcept(is_nothrow_invocable_v<T, Args...>)
244 return invoke(
static_cast<T &&
>(data_),
static_cast<Args &&
>(args)...);
246 template<
typename... Args>
247 void operator()(Args &&...)
const && =
delete;