68 struct semiregular_box :
private detail::semiregular_get
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)
97 constexpr semiregular_box(tag, std::false_type)
noexcept
99 constexpr semiregular_box(tag, std::true_type)
noexcept(
100 std::is_nothrow_default_constructible<T>::value)
117 bool engaged_{
false};
120 constexpr semiregular_box()
noexcept(
121 std::is_nothrow_default_constructible<T>::value ||
122 !std::is_default_constructible<T>::value)
123 : semiregular_box(tag{}, std::is_default_constructible<T>{})
125 semiregular_box(semiregular_box && that)
noexcept(
126 std::is_nothrow_move_constructible<T>::value)
129 this->construct_from(detail::move(that.data_));
131 semiregular_box(semiregular_box
const & that)
noexcept(
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)(
139 requires (!same_as<uncvref_t<U>, semiregular_box>) AND
140 constructible_from<T, U>)
141 explicit(!convertible_to<U, T>)
constexpr semiregular_box(U && u)
142 noexcept(std::is_nothrow_constructible<T, U>::value)
143 : semiregular_box(in_place,
static_cast<U &&
>(u))
146 template(
typename U)(
147 requires (!same_as<uncvref_t<U>, semiregular_box>) AND
148 constructible_from<T, U> AND (!convertible_to<U, T>))
149 constexpr explicit semiregular_box(U && u)
150 noexcept(std::is_nothrow_constructible<T, U>::value)
151 : semiregular_box(in_place,
static_cast<U &&
>(u))
153 template(
typename U)(
154 requires (!same_as<uncvref_t<U>, semiregular_box>) AND
155 constructible_from<T, U> AND convertible_to<U, T>)
156 constexpr semiregular_box(U && u)
157 noexcept(std::is_nothrow_constructible<T, U>::value)
158 : semiregular_box(in_place,
static_cast<U &&
>(u))
161 template(
typename... Args)(
162 requires constructible_from<T, Args...>)
163 constexpr semiregular_box(
in_place_t, Args &&... args)
164 noexcept(std::is_nothrow_constructible<T, Args...>::value)
165 : data_(
static_cast<Args &&
>(args)...)
172 semiregular_box & operator=(semiregular_box && that)
noexcept(
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_));
185 semiregular_box & operator=(semiregular_box
const & that)
noexcept(
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;