17 #ifndef OPENKALMAN_COMPATIBILITY_MOVABLE_BOX_HPP 18 #define OPENKALMAN_COMPATIBILITY_MOVABLE_BOX_HPP 28 #ifdef __cpp_lib_concepts 31 inline constexpr
bool boxable =
33 stdex::move_constructible<T> and std::is_object_v<T>;
37 #ifdef __cpp_lib_concepts 38 concept boxable_copyable =
40 inline constexpr
bool boxable_copyable =
42 stdex::copy_constructible<Tp> and
43 (stdex::copyable<Tp> or (std::is_nothrow_move_constructible_v<Tp> and std::is_nothrow_copy_constructible_v<Tp>));
47 #ifdef __cpp_lib_concepts 48 concept boxable_movable =
50 inline constexpr
bool boxable_movable =
52 (not stdex::copy_constructible<Tp>) and
53 (stdex::movable<Tp> or std::is_nothrow_move_constructible_v<Tp>);
61 #ifdef __cpp_lib_concepts 62 template<detail::boxable T>
63 struct movable_box : std::optional<T>
65 template<typename T, typename = void>
70 detail::boxable<T> and not detail::boxable_movable<T> and not detail::boxable_copyable<T>>> : std::optional<T>
73 using std::optional<T>::optional;
76 #ifdef __cpp_lib_concepts 78 movable_box() noexcept(std::is_nothrow_default_constructible_v<T>) requires std::default_initializable<T>
80 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<T>,
int> = 0>
82 movable_box() noexcept(std::is_nothrow_default_constructible_v<T>)
84 : std::optional<T>{std::in_place} {}
95 using std::optional<T>::operator=;
98 #ifdef __cpp_lib_concepts 100 operator=(
const movable_box& that) noexcept(std::is_nothrow_copy_constructible_v<T>)
101 requires (not std::copyable<T>) && std::copy_constructible<T>
103 template<
bool Enable = true, std::enable_if_t<Enable and (not stdex::copyable<T>) && stdex::copy_constructible<T>,
int> = 0>
105 operator=(
const movable_box& that) noexcept(std::is_nothrow_copy_constructible_v<T>)
108 if (
this != std::addressof(that))
110 if ((
bool) that) this->emplace(*that);
117 #ifdef __cpp_lib_concepts 119 operator=(
movable_box&& that) noexcept(std::is_nothrow_move_constructible_v<T>) requires (not std::movable<T>)
121 template<
bool Enable = true, std::enable_if_t<Enable and (not stdex::movable<T>),
int> = 0>
123 operator=(
movable_box&& that) noexcept(std::is_nothrow_move_constructible_v<T>)
126 if (
this != std::addressof(that))
128 if ((
bool) that) this->emplace(std::move(*that));
137 #ifdef __cpp_lib_concepts 138 template<detail::boxable T> requires detail::boxable_movable<T> or detail::boxable_copyable<T>
142 struct
movable_box<T,
std::enable_if_t<detail::boxable<T> and (detail::boxable_movable<T> or detail::boxable_copyable<T>)>>
147 [[no_unique_address]] T M_value = T();
151 #ifdef __cpp_lib_concepts 153 movable_box() requires std::default_initializable<T> =
default;
155 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<T>,
int> = 0>
161 #ifdef __cpp_lib_concepts 163 movable_box(
const T& t) noexcept(std::is_nothrow_copy_constructible_v<T>) requires std::copy_constructible<T>
165 template<
bool Enable = true, std::enable_if_t<Enable and stdex::copy_constructible<T>,
int> = 0>
167 movable_box(
const T& t) noexcept(std::is_nothrow_copy_constructible_v<T>)
173 movable_box(T&& t) noexcept(std::is_nothrow_move_constructible_v<T>) : M_value(std::move(t)) {}
176 #ifdef __cpp_lib_concepts 177 template<
typename...Args> requires std::constructible_from<T, Args...>
179 template<
typename...Args, std::enable_if_t<stdex::constructible_from<T, Args...>,
int> = 0>
182 movable_box(std::in_place_t, Args&&...args) noexcept(std::is_nothrow_constructible_v<T, Args...>)
183 : M_value(std::forward<Args>(args)...) {}
191 #ifdef __cpp_lib_concepts 196 operator=(
const movable_box& that) noexcept requires (not std::copyable<T>) and std::copy_constructible<T>
198 static_assert(std::is_nothrow_copy_constructible_v<T>);
199 if (
this != std::addressof(that))
202 std::construct_at(std::addressof(M_value), *that);
209 static_assert(stdex::copy_constructible<T> and std::is_nothrow_copy_constructible_v<T>);
210 if constexpr (stdex::copyable<T>)
211 if (
this != std::addressof(that))
213 if constexpr (stdex::copyable<T>)
215 M_value = that.M_value;
220 if constexpr (std::is_array_v<T>) return ::new (static_cast<void*>(std::addressof(M_value))) T[1]();
221 else return ::new (static_cast<void*>(std::addressof(M_value))) T(*that);
229 #ifdef __cpp_lib_concepts 234 operator=(
movable_box&& that) noexcept requires (not std::movable<T>)
236 static_assert(std::is_nothrow_move_constructible_v<T>);
237 if (
this != std::addressof(that))
240 std::construct_at(std::addressof(M_value), *that);
247 static_assert(std::is_nothrow_move_constructible_v<T>);
248 if (
this != std::addressof(that))
250 if constexpr (stdex::movable<T>)
252 M_value = std::move(that.M_value);
257 if constexpr (std::is_array_v<T>) return ::new (static_cast<void*>(std::addressof(M_value))) T[1]();
258 else return ::new (static_cast<void*>(std::addressof(M_value))) T(std::move(*that));
267 has_value()
const noexcept {
return true; };
270 operator*() & noexcept {
return M_value; }
273 operator*()
const & noexcept {
return M_value; }
276 operator*() && noexcept {
return std::move(M_value); }
279 operator*()
const && noexcept {
return std::move(M_value); }
282 operator->() noexcept {
return std::addressof(M_value); }
285 operator->()
const noexcept {
return std::addressof(M_value); }
Equivalent to exposition-only "movable-box" from c++23 standard.
Definition: movable_box.hpp:66
Definitions relating to standard c++ library concepts.
Definition: basics.hpp:48