vari
Loading...
Searching...
No Matches
uvref.h
1
23
24#pragma once
25
26#include "vari/bits/assert.h"
27#include "vari/bits/ptr_core.h"
28#include "vari/bits/typelist.h"
29#include "vari/bits/util.h"
30#include "vari/deleter.h"
31#include "vari/forward.h"
32#include "vari/vptr.h"
33#include "vari/vref.h"
34
35
36namespace vari
37{
38
41template < typename Deleter, typename... Ts >
42class _uvref : private _deleter_box< Deleter >
43{
44 template < typename... Us >
45 using same_uvref = _uvref< Deleter, Us... >;
46 using dbox = _deleter_box< Deleter >;
47
48public:
49 using types = typelist< Ts... >;
50
51 using core_type = _ptr_core< types >;
52 using reference = _vref< Ts... >;
53 using pointer = _vptr< Ts... >;
54 using owning_pointer = _uvptr< Deleter, Ts... >;
55
56 constexpr _uvref( _uvref const& ) = delete;
57 constexpr _uvref& operator=( _uvref const& ) = delete;
58
61 template < typename Deleter2, typename... Us >
62 requires(
63 vconvertible_to< typelist< Us... >, types > &&
64 convertible_deleter< Deleter2, Deleter > )
65 constexpr _uvref( _uvref< Deleter2, Us... >&& p ) noexcept
66 : dbox( std::move( (dbox&) p ) )
67 {
68 _core = std::move( p._core );
69 p._core.reset();
70 }
71
74 template < typename U >
75 requires( vconvertible_type< U, types > )
76 constexpr explicit _uvref( U& u ) noexcept
77 {
78 _core.set( u );
79 }
80
85 template < typename U >
86 requires( vconvertible_type< U, types > && copy_constructible_deleter< Deleter > )
87 constexpr explicit _uvref( U& u, Deleter const& d ) noexcept
88 : dbox( d )
89 {
90 _core.set( u );
91 }
92
97 template < typename U >
98 requires( vconvertible_type< U, types > && move_constructible_deleter< Deleter > )
99 constexpr explicit _uvref( U& u, Deleter&& d ) noexcept
100 : dbox( std::move( d ) )
101 {
102 _core.set( u );
103 }
104
107 template < typename Deleter2, typename... Us >
108 requires(
109 vconvertible_to< typelist< Us... >, types > &&
110 convertible_deleter< Deleter2, Deleter > )
111 constexpr _uvref& operator=( _uvref< Deleter2, Us... >&& p ) noexcept
112 {
113 _uvref tmp{ std::move( p ) };
114 swap( _core, tmp._core );
115 swap( (dbox&) ( *this ), (dbox&) tmp );
116 return *this;
117 }
118
121 constexpr auto& operator*() const noexcept
122 {
123 return *_core.ptr;
124 }
125
128 constexpr auto* operator->() const noexcept
129 {
130 return _core.ptr;
131 }
132
134 constexpr reference get() const noexcept
135 {
136 VARI_ASSERT( _core.ptr );
137 reference res;
138 res._core = _core;
139 return res;
140 }
141
144 [[nodiscard]] constexpr index_type index() const noexcept
145 {
146 VARI_ASSERT( _core.ptr );
147 return _core.index;
148 }
149
152 template < typename... Us >
153 requires( vconvertible_to< types, typelist< Us... > > )
154 constexpr operator _vref< Us... >() & noexcept
155 {
156 VARI_ASSERT( _core.ptr );
157 return vptr().vref();
158 }
161 template < typename... Us >
162 requires( vconvertible_to< types, typelist< Us... > > )
163 constexpr operator _vref< Us... >() const& noexcept
164 {
165 VARI_ASSERT( _core.ptr );
166 return vptr().vref();
167 }
168
170 template < typename... Us >
171 constexpr operator _vref< Us... >() && = delete;
172
175 constexpr pointer vptr() const& noexcept
176 {
177 VARI_ASSERT( _core.ptr );
178 pointer res;
179 res._core = _core;
180 return res;
181 }
182
185 constexpr owning_pointer vptr() && noexcept
186 {
187 VARI_ASSERT( _core.ptr );
188 owning_pointer res;
189 swap( res._core, _core );
190 return res;
191 }
192
195 template < typename... Fs >
196 constexpr decltype( auto ) visit( Fs&&... f ) const
197 {
198 typename _check_unique_invocability< types >::template with_pure_ref< Fs... > _{};
199 VARI_ASSERT( _core.ptr );
200 return _core.visit_impl( (Fs&&) f... );
201 }
202
205 template < typename... Fs >
206 constexpr decltype( auto ) take( Fs&&... fs ) &&
207 {
208 typename _check_unique_invocability< types >::template with_deleter<
209 Deleter >::template with_uvref< Fs... >
210 _{};
211 VARI_ASSERT( _core.ptr );
212 auto tmp = _core;
213 _core.reset();
214 return tmp.template take_impl< same_uvref >( (Fs&&) fs... );
215 }
216
219 Deleter& get_deleter() noexcept
220 {
221 return dbox::get();
222 }
223
226 Deleter const& get_deleter() const noexcept
227 {
228 return dbox::get();
229 }
230
231
234 constexpr ~_uvref()
235 {
236 _core.delete_ptr( dbox::get() );
237 }
238
241 friend constexpr void swap( _uvref& lh, _uvref& rh ) noexcept
242 {
243 swap( lh._core, rh._core );
244 swap( (dbox&) lh, (dbox&) rh );
245 }
246
247private:
248 constexpr _uvref() noexcept = default;
249
250 core_type _core;
251
252 template < typename... Us >
253 friend class _vptr;
254
255 template < typename Deleter2, typename... Us >
256 friend class _uvptr;
257
258 template < typename Deleter2, typename... Us >
259 friend class _uvref;
260};
261
264template < typename... Lhs, typename... Rhs >
265constexpr auto operator<=>( _uvref< Lhs... > const& lh, _uvref< Rhs... > const& rh ) noexcept
266{
267 return lh.get() <=> rh.get();
268}
269
272template < typename... Lhs, typename... Rhs >
273constexpr bool operator==( _uvref< Lhs... > const& lh, _uvref< Rhs... > const& rh ) noexcept
274{
275 return lh.get() == rh.get();
276}
277
280template < typename... Ts >
281using uvref = _define_variadic< _uvref, typelist< Ts... >, def_del >;
282
284template < typename T >
285constexpr uvref< T > uwrap( T item )
286{
287 return uvref< T >( *new T( std::move( item ) ) );
288}
289
290} // namespace vari
291
292VARI_REC_GET_HASH_SPECIALIZATION( vari::_uvref );
A nullable owning pointer to one of the types in Ts...
Definition: uvptr.h:43
A nullable pointer to one of the types in Ts...
Definition: vptr.h:42
A non-nullable pointer to one of the types in Ts...
Definition: vref.h:40
constexpr auto * get() const noexcept
Returns a pointer to the pointed-to type.
Definition: vref.h:80
MIT License.
Definition: dispatch.h:32
_define_variadic< _uvref, typelist< Ts... >, def_del > uvref
A non-nullable owning pointer to types derived out of Ts... list by flattening it and filtering for u...
Definition: uvref.h:281
constexpr uvref< T > uwrap(T item)
Wraps object item into uvref of its type.
Definition: uvref.h:285
_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
A non-nullable owning pointer to one of the types in Ts...
Definition: uvref.h:43
constexpr _uvref(U &u, Deleter &&d) noexcept
Constructs an uvref which owns a reference to one of the types that uvref can reference.
Definition: uvref.h:99
friend constexpr void swap(_uvref &lh, _uvref &rh) noexcept
Swaps uvref with each other.
Definition: uvref.h:241
constexpr auto & operator*() const noexcept
Dereferences to the pointed-to type.
Definition: uvref.h:121
constexpr pointer vptr() const &noexcept
Constructs a variadic pointer that points to the same target as the current reference.
Definition: uvref.h:175
constexpr reference get() const noexcept
Returns a reference to the pointed-to type.
Definition: uvref.h:134
constexpr _uvref(U &u) noexcept
Constructs an uvref which owns a reference to one of the types that uvref can reference.
Definition: uvref.h:76
Deleter & get_deleter() noexcept
Getter to the internal deleter.
Definition: uvref.h:219
constexpr index_type index() const noexcept
Returns the index representing the type currently being referenced.
Definition: uvref.h:144
constexpr ~_uvref()
Destroys the owned object.
Definition: uvref.h:234
constexpr _uvref(U &u, Deleter const &d) noexcept
Constructs an uvref which owns a reference to one of the types that uvref can reference.
Definition: uvref.h:87
constexpr _uvref(_uvref< Deleter2, Us... > &&p) noexcept
Constructs an uvref by transfering ownership from uvref with compatible types.
Definition: uvref.h:65
constexpr owning_pointer vptr() &&noexcept
Constructs an owning variadic pointer and transfers ownership of current target to the pointer.
Definition: uvref.h:185
constexpr auto * operator->() const noexcept
Provides member access to the pointed-to type.
Definition: uvref.h:128
constexpr decltype(auto) visit(Fs &&... f) const
Calls the appropriate function from the list fs..., based on the type of the current target.
Definition: uvref.h:196
Deleter const & get_deleter() const noexcept
Getter to the internal deleter.
Definition: uvref.h:226
constexpr decltype(auto) take(Fs &&... fs) &&
Constructs an owning reference to currently pointed-to type and transfers ownership to it.
Definition: uvref.h:206
Default library deleter.
Definition: deleter.h:33