26#include "vari/bits/typelist.h"
42static constexpr empty_t empty;
45template <
template <
typename... >
typename T,
typename TL,
typename... Us >
48template <
template <
typename... >
typename T,
typename... Ts,
typename... Us >
49struct _vptr_apply< T, typelist< Ts... >, Us... >
51 using type = T< Us..., Ts... >;
54template <
template <
typename... >
typename T,
typename TL,
typename... Us >
55using _vptr_apply_t =
typename _vptr_apply< T, TL, Us... >::type;
60template <
template <
typename... >
typename T,
typename TL,
typename... Extra >
61using _define_variadic = _vptr_apply_t< T, unique_typelist_t< flatten_t< TL > >, Extra... >;
63template <
typename F,
typename... Args >
64concept invocable =
requires( F&& f, Args&&... args ) { ( (F&&) f )( (Args&&) args... ); };
67template <
typename U >
68concept _forward_nothrow_constructible =
69 ( std::is_lvalue_reference_v< U > ?
70 std::is_nothrow_copy_constructible_v< std::remove_reference_t< U > > :
71 std::is_nothrow_move_constructible_v< U > );
73template <
typename T,
typename... Fs >
74concept invocable_for_one = ( (+invocable< Fs, T >) +... ) == 1;
76template <
typename F,
typename... Ts >
77concept invocable_with_any = ( invocable< F, Ts > || ... || false );
79template <
typename Deleter,
typename... Ts >
82template <
typename T >
83struct _check_unique_invocability;
85template <
typename... Ts >
86struct _check_unique_invocability< typelist< Ts... > >
88 template <
typename... Fs >
89 struct with_pure_value
92 ( invocable_for_one< Ts, Fs... > && ... ),
93 "For each type, there has to be one and only one callable" );
95 ( invocable_with_any< Fs, Ts... > && ... ),
96 "For each function, there has to be at least one type it is invocable with" );
99 template <
typename... Fs >
103 ( invocable_for_one< Ts&, Fs... > && ... ),
104 "For each type, there has to be one and only one callable" );
106 ( invocable_with_any< Fs, Ts&... > && ... ),
107 "For each function, there has to be at least one type it is invocable with" );
110 template <
typename... Fs >
111 struct with_nullable_pure_ref
114 (invocable_for_one< Ts&, Fs... > && ... && invocable_for_one< empty_t, Fs... >),
115 "For each type, there has to be one and only one callable" );
117 ( invocable_with_any< Fs, empty_t, Ts&... > && ... ),
118 "For each function, there has to be at least one type it is invocable with" );
121 template <
typename... Fs >
122 struct with_pure_cref
125 ( invocable_for_one< Ts
const&, Fs... > && ... ),
126 "For each type, there has to be one and only one callable" );
128 ( invocable_with_any< Fs, Ts
const&... > && ... ),
129 "For each function, there has to be at least one type it is invocable with" );
132 template <
typename... Fs >
133 struct with_nullable_pure_cref
136 (invocable_for_one< Ts
const&, Fs... > && ... &&
137 invocable_for_one< empty_t, Fs... >),
138 "For each type, there has to be one and only one callable" );
140 ( invocable_with_any< Fs, empty_t, Ts
const&... > && ... ),
141 "For each function, there has to be at least one type it is invocable with" );
144 template <
typename Deleter >
147 template <
typename... Fs >
151 ( invocable_for_one< _uvref< Deleter, Ts >, Fs... > && ... ),
152 "For each type, there has to be one and only one callable" );
154 ( invocable_with_any< Fs, _uvref< Deleter, Ts >... > && ... ),
155 "For each function, there has to be at least one type it is invocable with" );
158 template <
typename... Fs >
159 struct with_nullable_uvref
162 (invocable_for_one< _uvref< Deleter, Ts >, Fs... > && ... &&
163 invocable_for_one< empty_t, Fs... >),
164 "For each type, there has to be one and only one callable" );
166 ( invocable_with_any< Fs, empty_t, _uvref< Deleter, Ts >... > && ... ),
167 "For each function, there has to be at least one type it is invocable with" );
172template <
typename... Args >
173struct _function_picker
175 template <
typename F,
typename... Fs >
176 static constexpr decltype( auto ) pick( F&& f, Fs&&... fs )
178 if constexpr ( invocable< F, Args... > ) {
181 static_assert(
sizeof...( fs ) != 0 );
182 return pick( (Fs&&) fs... );
187using index_type = uint32_t;
188static constexpr auto null_index = std::numeric_limits< index_type >::max();
190template <
typename TL,
typename UL >
193template <
typename TL,
typename... Us >
194struct _vptr_cnv_map< TL, typelist< Us... > >
196 static constexpr index_type conv( std::size_t i )
198 return i == null_index ? null_index : value[i];
202 static constexpr index_type value[
sizeof...( Us )] = {
203 index_of_t_or_const_t_v< Us, TL >... };
206template <
typename UL,
typename TL >
209template <
typename... Us,
typename T,
typename... Ts >
210 requires(
sizeof...( Us ) <
sizeof...( Ts ) )
211struct _split_impl< typelist< Us... >, typelist< T, Ts... > >
213 using sub = _split_impl< typelist< Us..., T >, typelist< Ts... > >;
214 using lh =
typename sub::lh;
215 using rh =
typename sub::rh;
218template <
typename... Us,
typename T,
typename... Ts >
219 requires(
sizeof...( Us ) >=
sizeof...( Ts ) )
220struct _split_impl< typelist< Us... >, typelist< T, Ts... > >
222 using lh = typelist< Us... >;
223 using rh = typelist< T, Ts... >;
227struct _split_impl< typelist<>, typelist<> >
229 using lh = typelist<>;
230 using rh = typelist<>;
233template <
typename TL >
234using split = _split_impl< typelist<>, TL >;
236template <
typename Deleter >
239template <
typename Deleter >
240 requires( !std::is_lvalue_reference_v< Deleter > )
241struct _deleter_box< Deleter > :
private Deleter
243 constexpr _deleter_box() noexcept = default;
245 constexpr _deleter_box( Deleter&& d ) noexcept
246 : Deleter( std::move( d ) )
248 static_assert( std::is_nothrow_move_constructible_v< Deleter > );
251 constexpr Deleter& get() noexcept
256 friend constexpr void swap( _deleter_box& lh, _deleter_box& rh )
noexcept
259 swap( (Deleter&) lh, (Deleter&) rh );
262 friend constexpr auto operator<=>( _deleter_box
const&, _deleter_box
const& ) =
default;
265template <
typename Deleter >
266 requires( std::is_lvalue_reference_v< Deleter& > )
267struct _deleter_box< Deleter& >
269 constexpr _deleter_box() noexcept = delete;
271 constexpr _deleter_box( Deleter& d ) noexcept
276 constexpr Deleter& get() noexcept
281 friend constexpr void swap( _deleter_box& lh, _deleter_box& rh )
noexcept
284 swap( lh._del_ref, rh._del_ref );
287 friend constexpr auto operator<=>( _deleter_box
const&, _deleter_box
const& ) =
default;
293template < std::
size_t Align >
294constexpr std::intptr_t hash_ptr(
void* p )
296 return (std::intptr_t) ( p ) >> std::bit_width( Align );
301#define VARI_GET_PTR_HASH_SPECIALIZATION( TYPE ) \
302 template < typename... Ts > \
303 struct std::hash< TYPE< Ts... > > \
305 std::size_t operator()( TYPE< Ts... > const& r ) const \
307 return vari::hash_ptr< std::min( { alignof( Ts )... } ) >( r.get() ); \
311#define VARI_REC_GET_HASH_SPECIALIZATION( TYPE ) \
312 template < typename... Ts > \
313 struct std::hash< TYPE< Ts... > > \
315 std::size_t operator()( TYPE< Ts... > const& r ) const \
318 return std::hash< decltype( x ) >()( x ); \
MIT License.
Definition: dispatch.h:32
_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