25template<
typename BaseType,
size_t Capacity>
28 using value_type = BaseType;
30 using const_reference = value_type
const &;
32 using const_pointer = value_type
const *;
34 static constexpr size_t capacity = Capacity;
56 template<
typename Other>
59 static_assert(std::is_base_of_v<value_type, std::remove_cvref_t<Other>>);
60 _state = state::empty;
61 emplace<std::remove_cvref_t<Other>>(std::forward<Other>(other));
69 template<decayed_derived_from<value_type> Other>
72 emplace<std::remove_cvref_t<Other>>(std::forward<Other>(other));
82 template<derived_from<value_type> T,
typename... Args>
88 if (
sizeof(T) <= capacity) {
89 r =
new (_value.buffer.data()) T(std::forward<Args>(args)...);
90 _state = state::internal;
93 r = _value.pointer =
new T(std::forward<Args>(args)...);
94 _state = state::external;
96 tt_axiom(r !=
nullptr);
106 return _state != state::empty;
113 [[nodiscard]]
operator bool() const noexcept
122 if (_state != state::empty) {
123 [[unlikely]] reset_deep();
132 [[nodiscard]] const_reference
value() const &noexcept
134 if (_state == state::empty) {
147 if (_state == state::empty) {
159 [[nodiscard]] const_reference
operator*() const noexcept
161 tt_axiom(_state != state::empty);
173 tt_axiom(_state != state::empty);
196 enum state { empty, internal, external };
204 tt_no_inline
void reset_deep() noexcept
206 if (_state == state::internal) {
207 std::destroy_at(internal_pointer());
208 }
else if (_state == state::external) {
209 delete external_pointer();
211 _state = state::empty;
214 [[nodiscard]] const_pointer internal_pointer() const noexcept
216 tt_axiom(_state == state::internal);
217 return std::launder(
reinterpret_cast<const_pointer
>(_value.buffer.data()));
220 [[nodiscard]] pointer internal_pointer() noexcept
222 tt_axiom(_state == state::internal);
223 return std::launder(
reinterpret_cast<pointer
>(_value.buffer.data()));
226 [[nodiscard]] const_pointer external_pointer() const noexcept
228 tt_axiom(_state == state::external);
229 return std::launder(_value.pointer);
233 [[nodiscard]] pointer external_pointer() noexcept
235 tt_axiom(_state == state::external);
236 return std::launder(_value.pointer);
244 [[nodiscard]] const_pointer _pointer() const noexcept
247 case state::internal:
return internal_pointer();
248 case state::external:
return external_pointer();
249 case state::empty:
return nullptr;
250 default: tt_no_default();
258 [[nodiscard]] pointer _pointer() noexcept
261 case state::internal:
return internal_pointer();
262 case state::external:
return external_pointer();
263 case state::empty:
return nullptr;
264 default: tt_no_default();
Polymorphic optional.
Definition polymorphic_optional.hpp:26
polymorphic_optional(Other &&other) noexcept
Construct an object as value.
Definition polymorphic_optional.hpp:57
reference value() &noexcept
Returns the contained value.
Definition polymorphic_optional.hpp:145
void reset() noexcept
Destroys any contained value.
Definition polymorphic_optional.hpp:120
bool has_value() const noexcept
Check whether the object contains a value.
Definition polymorphic_optional.hpp:104
polymorphic_optional & operator=(Other &&other) noexcept
Assign an object.
Definition polymorphic_optional.hpp:70
pointer operator->() noexcept
Get a pointer to the contained value.
Definition polymorphic_optional.hpp:190
constexpr polymorphic_optional() noexcept
Construct an empty value.
Definition polymorphic_optional.hpp:50
reference operator*() noexcept
Dereference the contained value.
Definition polymorphic_optional.hpp:171
reference emplace(Args &&...args) noexcept
Construct the contained value in-place.
Definition polymorphic_optional.hpp:83
const_pointer operator->() const noexcept
Get a pointer to the contained value.
Definition polymorphic_optional.hpp:181
const_reference operator*() const noexcept
Dereference the contained value.
Definition polymorphic_optional.hpp:159
const_reference value() const &noexcept
Returns the contained value.
Definition polymorphic_optional.hpp:132
~polymorphic_optional()
Destroy any contained value.
Definition polymorphic_optional.hpp:38
Definition concepts.hpp:18
Definition concepts.hpp:21