27 template <copy_constructible_
object T>
29 [[no_unique_address]] std::optional<T> instance_ = std::nullopt;
32 template <
class... Args>
33 requires std::is_constructible_v<T, Args...>
34 constexpr explicit copyable_box(std::in_place_t, Args&&... args)
35 noexcept(std::is_nothrow_constructible_v<T, Args...>)
36 : instance_(std::in_place, std::forward<Args>(args)...) {}
39 noexcept(std::is_nothrow_default_constructible_v<T>)
40 requires std::default_initializable<T> : instance_(std::in_place) {}
46 operator=(
const copyable_box& other)
noexcept(std::is_nothrow_copy_constructible_v<T>) {
47 if (
this != std::addressof(other)) {
48 if (other.has_value())
49 instance_.emplace(*other);
60 operator=(
copyable_box&& other)
noexcept(std::is_nothrow_move_constructible_v<T>) {
61 if (
this != std::addressof(other)) {
62 if (other.has_value())
63 instance_.emplace(std::move(*other));
70 constexpr const T& operator*()
const&
noexcept {
73 constexpr const T&& operator*()
const&&
noexcept {
74 return std::move(*instance_);
76 constexpr T& operator*() &
noexcept {
79 constexpr T&& operator*() &&
noexcept {
80 return std::move(*instance_);
83 constexpr const T* operator->()
const noexcept {
84 return instance_.operator->();
86 constexpr T* operator->()
noexcept {
87 return instance_.operator->();
90 constexpr bool has_value()
const noexcept {
91 return instance_.has_value();
113 concept doesnt_need_empty_state_for_copy =
114 std::copyable<T> or std::is_nothrow_copy_constructible_v<T>;
117 concept doesnt_need_empty_state_for_move =
118 std::movable<T> or std::is_nothrow_move_constructible_v<T>;
122 template <copy_constructible_
object T>
123 requires doesnt_need_empty_state_for_copy<T> and doesnt_need_empty_state_for_move<T>
125 [[no_unique_address]] T instance_{};
128 template <
class... Args>
129 requires std::is_constructible_v<T, Args...>
130 constexpr explicit copyable_box(std::in_place_t, Args&&... args)
131 noexcept(std::is_nothrow_constructible_v<T, Args...>)
132 : instance_(std::forward<Args>(args)...) {}
135 noexcept(std::is_nothrow_default_constructible_v<T>)
136 requires std::default_initializable<T> : instance_{} {}
149 static_assert(std::is_nothrow_copy_constructible_v<T>);
150 if (
this != std::addressof(other)) {
151 std::destroy_at(std::addressof(instance_));
152 std::construct_at(std::addressof(instance_), other.instance_);
158 static_assert(std::is_nothrow_move_constructible_v<T>);
159 if (
this != std::addressof(other)) {
160 std::destroy_at(std::addressof(instance_));
161 std::construct_at(std::addressof(instance_), std::move(other.instance_));
166 constexpr const T& operator*()
const&
noexcept {
169 constexpr const T&& operator*()
const&&
noexcept {
170 return std::move(instance_);
172 constexpr T& operator*() &
noexcept {
175 constexpr T&& operator*() &&
noexcept {
176 return std::move(instance_);
179 constexpr const T* operator->()
const noexcept {
180 return std::addressof(instance_);
182 constexpr T* operator->()
noexcept {
183 return std::addressof(instance_);
186 constexpr bool has_value()
const noexcept {
Makes copy_constructible but not copy_assignable types copy_assignable.
Definition: copyable_box.hpp:28
Requires copy_constructible and is_object.
Definition: copyable_box.hpp:22