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"
41template <
typename... Ts >
44 using core_type = _val_core< typelist< Ts... > >;
47 using types = typelist< Ts... >;
48 using pointer = _vptr< Ts... >;
49 using const_pointer = _vptr< Ts
const... >;
50 using reference = _vref< Ts... >;
51 using const_reference = _vref< Ts
const... >;
53 template <
typename U >
54 requires( vconvertible_type< std::remove_cvref_t< U >, types > )
55 constexpr _vval( U&& v )
noexcept( _forward_nothrow_constructible< U > )
57 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
60 template <
typename U,
typename... Args >
61 requires( vconvertible_type< U, types > )
62 constexpr _vval( std::in_place_type_t< U >, Args&&... args )
noexcept(
63 std::is_nothrow_constructible_v< U, Args... > )
65 _core.template emplace< U >( (Args&&) args... );
68 constexpr _vval( _vval&& p )
noexcept( std::is_nothrow_move_constructible_v< core_type > )
69 : _core( std::move( p._core ) )
73 template <
typename... Us >
74 requires( vconvertible_to< typelist< Us... >, types > )
75 constexpr _vval( _vval< Us... >&& p )
noexcept(
76 std::is_nothrow_constructible_v< core_type,
typename _vval< Us... >::core_type&& > )
77 : _core( std::move( p._core ) )
81 constexpr _vval( _vval
const& p )
noexcept(
82 std::is_nothrow_copy_constructible_v< core_type > )
87 template <
typename... Us >
88 requires( vconvertible_to< typelist< Us... >, types > )
89 constexpr _vval( _vval< Us... >
const& p )
noexcept(
91 is_nothrow_constructible_v< core_type,
typename _vval< Us... >::core_type
const& > )
96 template <
typename U >
97 requires( vconvertible_type< std::remove_cvref_t< U >, types > )
98 constexpr _vval&
operator=( U&& v )
noexcept( _forward_nothrow_constructible< U > )
100 if ( _core.index != null_index )
102 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
106 constexpr _vval& operator=( _vval&& p )
noexcept(
107 core_type::template is_nothrow_assignable< typename _vval::core_type&& > )
109 _core.assign( std::move( p._core ) );
113 template <
typename... Us >
114 requires( vconvertible_to< typelist< Us... >, types > )
115 constexpr _vval&
operator=( _vval< Us... >&& p )
noexcept(
116 core_type::template is_nothrow_assignable<
typename _vval< Us... >::core_type&& > )
118 _core.assign( std::move( p._core ) );
122 constexpr _vval& operator=( _vval
const& p )
noexcept(
123 core_type::template is_nothrow_assignable< typename _vval::core_type const& > )
125 _core.assign( p._core );
129 template <
typename... Us >
130 requires( vconvertible_to< typelist< Us... >, types > )
131 constexpr _vval&
operator=( _vval< Us... >
const& p )
noexcept(
132 core_type::template is_nothrow_assignable<
typename _vval< Us... >::core_type
const& > )
134 _core.assign( p._core );
138 template <
typename T,
typename... Args >
139 requires( vconvertible_type< T, types > )
141 emplace( Args&&... args )
noexcept( std::is_nothrow_constructible_v< T, Args... > )
144 return _core.template emplace< T >( (Args&&) args... );
147 [[nodiscard]]
constexpr index_type index() const noexcept
152 constexpr auto& operator*() const noexcept
153 requires( types::size == 1 )
155 return core_type::ST::template get< 0 >( _core.storage );
158 constexpr auto* operator->() const noexcept
159 requires( types::size == 1 )
164 template <
typename... Us >
165 requires( vconvertible_to< types, typelist< Us... > > )
166 constexpr operator _vref< Us... >() &
noexcept
168 return core_type::visit_impl( _core, [&](
auto& item ) {
169 return _vref< Us... >( item );
173 template <
typename... Us >
174 requires( vconvertible_to< types, typelist< Us... > > )
175 constexpr operator _vref< Us... >() const& noexcept
177 static_assert( all_is_const_v< typelist< Us... > > );
178 return core_type::visit_impl( _core, [&](
auto& item ) {
179 return _vref< Us... >( item );
183 constexpr reference
vref() &
noexcept
185 return reference{ *
this };
188 constexpr const_reference
vref() const& noexcept
190 return const_reference{ *
this };
193 constexpr pointer
vptr() &
noexcept
195 return reference{ *
this }.vptr();
198 constexpr const_pointer
vptr() const& noexcept
200 return const_reference{ *
this }.vptr();
203 template <
typename... Fs >
204 constexpr decltype( auto ) visit( Fs&&... f )
const
206 typename _check_unique_invocability< types >::template with_pure_cref< Fs... > _{};
207 return core_type::visit_impl( _core, (Fs&&) f... );
210 template <
typename... Fs >
211 constexpr decltype( auto ) visit( Fs&&... f )
213 typename _check_unique_invocability< types >::template with_pure_ref< Fs... > _{};
214 return core_type::visit_impl( _core, (Fs&&) f... );
217 constexpr friend void
218 swap( _vval& lh, _vval& rh )
noexcept( std::is_nothrow_swappable_v< core_type > )
220 swap( lh._core, rh._core );
223 constexpr ~_vval() noexcept( std::is_nothrow_destructible_v< core_type > )
228 friend constexpr auto operator<=>( _vval
const& lh, _vval
const& rh )
noexcept(
229 all_nothrow_three_way_comparable_v< types > )
231 return core_type::three_way_compare( lh._core, rh._core );
234 friend constexpr auto operator==( _vval
const& lh, _vval
const& rh )
noexcept(
235 all_nothrow_equality_comparable_v< types > )
237 return core_type::compare( lh._core, rh._core );
241 constexpr _vval() noexcept = default;
245 template < typename... Us >
247 template < typename... Us >
251template < 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