vari
Loading...
Searching...
No Matches
vval.h
1
23
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"
29#include "vari/vptr.h"
30#include "vari/vref.h"
31
32#include <type_traits>
33#include <utility>
34
35#pragma once
36
37namespace vari
38{
39
40// WARNING: experimental
41template < typename... Ts >
42class _vval
43{
44 using core_type = _val_core< typelist< Ts... > >;
45
46public:
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... >;
52
53 template < typename U >
54 requires( vconvertible_type< std::remove_cvref_t< U >, types > )
55 constexpr _vval( U&& v ) noexcept( _forward_nothrow_constructible< U > )
56 {
57 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
58 }
59
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... > )
64 {
65 _core.template emplace< U >( (Args&&) args... );
66 }
67
68 constexpr _vval( _vval&& p ) noexcept( std::is_nothrow_move_constructible_v< core_type > )
69 : _core( std::move( p._core ) )
70 {
71 }
72
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 ) )
78 {
79 }
80
81 constexpr _vval( _vval const& p ) noexcept(
82 std::is_nothrow_copy_constructible_v< core_type > )
83 : _core( p._core )
84 {
85 }
86
87 template < typename... Us >
88 requires( vconvertible_to< typelist< Us... >, types > )
89 constexpr _vval( _vval< Us... > const& p ) noexcept(
90 std::
91 is_nothrow_constructible_v< core_type, typename _vval< Us... >::core_type const& > )
92 : _core( p._core )
93 {
94 }
95
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 > )
99 {
100 if ( _core.index != null_index )
101 _core.destroy();
102 _core.template emplace< std::remove_cvref_t< U > >( (U&&) v );
103 return *this;
104 }
105
106 constexpr _vval& operator=( _vval&& p ) noexcept(
107 core_type::template is_nothrow_assignable< typename _vval::core_type&& > )
108 {
109 _core.assign( std::move( p._core ) );
110 return *this;
111 }
112
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&& > )
117 {
118 _core.assign( std::move( p._core ) );
119 return *this;
120 }
121
122 constexpr _vval& operator=( _vval const& p ) noexcept(
123 core_type::template is_nothrow_assignable< typename _vval::core_type const& > )
124 {
125 _core.assign( p._core );
126 return *this;
127 }
128
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& > )
133 {
134 _core.assign( p._core );
135 return *this;
136 }
137
138 template < typename T, typename... Args >
139 requires( vconvertible_type< T, types > )
140 constexpr T&
141 emplace( Args&&... args ) noexcept( std::is_nothrow_constructible_v< T, Args... > )
142 {
143 _core.destroy();
144 return _core.template emplace< T >( (Args&&) args... );
145 }
146
147 [[nodiscard]] constexpr index_type index() const noexcept
148 {
149 return _core.index;
150 }
151
152 constexpr auto& operator*() const noexcept
153 requires( types::size == 1 )
154 {
155 return core_type::ST::template get< 0 >( _core.storage );
156 }
157
158 constexpr auto* operator->() const noexcept
159 requires( types::size == 1 )
160 {
161 return &**this;
162 }
163
164 template < typename... Us >
165 requires( vconvertible_to< types, typelist< Us... > > )
166 constexpr operator _vref< Us... >() & noexcept
167 {
168 return core_type::visit_impl( _core, [&]( auto& item ) {
169 return _vref< Us... >( item );
170 } );
171 }
172
173 template < typename... Us >
174 requires( vconvertible_to< types, typelist< Us... > > )
175 constexpr operator _vref< Us... >() const& noexcept
176 {
177 static_assert( all_is_const_v< typelist< Us... > > );
178 return core_type::visit_impl( _core, [&]( auto& item ) {
179 return _vref< Us... >( item );
180 } );
181 }
182
183 constexpr reference vref() & noexcept
184 {
185 return reference{ *this };
186 }
187
188 constexpr const_reference vref() const& noexcept
189 {
190 return const_reference{ *this };
191 }
192
193 constexpr pointer vptr() & noexcept
194 {
195 return reference{ *this }.vptr();
196 }
197
198 constexpr const_pointer vptr() const& noexcept
199 {
200 return const_reference{ *this }.vptr();
201 }
202
203 template < typename... Fs >
204 constexpr decltype( auto ) visit( Fs&&... f ) const
205 {
206 typename _check_unique_invocability< types >::template with_pure_cref< Fs... > _{};
207 return core_type::visit_impl( _core, (Fs&&) f... );
208 }
209
210 template < typename... Fs >
211 constexpr decltype( auto ) visit( Fs&&... f )
212 {
213 typename _check_unique_invocability< types >::template with_pure_ref< Fs... > _{};
214 return core_type::visit_impl( _core, (Fs&&) f... );
215 }
216
217 constexpr friend void
218 swap( _vval& lh, _vval& rh ) noexcept( std::is_nothrow_swappable_v< core_type > )
219 {
220 swap( lh._core, rh._core );
221 }
222
223 constexpr ~_vval() noexcept( std::is_nothrow_destructible_v< core_type > )
224 {
225 _core.destroy();
226 }
227
228 friend constexpr auto operator<=>( _vval const& lh, _vval const& rh ) noexcept(
229 all_nothrow_three_way_comparable_v< types > )
230 {
231 return core_type::three_way_compare( lh._core, rh._core );
232 };
233
234 friend constexpr auto operator==( _vval const& lh, _vval const& rh ) noexcept(
235 all_nothrow_equality_comparable_v< types > )
236 {
237 return core_type::compare( lh._core, rh._core );
238 };
239
240private:
241 constexpr _vval() noexcept = default;
242
243 core_type _core;
244
245 template < typename... Us >
246 friend class _vval;
247 template < typename... Us >
248 friend class _vopt;
249};
250
251template < typename... Ts >
252using vval = _define_variadic< _vval, typelist< Ts... > >;
253
254} // namespace vari
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