vari
Loading...
Searching...
No Matches
uvptr.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
34#include <cstddef>
35
36namespace vari
37{
38
41template < typename Deleter, typename... Ts >
42class _uvptr : 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 pointer = _vptr< Ts... >;
53 using reference = _vref< Ts... >;
54 using owning_reference = _uvref< Deleter, Ts... >;
55
56 constexpr _uvptr() noexcept = default;
57
58 constexpr _uvptr( _uvptr const& ) = delete;
59 constexpr _uvptr& operator=( _uvptr const& ) = delete;
60
63 constexpr _uvptr( std::nullptr_t ) noexcept
64 {
65 }
66
69 template < typename Deleter2, typename... Us >
70 requires(
71 vconvertible_to< typelist< Us... >, types > &&
72 convertible_deleter< Deleter2, Deleter > )
73 constexpr explicit _uvptr( _uvref< Deleter2, Us... >&& p ) noexcept
74 {
75 _core = std::move( p._core );
76 p._core.reset();
77 }
78
81 template < typename Deleter2, typename... Us >
82 requires(
83 vconvertible_to< typelist< Us... >, types > &&
84 convertible_deleter< Deleter2, Deleter > )
85 constexpr _uvptr( _uvptr< Deleter2, Us... >&& p ) noexcept
86 : dbox( std::move( (dbox&) p ) )
87 {
88 _core = std::move( p._core );
89 p._core.reset();
90 }
91
92
95 template < typename U >
96 requires( vconvertible_type< U, types > )
97 constexpr _uvptr( U* u ) noexcept
98 {
99 if ( u )
100 _core.set( *u );
101 }
102
107 template < typename U >
108 requires( vconvertible_type< U, types > && copy_constructible_deleter< Deleter > )
109 constexpr _uvptr( U* u, Deleter const& d ) noexcept
110 : dbox( d )
111 {
112 if ( u )
113 _core.set( *u );
114 }
115
120 template < typename U >
121 requires( vconvertible_type< U, types > && move_constructible_deleter< Deleter > )
122 constexpr _uvptr( U* u, Deleter&& d ) noexcept
123 : dbox( std::move( d ) )
124 {
125 if ( u )
126 _core.set( *u );
127 }
128
129
132 constexpr _uvptr& operator=( std::nullptr_t ) noexcept
133 {
134 reset( nullptr );
135 return *this;
136 }
137
140 template < typename Deleter2, typename... Us >
141 requires(
142 vconvertible_to< typelist< Us... >, types > &&
143 convertible_deleter< Deleter2, Deleter > )
144 constexpr _uvptr& operator=( _uvptr< Deleter2, Us... >&& p ) noexcept
145 {
146 _uvptr tmp{ std::move( p ) };
147 swap( _core, tmp._core );
148 swap( (dbox&) ( *this ), (dbox&) tmp );
149 return *this;
150 }
151
154 constexpr auto& operator*() const noexcept
155 {
156 return *_core.ptr;
157 }
158
161 constexpr auto* operator->() const noexcept
162 {
163 return _core.ptr;
164 }
165
167 constexpr pointer get() const noexcept
168 {
169 pointer res;
170 res._core = _core;
171 return res;
172 }
173
177 [[nodiscard]] constexpr index_type index() const noexcept
178 {
179 return _core.get_index();
180 }
181
184 template < typename... Us >
185 requires( vconvertible_to< types, typelist< Us... > > )
186 constexpr operator _vptr< Us... >() & noexcept
187 {
188 _vptr< Us... > res;
189 res._core = _core;
190 return res;
191 }
192
195 template < typename... Us >
196 requires( vconvertible_to< types, typelist< Us... > > )
197 constexpr operator _vptr< Us... >() const& noexcept
198 {
199 _vptr< Us... > res;
200 res._core = _core;
201 return res;
202 }
203
205 template < typename... Us >
206 constexpr operator _vptr< Us... >() && = delete;
207
208 constexpr void reset( pointer ptr = pointer() )
209 {
210 auto tmp = _core;
211 _core = std::move( ptr._core );
212 tmp.delete_ptr( _deleter_box< Deleter >::get() );
213 }
214
217 constexpr pointer release() noexcept
218 {
219 pointer res;
220 swap( res._core, _core );
221 return res;
222 }
223
226 constexpr explicit operator bool() const noexcept
227 {
228 return _core.get_index() != null_index;
229 }
230
233 constexpr reference vref() const& noexcept
234 {
235 VARI_ASSERT( _core.get_index() != null_index );
236 reference res;
237 res._core = _core;
238 return res;
239 }
240
243 constexpr owning_reference vref() && noexcept
244 {
245 VARI_ASSERT( _core.get_index() != null_index );
247 swap( res._core, _core );
248 return res;
249 }
250
253 template < typename... Fs >
254 constexpr decltype( auto ) visit( Fs&&... f ) const
255 {
256
257 typename _check_unique_invocability< types >::template with_nullable_pure_ref<
258 Fs... >
259 _{};
260 if ( _core.ptr == nullptr )
261 return _dispatch_fun( empty, (Fs&&) f... );
262 return _core.visit_impl( (Fs&&) f... );
263 }
264
268 template < typename... Fs >
269 constexpr decltype( auto ) take( Fs&&... fs ) &&
270 {
271 typename _check_unique_invocability< types >::template with_deleter<
272 Deleter >::template with_nullable_uvref< Fs... >
273 _{};
274 auto p = release();
275 if ( p._core.ptr == nullptr )
276 return _dispatch_fun( empty, (Fs&&) fs... );
277 return p._core.template take_impl< same_uvref >( (Fs&&) fs... );
278 }
279
282 Deleter& get_deleter() noexcept
283 {
284 return dbox::get();
285 }
286
289 Deleter const& get_deleter() const noexcept
290 {
291 return dbox::get();
292 }
293
296 constexpr ~_uvptr()
297 {
298 _core.delete_ptr( _deleter_box< Deleter >::get() );
299 }
300
303 friend constexpr void swap( _uvptr& lh, _uvptr& rh ) noexcept
304 {
305 swap( lh._core, rh._core );
306 swap( (dbox&) lh, (dbox&) rh );
307 }
308
309private:
310 core_type _core;
311
312 template < typename Deleter2, typename... Us >
313 friend class _uvptr;
314
315 template < typename Deleter2, typename... Us >
316 friend class _uvref;
317};
318
321template < typename... Lhs, typename... Rhs >
322constexpr auto operator<=>( _uvptr< Lhs... > const& lh, _uvptr< Rhs... > const& rh ) noexcept
323{
324 return lh.get() <=> rh.get();
325}
326
329template < typename... Lhs, typename... Rhs >
330constexpr bool operator==( _uvptr< Lhs... > const& lh, _uvptr< Rhs... > const& rh ) noexcept
331{
332 return lh.get() == rh.get();
333}
334
337template < typename... Ts >
338using uvptr = _define_variadic< _uvptr, typelist< Ts... >, def_del >;
339
340} // namespace vari
341
342VARI_REC_GET_HASH_SPECIALIZATION( vari::_uvptr );
A nullable owning pointer to one of the types in Ts...
Definition: uvptr.h:43
constexpr _uvptr(U *u, Deleter &&d) noexcept
Constructs an uvptr which owns a pointer to one of the types that uvptr can reference.
Definition: uvptr.h:122
constexpr ~_uvptr()
Destroys the owned object, if any.
Definition: uvptr.h:296
friend constexpr void swap(_uvptr &lh, _uvptr &rh) noexcept
Swaps uvptr with each other.
Definition: uvptr.h:303
constexpr _uvptr(U *u) noexcept
Constructs an uvptr which owns a pointer to one of the types that uvptr can reference.
Definition: uvptr.h:97
constexpr _uvptr & operator=(std::nullptr_t) noexcept
nullptr assignment operator resets this pointer.
Definition: uvptr.h:132
Deleter & get_deleter() noexcept
Getter to the internal deleter.
Definition: uvptr.h:282
constexpr decltype(auto) take(Fs &&... fs) &&
Constructs an owning reference to currently pointed-to type and transfers ownership to it.
Definition: uvptr.h:269
constexpr decltype(auto) visit(Fs &&... f) const
Calls the appropriate function from the list fs..., based on the type of the current target,...
Definition: uvptr.h:254
constexpr auto * operator->() const noexcept
Provides member access to the pointed-to type.
Definition: uvptr.h:161
constexpr pointer get() const noexcept
Returns a pointer to the pointed-to type.
Definition: uvptr.h:167
Deleter const & get_deleter() const noexcept
Getter to the internal deleter.
Definition: uvptr.h:289
constexpr index_type index() const noexcept
Returns the index representing the type currently being pointed-to.
Definition: uvptr.h:177
constexpr _uvptr(U *u, Deleter const &d) noexcept
Constructs an uvptr which owns a pointer to one of the types that uvptr can reference.
Definition: uvptr.h:109
constexpr _uvptr(_uvref< Deleter2, Us... > &&p) noexcept
Constructs an uvptr by transfering ownership from uvref with compatible types.
Definition: uvptr.h:73
constexpr pointer release() noexcept
Release the ownership of managed object, if any.
Definition: uvptr.h:217
constexpr owning_reference vref() &&noexcept
Constructs an owning variadic reference and trasnfers ownership of current target to the reference.
Definition: uvptr.h:243
constexpr reference vref() const &noexcept
Constructs a variadic reference that points to the same target as this pointer.
Definition: uvptr.h:233
constexpr _uvptr(_uvptr< Deleter2, Us... > &&p) noexcept
Constructs an uvptr by transfering ownership from uvptr with compatible types.
Definition: uvptr.h:85
constexpr _uvptr(std::nullptr_t) noexcept
Construct a pointer in a null state.
Definition: uvptr.h:63
constexpr auto & operator*() const noexcept
Dereferences to the pointed-to type.
Definition: uvptr.h:154
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
MIT License.
Definition: dispatch.h:32
_define_variadic< _uvptr, typelist< Ts... >, def_del > uvptr
A nullable owning pointer to types derived out of Ts... list by flattening it and filtering for uniqu...
Definition: uvptr.h:338
_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
Default library deleter.
Definition: deleter.h:33