24#include "vari/bits/typelist.h"
25#include "vari/bits/util.h"
26#include "vari/bits/val_core.h"
27#include "vari/forward.h"
28#include "vari/uvref.h"
43template <
typename... Ts >
46 using core_type = _val_core< typelist< Ts... > >;
49 using types = typelist< Ts... >;
50 using pointer = _vptr< Ts... >;
51 using const_pointer = _vptr< Ts
const... >;
52 using reference = _vref< Ts... >;
53 using const_reference = _vref< Ts
const... >;
55 constexpr _vopt() noexcept = default;
57 template < typename U >
58 requires( vconvertible_type< std::remove_cvref_t< U >, types > )
59 constexpr _vopt( U&& v ) noexcept( _forward_nothrow_constructible< U > )
61 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
64 template <
typename U,
typename... Args >
65 requires( vconvertible_type< U, types > )
66 constexpr _vopt( std::in_place_type_t< U >, Args&&... args )
noexcept(
67 std::is_nothrow_constructible_v< U, Args... > )
69 _core.template emplace< U >( (Args&&) args... );
72 constexpr _vopt( _vopt&& p )
noexcept( std::is_nothrow_move_constructible_v< core_type > )
73 : _core( std::move( p._core ) )
77 template <
typename... Us >
78 requires( vconvertible_to< typelist< Us... >, types > )
79 constexpr _vopt( _vopt< Us... >&& p )
noexcept(
80 std::is_nothrow_constructible_v< core_type,
typename _vopt< Us... >::core_type&& > )
81 : _core( std::move( p._core ) )
85 template <
typename... Us >
86 requires( vconvertible_to< typelist< Us... >, types > )
87 constexpr _vopt( _vval< Us... >&& p )
noexcept(
88 std::is_nothrow_constructible_v< core_type,
typename _vval< Us... >::core_type&& > )
89 : _core( std::move( p._core ) )
93 constexpr _vopt( _vopt
const& p )
noexcept(
94 std::is_nothrow_copy_constructible_v< core_type > )
99 template <
typename... Us >
100 requires( vconvertible_to< typelist< Us... >, types > )
101 constexpr _vopt( _vopt< Us... >
const& p )
noexcept(
103 is_nothrow_constructible_v< core_type,
typename _vopt< Us... >::core_type
const& > )
108 template <
typename... Us >
109 requires( vconvertible_to< typelist< Us... >, types > )
110 constexpr _vopt( _vval< Us... >
const& p )
noexcept(
112 is_nothrow_constructible_v< core_type,
typename _vval< Us... >::core_type
const& > )
117 template <
typename U >
118 requires( vconvertible_type< std::remove_cvref_t< U >, types > )
119 constexpr _vopt&
operator=( U&& v )
noexcept( _forward_nothrow_constructible< U > )
121 if ( _core.index != null_index )
123 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
127 constexpr _vopt& operator=( _vopt&& p )
noexcept(
128 core_type::template is_nothrow_assignable< typename _vopt::core_type&& > )
131 _core.assign( std::move( p._core ) );
135 template <
typename... Us >
136 requires( vconvertible_to< typelist< Us... >, types > )
137 constexpr _vopt&
operator=( _vopt< Us... >&& p )
noexcept(
138 core_type::template is_nothrow_assignable<
typename _vopt< Us... >::core_type&& > )
141 _core.assign( std::move( p._core ) );
145 constexpr _vopt& operator=( _vopt
const& p )
noexcept(
146 core_type::template is_nothrow_assignable< typename _vopt::core_type const& > )
149 _core.assign( p._core );
153 template <
typename... Us >
154 requires( vconvertible_to< typelist< Us... >, types > )
155 constexpr _vopt&
operator=( _vopt< Us... >
const& p )
noexcept(
156 core_type::template is_nothrow_assignable<
typename _vopt< Us... >::core_type
const& > )
159 _core.assign( p._core );
163 template <
typename T,
typename... Args >
164 requires( vconvertible_type< T, types > )
166 emplace( Args&&... args )
noexcept( std::is_nothrow_constructible_v< T, Args... > )
168 if ( _core.index != null_index )
170 return _core.template emplace< T >( (Args&&) args... );
173 [[nodiscard]]
constexpr index_type index() const noexcept
178 constexpr auto& operator*() const noexcept
179 requires( types::size == 1 )
181 return core_type::ST::template get< 0 >( _core.storage );
184 constexpr auto* operator->() const noexcept
185 requires( types::size == 1 )
190 template <
typename... Us >
191 requires( vconvertible_to< types, typelist< Us... > > )
192 constexpr operator _vptr< Us... >() &
noexcept
194 if ( _core.index == null_index )
195 return _vptr< Us... >{};
196 return core_type::visit_impl( _core, [&](
auto& item ) {
197 return _vptr< Us... >( &item );
201 template <
typename... Us >
202 requires( vconvertible_to< types, typelist< Us... > > )
203 constexpr operator _vptr< Us... >() const& noexcept
205 static_assert( all_is_const_v< typelist< Us... > > );
206 if ( _core.index == null_index )
207 return _vptr< Us... >{};
208 return core_type::visit_impl( _core, [&](
auto& item ) {
209 return _vptr< Us... >( &item );
213 constexpr explicit operator bool() const noexcept
215 return _core.index != null_index;
218 constexpr reference
vref() &
noexcept
220 VARI_ASSERT( *
this );
221 return vptr().vref();
224 constexpr const_reference
vref() const& noexcept
226 VARI_ASSERT( *
this );
227 return vptr().vref();
230 constexpr pointer
vptr() &
noexcept
232 return pointer{ *
this };
235 constexpr const_pointer
vptr() const& noexcept
237 return const_pointer{ *
this };
243 constexpr _vval< Ts... > vval() &&
245 VARI_ASSERT( !!*
this );
247 swap( res._core, _core );
251 template <
typename... Fs >
252 constexpr decltype( auto ) visit( Fs&&... f )
const
254 typename _check_unique_invocability< types >::template with_nullable_pure_cref<
257 if ( _core.index == null_index )
258 return _dispatch_fun( empty, (Fs&&) f... );
259 return core_type::visit_impl( _core, (Fs&&) f... );
262 template <
typename... Fs >
263 constexpr decltype( auto ) visit( Fs&&... f )
265 typename _check_unique_invocability< types >::template with_nullable_pure_ref<
268 if ( _core.index == null_index )
269 return _dispatch_fun( empty, (Fs&&) f... );
270 return core_type::visit_impl( _core, (Fs&&) f... );
273 constexpr friend void
274 swap( _vopt& lh, _vopt& rh )
noexcept( std::is_nothrow_swappable_v< core_type > )
277 swap( lh._core, rh._core );
280 constexpr ~_vopt() noexcept( std::is_nothrow_destructible_v< core_type > )
282 if ( _core.index != null_index )
286 friend constexpr std::partial_ordering operator<=>(
288 _vopt
const& rh )
noexcept( all_nothrow_three_way_comparable_v< types > )
290 if ( lh._core.index == null_index || rh._core.index == null_index )
291 return lh._core.index <=> rh._core.index;
292 return core_type::three_way_compare( lh._core, rh._core );
295 friend constexpr auto operator==( _vopt
const& lh, _vopt
const& rh )
noexcept(
296 all_nothrow_equality_comparable_v< types > )
298 if ( lh._core.index == null_index || rh._core.index == null_index )
299 return lh._core.index == rh._core.index;
300 return core_type::compare( lh._core, rh._core );
304 template <
typename... Us >
310template <
typename... Ts >
MIT License.
Definition: dispatch.h:32
_define_variadic< _vref, typelist< Ts... > > vref
A non-nullable pointer to types derived out of Ts... list by flattening it and filtering for unique t...
Definition: vref.h:162
_define_variadic< _vptr, typelist< Ts... > > vptr
A nullable pointer to types derived out of Ts... list by flattening it and filtering for unique types...
Definition: vptr.h:189
_vptr_apply_t< T, unique_typelist_t< flatten_t< TL > >, Extra... > _define_variadic
Given a templated type T and typelist of types TL, aliases T<Us...> where Us... is flattend version o...
Definition: util.h:61