26#include "vari/bits/dispatch.h"
27#include "vari/bits/typelist.h"
28#include "vari/bits/util.h"
29#include "vari/concept.h"
38template <
typename T >
39constexpr void* _to_void_cast( T* p )
noexcept
41 return static_cast< void*
>(
const_cast< std::remove_const_t< T >*
>( p ) );
44template <
typename TL >
48 index_type index = null_index;
52 constexpr _ptr_core() noexcept = default;
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 ) )
62 friend constexpr void swap( _ptr_core& lh, _ptr_core& rh )
noexcept
64 std::swap( lh.ptr, rh.ptr );
65 std::swap( lh.index, rh.index );
68 template <
typename U >
69 requires( vconvertible_to< typelist< U >, TL > )
70 constexpr void set( U& val )
noexcept
72 index = index_of_t_or_const_t_v< U, TL >;
73 ptr = _to_void_cast( &val );
76 constexpr void reset() noexcept
81 [[nodiscard]]
constexpr index_type get_index() const noexcept
86 template <
typename... Fs >
87 constexpr decltype( auto ) visit_impl( Fs&&... fs )
const
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... );
97 template <
template <
typename... >
typename ArgTempl,
typename... Fs >
98 constexpr decltype( auto ) take_impl( Fs&&... fs )
const
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... );
109 constexpr void delete_ptr(
auto&& del )
111 if ( index == null_index )
113 _dispatch_index< 0, TL::size >( index, [&]< index_type j > {
114 using U = type_at_t< j, TL >;
115 del(
static_cast< U*
>( ptr ) );
120template <
typename T >
121struct _ptr_core< typelist< T > >
126 constexpr _ptr_core() noexcept = default;
128 constexpr _ptr_core( _ptr_core< typelist<> > ) noexcept
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
140 friend constexpr void swap( _ptr_core& lh, _ptr_core& rh )
noexcept
142 std::swap( lh.ptr, rh.ptr );
145 template <
typename U >
146 requires( vconvertible_to< typelist< U >, typelist< T > > )
147 constexpr void set( U& val )
noexcept
152 constexpr void reset() noexcept
158 [[nodiscard]]
constexpr index_type get_index() const noexcept
160 return ptr ==
nullptr ? null_index : 0;
163 template <
typename... Fs >
164 constexpr decltype( auto ) visit_impl( Fs&&... fs )
const
166 return _dispatch_fun( *ptr, (Fs&&) fs... );
169 template <
template <
typename... >
typename ArgTempl,
typename... Fs >
170 constexpr decltype( auto ) take_impl( Fs&&... fs )
const
172 using ArgType = ArgTempl< T >;
173 return _dispatch_fun( ArgType( *ptr ), (Fs&&) fs... );
176 constexpr void delete_ptr(
auto&& del )
178 if ( ptr !=
nullptr )
183template <
typename T >
184constexpr auto operator<=>( _ptr_core< T >
const& lh, _ptr_core< T >
const& rh )
noexcept
186 return std::compare_three_way{}( lh.ptr, rh.ptr );
189template <
typename T >
190constexpr bool operator==( _ptr_core< T >
const& lh, _ptr_core< T >
const& rh )
noexcept
192 return lh.ptr == rh.ptr;
MIT License.
Definition: dispatch.h:32