26template<
typename BaseType,
size_t Capacity>
29 using value_type = BaseType;
31 using const_reference = value_type
const &;
33 using const_pointer = value_type
const *;
35 static constexpr size_t capacity = Capacity;
57 template<
typename Other>
60 static_assert(std::is_base_of_v<value_type, std::remove_cvref_t<Other>>);
61 _state = state::empty;
62 emplace<std::remove_cvref_t<Other>>(std::forward<Other>(other));
70 template<decayed_derived_from<value_type> Other>
73 emplace<std::remove_cvref_t<Other>>(std::forward<Other>(other));
83 template<derived_from<value_type> T,
typename... Args>
89 if (
sizeof(T) <= capacity) {
90 r =
new (_value.buffer.data()) T(std::forward<Args>(args)...);
91 _state = state::internal;
94 r = _value.pointer =
new T(std::forward<Args>(args)...);
95 _state = state::external;
97 tt_axiom(r !=
nullptr);
107 return _state != state::empty;
114 [[nodiscard]]
operator bool() const noexcept
123 if (_state != state::empty) {
124 [[unlikely]] reset_deep();
133 [[nodiscard]] const_reference
value() const &noexcept
135 if (_state == state::empty) {
148 if (_state == state::empty) {
160 [[nodiscard]] const_reference
operator*() const noexcept
162 tt_axiom(_state != state::empty);
174 tt_axiom(_state != state::empty);
197 enum class state : uint8_t { empty, internal, external };
207 tt_no_inline
void reset_deep() noexcept
209 if (_state == state::internal) {
210 std::destroy_at(internal_pointer());
211 }
else if (_state == state::external) {
212 delete external_pointer();
214 _state = state::empty;
217 [[nodiscard]] const_pointer internal_pointer() const noexcept
219 tt_axiom(_state == state::internal);
220 return std::launder(
reinterpret_cast<const_pointer
>(_value.buffer.data()));
223 [[nodiscard]] pointer internal_pointer() noexcept
225 tt_axiom(_state == state::internal);
226 return std::launder(
reinterpret_cast<pointer
>(_value.buffer.data()));
229 [[nodiscard]] const_pointer external_pointer() const noexcept
231 tt_axiom(_state == state::external);
232 return std::launder(_value.pointer);
236 [[nodiscard]] pointer external_pointer() noexcept
238 tt_axiom(_state == state::external);
239 return std::launder(_value.pointer);
247 [[nodiscard]] const_pointer _pointer() const noexcept
249 if (_state == state::internal) {
250 return internal_pointer();
251 }
else if (_state == state::external) {
252 return external_pointer();
262 [[nodiscard]] pointer _pointer() noexcept
264 if (_state == state::internal) {
265 return internal_pointer();
266 }
else if (_state == state::external) {
267 return external_pointer();
Polymorphic optional.
Definition polymorphic_optional.hpp:27
polymorphic_optional(Other &&other) noexcept
Construct an object as value.
Definition polymorphic_optional.hpp:58
reference value() &noexcept
Returns the contained value.
Definition polymorphic_optional.hpp:146
void reset() noexcept
Destroys any contained value.
Definition polymorphic_optional.hpp:121
bool has_value() const noexcept
Check whether the object contains a value.
Definition polymorphic_optional.hpp:105
polymorphic_optional & operator=(Other &&other) noexcept
Assign an object.
Definition polymorphic_optional.hpp:71
pointer operator->() noexcept
Get a pointer to the contained value.
Definition polymorphic_optional.hpp:191
constexpr polymorphic_optional() noexcept
Construct an empty value.
Definition polymorphic_optional.hpp:51
reference operator*() noexcept
Dereference the contained value.
Definition polymorphic_optional.hpp:172
reference emplace(Args &&...args) noexcept
Construct the contained value in-place.
Definition polymorphic_optional.hpp:84
const_pointer operator->() const noexcept
Get a pointer to the contained value.
Definition polymorphic_optional.hpp:182
const_reference operator*() const noexcept
Dereference the contained value.
Definition polymorphic_optional.hpp:160
const_reference value() const &noexcept
Returns the contained value.
Definition polymorphic_optional.hpp:133
~polymorphic_optional()
Destroy any contained value.
Definition polymorphic_optional.hpp:39
Definition concepts.hpp:34
Definition concepts.hpp:37