vari
Loading...
Searching...
No Matches
ptr_core.h
1
23
24#pragma once
25
26#include "vari/bits/dispatch.h"
27#include "vari/bits/typelist.h"
28#include "vari/bits/util.h"
29#include "vari/concept.h"
30
31#include <compare>
32#include <cstddef>
33#include <utility>
34
35namespace vari
36{
37
38template < typename T >
39constexpr void* _to_void_cast( T* p ) noexcept
40{
41 return static_cast< void* >( const_cast< std::remove_const_t< T >* >( p ) );
42}
43
44template < typename TL >
45struct _ptr_core
46{
47
48 index_type index = null_index;
49 void* ptr = nullptr;
50
51
52 constexpr _ptr_core() noexcept = default;
53
54 template < typename UL >
55 requires( vconvertible_to< UL, TL > )
56 constexpr _ptr_core( _ptr_core< UL > other ) noexcept
57 : index( _vptr_cnv_map< TL, UL >::conv( other.get_index() ) )
58 , ptr( _to_void_cast( other.ptr ) )
59 {
60 }
61
62 friend constexpr void swap( _ptr_core& lh, _ptr_core& rh ) noexcept
63 {
64 std::swap( lh.ptr, rh.ptr );
65 std::swap( lh.index, rh.index );
66 }
67
68 template < typename U >
69 requires( vconvertible_to< typelist< U >, TL > )
70 constexpr void set( U& val ) noexcept
71 {
72 index = index_of_t_or_const_t_v< U, TL >;
73 ptr = _to_void_cast( &val );
74 }
75
76 constexpr void reset() noexcept
77 {
78 *this = _ptr_core{};
79 }
80
81 [[nodiscard]] constexpr index_type get_index() const noexcept
82 {
83 return index;
84 }
85
86 template < typename... Fs >
87 constexpr decltype( auto ) visit_impl( Fs&&... fs ) const
88 {
89 return _dispatch_index< 0, TL::size >(
90 index, [&]< index_type j >() -> decltype( auto ) {
91 using U = type_at_t< j, TL >;
92 U* p = static_cast< U* >( ptr );
93 return _dispatch_fun( *p, (Fs&&) fs... );
94 } );
95 }
96
97 template < template < typename... > typename ArgTempl, typename... Fs >
98 constexpr decltype( auto ) take_impl( Fs&&... fs ) const
99 {
100 return _dispatch_index< 0, TL::size >(
101 index, [&]< index_type j >() -> decltype( auto ) {
102 using U = type_at_t< j, TL >;
103 using ArgType = ArgTempl< U >;
104 U* p = static_cast< U* >( ptr );
105 return _dispatch_fun( ArgType{ *p }, (Fs&&) fs... );
106 } );
107 }
108
109 constexpr void delete_ptr( auto&& del )
110 {
111 if ( index == null_index )
112 return;
113 _dispatch_index< 0, TL::size >( index, [&]< index_type j > {
114 using U = type_at_t< j, TL >;
115 del( static_cast< U* >( ptr ) );
116 } );
117 }
118};
119
120template < typename T >
121struct _ptr_core< typelist< T > >
122{
123
124 T* ptr = nullptr;
125
126 constexpr _ptr_core() noexcept = default;
127
128 constexpr _ptr_core( _ptr_core< typelist<> > ) noexcept
129 : ptr( nullptr )
130 {
131 }
132
133 template < typename U >
134 requires( std::same_as< U, T > || std::same_as< U const, T > )
135 constexpr _ptr_core( _ptr_core< typelist< U > > other ) noexcept
136 : ptr( other.ptr )
137 {
138 }
139
140 friend constexpr void swap( _ptr_core& lh, _ptr_core& rh ) noexcept
141 {
142 std::swap( lh.ptr, rh.ptr );
143 }
144
145 template < typename U >
146 requires( vconvertible_to< typelist< U >, typelist< T > > )
147 constexpr void set( U& val ) noexcept
148 {
149 ptr = &val;
150 }
151
152 constexpr void reset() noexcept
153 {
154 *this = _ptr_core{};
155 }
156
157
158 [[nodiscard]] constexpr index_type get_index() const noexcept
159 {
160 return ptr == nullptr ? null_index : 0;
161 }
162
163 template < typename... Fs >
164 constexpr decltype( auto ) visit_impl( Fs&&... fs ) const
165 {
166 return _dispatch_fun( *ptr, (Fs&&) fs... );
167 }
168
169 template < template < typename... > typename ArgTempl, typename... Fs >
170 constexpr decltype( auto ) take_impl( Fs&&... fs ) const
171 {
172 using ArgType = ArgTempl< T >;
173 return _dispatch_fun( ArgType( *ptr ), (Fs&&) fs... );
174 }
175
176 constexpr void delete_ptr( auto&& del )
177 {
178 if ( ptr != nullptr )
179 del( ptr );
180 }
181};
182
183template < typename T >
184constexpr auto operator<=>( _ptr_core< T > const& lh, _ptr_core< T > const& rh ) noexcept
185{
186 return std::compare_three_way{}( lh.ptr, rh.ptr );
187}
188
189template < typename T >
190constexpr bool operator==( _ptr_core< T > const& lh, _ptr_core< T > const& rh ) noexcept
191{
192 return lh.ptr == rh.ptr;
193}
194
195} // namespace vari
MIT License.
Definition: dispatch.h:32