17 #ifndef OPENKALMAN_COMPATIBILITY_MOVABLE_BOX_HPP 18 #define OPENKALMAN_COMPATIBILITY_MOVABLE_BOX_HPP 21 #include <type_traits> 29 #ifdef __cpp_lib_concepts 30 concept boxable = std::copy_constructible<T> and std::is_object_v<T>;
32 inline constexpr
bool boxable = copy_constructible<T> and std::is_object_v<T>;
37 #ifdef __cpp_lib_concepts 38 concept boxable_copyable =
39 std::copy_constructible<T> and (std::movable<T> or std::is_nothrow_move_constructible_v<T>);
41 inline constexpr
bool boxable_copyable =
42 copy_constructible<T> and
43 (copyable<T> or (std::is_nothrow_move_constructible_v<T> or std::is_nothrow_copy_constructible_v<T>));
48 #ifdef __cpp_lib_concepts 49 concept boxable_movable =
50 (not std::copy_constructible<T>) and (std::movable<T> or std::is_nothrow_move_constructible_v<T>);
52 inline constexpr
bool boxable_movable =
53 (not copy_constructible<T>) and (movable<T> or std::is_nothrow_move_constructible_v<T>);
58 #ifdef __cpp_lib_concepts 59 template<detail::boxable>
61 template<
typename T,
typename =
void>
66 #ifdef __cpp_lib_concepts 67 template<detail::boxable T>
72 not detail::boxable_movable<T> and not detail::boxable_copyable<T>>>
76 using std::optional<T>::optional;
79 #ifdef __cpp_lib_concepts 81 movable_box() noexcept(std::is_nothrow_default_constructible_v<T>) requires std::default_initializable<T>
83 template<
bool Enable = true, std::enable_if_t<Enable and std::is_default_constructible_v<T>,
int> = 0>
85 movable_box() noexcept(std::is_nothrow_default_constructible_v<T>)
87 : std::optional<T>{std::in_place} {}
96 using std::optional<T>::operator=;
99 #ifdef __cpp_lib_concepts 101 operator=(
const movable_box& that) noexcept(std::is_nothrow_copy_constructible_v<T>)
102 requires (not std::copyable<T>) && std::copy_constructible<T>
104 template<
bool Enable = true, std::enable_if_t<Enable and (not copyable<T>) && copy_constructible<T>,
int> = 0>
106 operator=(
const movable_box& that) noexcept(std::is_nothrow_copy_constructible_v<T>)
109 if (
this != std::addressof(that))
111 if ((
bool) that) this->emplace(*that);
118 #ifdef __cpp_lib_concepts 120 operator=(
movable_box&& that) noexcept(std::is_nothrow_move_constructible_v<T>) requires (not std::movable<T>)
122 template<
bool Enable = true, std::enable_if_t<Enable and (not movable<T>),
int> = 0>
124 operator=(
movable_box&& that) noexcept(std::is_nothrow_move_constructible_v<T>)
127 if (
this != std::addressof(that))
129 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 152 movable_box() requires std::default_initializable<T> =
default;
154 template<
bool Enable = true, std::enable_if_t<Enable and std::is_default_constructible_v<T>,
int> = 0>
159 #ifdef __cpp_lib_concepts 161 movable_box(
const T& t) noexcept(std::is_nothrow_copy_constructible_v<T>) requires std::copy_constructible<T>
163 template<
bool Enable = true, std::enable_if_t<Enable and copy_constructible<T>,
int> = 0>
165 movable_box(
const T& t) noexcept(std::is_nothrow_copy_constructible_v<T>)
171 movable_box(T&& t) noexcept(std::is_nothrow_move_constructible_v<T>) : M_value(std::move(t)) {}
174 #ifdef __cpp_lib_concepts 175 template<
typename...Args> requires std::constructible_from<T, Args...>
177 template<
typename...Args, std::enable_if_t<constructible_from<T, Args...>,
int> = 0>
180 movable_box(std::in_place_t, Args&&...args) noexcept(std::is_nothrow_constructible_v<T, Args...>)
181 : M_value(std::forward<Args>(args)...) {}
188 #ifdef __cpp_lib_concepts 191 template<
bool Enable = true, std::enable_if_t<Enable and copyable<T>,
int> = 0>
196 #ifdef __cpp_lib_concepts 199 template<
bool Enable = true, std::enable_if_t<Enable and movable<T>,
int> = 0>
204 #ifdef __cpp_lib_concepts 206 operator=(
const movable_box& that) noexcept requires (not std::copyable<T>) and std::copy_constructible<T>
208 template<
bool Enable = true, std::enable_if_t<Enable and (not copyable<T>) and copy_constructible<T>,
int> = 0>
213 static_assert(std::is_nothrow_copy_constructible_v<T>);
214 if (
this != std::addressof(that))
217 #if __cplusplus >= 202002L 218 std::construct_at(std::addressof(M_value), *that);
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);
228 #ifdef __cpp_lib_concepts 230 operator=(
movable_box&& that) noexcept requires (not std::movable<T>)
232 template<
bool Enable = true, std::enable_if_t<Enable and (not movable<T>),
int> = 0>
237 static_assert(std::is_nothrow_move_constructible_v<T>);
238 if (
this != std::addressof(that))
241 #if __cplusplus >= 202002L 242 std::construct_at(std::addressof(M_value), *that);
244 if constexpr (std::is_array_v<T>) return ::new (static_cast<void*>(std::addressof(M_value))) T[1]();
245 else return ::new (static_cast<void*>(std::addressof(M_value))) T(std::move(*that));
252 has_value()
const noexcept {
return true; };
255 operator*() & noexcept {
return M_value; }
258 operator*()
const & noexcept {
return M_value; }
261 operator*() && noexcept {
return std::move(M_value); }
264 operator*()
const && noexcept {
return std::move(M_value); }
267 operator->() noexcept {
return std::addressof(M_value); }
270 operator->()
const noexcept {
return std::__addressof(M_value); }
276 #endif //OPENKALMAN_COMPATIBILITY_MOVABLE_BOX_HPP Definition: movable_box.hpp:63
Definition: tuple_reverse.hpp:103
Definitions relating to the availability of c++ language features.
Definition: basics.hpp:48