32 template<
typename T >
35 template<
typename T >
38 template<
typename T >
53 template< Comparison_operators, Index,
typename >
59 template<
typename T >
69 template< range RangeType >
77 : start_( start ), end_( end )
84 return val >= rm.start_ && val <= rm.end_;
86 return val > rm.start_ && val < rm.end_;
92 template<
typename T >
97 template<
typename T >
103 template<
typename T, std::
size_t Sz >
108 template<
typename ... Args >
110 :
anythings{ std::forward< Args >( args )... }
114 template<
typename T_ >
117 #ifdef __cpp_lib_ranges
129 template<
typename ... Args >
130 Any_from_impl( Args &&... ) -> Any_from_impl< std::common_type_t< std::decay_t< Args >... >,
sizeof...( Args ) >;
140 template< std::
size_t Idx >
152 using namespace extension;
154 using Rng_t = Range< range::open >;
163 using namespace extension;
165 using Rng_t = Range< range::close >;
191 template<
typename T >
194 template< Comparison_operators Op, Index I >
197 template<
typename T >
200 template<
typename T >
203 template<
typename ... Ts >
206 template<
typename T >
209 template<
typename T >
212 template<
template<
typename T1,
typename T2 >
class Pair,
typename T1,
typename T2 >
215 std::true_type, std::false_type >
218 template<
typename T >
221 template<
typename T >
224 template<
template<
typename ... Ts >
class Tuple, typename ... Ts >
227 std::true_type, std::false_type >
230 template<
typename T >
233 template<
typename T >
236 template<
typename T >
239 template<
typename R,
typename C,
typename ... Args >
242 template<
typename R,
typename C,
typename ... Args >
245 template<
typename T >
255 template<
typename T >
258 template<
template<
typename,
std::size_t ... >
class C, typename T,
std::size_t ... Is >
261 std::is_same_v< C<T, Is... >, predicate_condition< T, Is... > >,
262 std::true_type, std::false_type >
266 template<
typename T >
269 template<
typename T >
274 template<
typename R,
typename C,
typename ... Args >
281 template<
typename R,
typename C,
typename ... Args >
288 template<
typename T,
typename =
void >
291 template<
typename T >
297 template<
typename T >
300 template<
typename T,
typename =
void >
303 template<
typename T >
309 template<
typename T >
312 template<
typename ... Ts >
315 static constexpr
bool value =
false;
318 template<
typename ... TupleCnds,
typename Cnd,
typename ... Cnds >
325 std::forward< Cnds >( cnds )...,
326 std::forward< Cnd >( cnd ) ) );
328 else if constexpr(
sizeof...( Cnds ) > 0 )
332 std::forward< Cnds >( cnds )... );
340 template<
typename ... Cnds >
344 std::forward< Cnds >( cnds )... );
350 auto combine = []<
typename T1,
typename T2 >( T1 && t1, T2 && t2 )
352 if constexpr( Condition< T2 > && Index< T1 > )
354 static_assert( T1::eswitch_index == T2::idx::eswitch_index,
"Wrong Index!" );
355 return std::forward< T2 >( t2 );
358 return std::forward< T1 >( t1 ) == std::forward< T2 >( t2 );
361 return ( combine(
Index_< Is >{}, std::get< Is >( std::move( values ) ) ) && ... );
369 template<
typename T >
372 template<
typename T >
375 template<
typename T >
377 !details::is_std_any_v< T > ||
378 !details::is_std_variant_v< T > ||
379 requires( T a, T b ) {
384 template<
typename T >
389 template<
typename T >
392 template<
typename T >
395 template<
typename T >
398 template<
typename T >
401 template<
typename T >
402 concept
StdPair = details::is_std_pair_v< T >;
420 for(
const auto & v : match )
431 template<
typename TupleEntry,
typename UnderlyingType >
437 const UnderlyingType, UnderlyingType >;
439 if constexpr( std::is_pointer_v< _T > )
441 auto * d =
dynamic_cast< type*
>( tuple_entry );
449 auto & d =
dynamic_cast< type&
>( tuple_entry );
461 template<
typename TupleEntry,
typename UnderlyingType >
462 inline static constexpr
auto operator==( TupleEntry && tuple_entry,
const is< UnderlyingType > & ) noexcept
463 requires details::is_std_any_v< TupleEntry >
465 if(
auto * val = std::any_cast< UnderlyingType >( &tuple_entry ) )
475 template<
typename TupleEntry,
typename UnderlyingType >
476 inline static constexpr
auto operator==( TupleEntry && tuple_entry,
const is< UnderlyingType > & ) noexcept
477 requires details::is_std_variant_v< TupleEntry >
479 if(
auto * val = std::get_if< UnderlyingType >( &tuple_entry ) )
491 template<
typename T,
typename U >
492 concept EqualityComparable =
501 template< Comparison_operators CmpOperator, Index TIndex,
typename CaseEntry >
504 template< Comparison_operators, Index,
typename >
513 template<
typename Arg >
515 : value_(
std::forward< Arg >( value ) )
519 template< StdTuple TSrcTuple >
520 inline constexpr
auto operator()(
const TSrcTuple & src_tuple )
const
522 static_assert( !is_out_of_range< std::tuple_size_v< TSrcTuple > >(),
523 "Case Index is OUT OF RANGE" );
525 return compare( std::get< TIndex::eswitch_index >( src_tuple ), value_ );
528 template< StdTuple TSrcTuple >
529 inline constexpr
bool operator()(
const TSrcTuple & src_tuple )
const
535 template< std::
size_t MaxIndex >
538 return TIndex::eswitch_index >= MaxIndex;
543 template<
typename TupleEntry >
544 inline static constexpr
auto compare( TupleEntry && t1,
const CaseEntry & t2 )
545 requires EqualityComparable< decltype( t1 ), decltype( t2 ) >
547 switch( CmpOperator )
551 if constexpr( requires{ t1 == t2; } )
return t1 == t2;
555 if constexpr( requires{ t1 != t2; } )
return t1 != t2;
559 if constexpr( requires{ t1 > t2; } )
return t1 > t2;
563 if constexpr( requires{ t1 >= t2; } )
return t1 >= t2;
567 if constexpr( requires{ t1 < t2; } )
return t1 < t2;
571 if constexpr( requires{ t1 <= t2; } )
return t1 <= t2;
576 template<
typename T1,
typename T2 >
577 inline static constexpr
bool compare( T1 && t1, T2 && t2 )
579 static_assert( EqualityComparable< T1, T2 >,
"Types are not COMPARABLE!" );
597 : cnds_(
std::tuple_cat(
std::move( cnds.cnds_ ),
std::make_tuple(
std::move( cnd ) ) ) )
602 : cnds_(
std::move( cnds )... )
606 template< std::
size_t MaxIndex >
609 return ( Cnds::template is_out_of_range< MaxIndex >() || ... );
612 template< StdTuple TSrcTuple >
613 inline constexpr
bool operator()(
const TSrcTuple & src_tuple )
const
617 return compare(
static_cast< bool >( std::get< ints >( cnds_ )( src_tuple ) )... );
625 inline static constexpr
bool compare(
const auto ... ts )
627 switch( LogicalOperator )
630 return ( ts && ... );
632 return ( ts || ... );
641 std::move( cnds ), std::move( cnd ) );
644 template< Condition Cnd1, Condition Cnd2 >
645 inline static constexpr
auto operator&&( Cnd1 && cnd1, Cnd2 && cnd2 )
654 std::move( cnds ), std::move( cnd ) );
657 template< Condition Cnd1, Condition Cnd2 >
658 inline static constexpr
auto operator||( Cnd1 && cnd1, Cnd2 && cnd2 )
663 template< Index Idx,
typename T >
669 template< Index Idx,
typename T >
675 template< Index Idx,
typename T >
681 template< Index Idx,
typename T >
687 template< Index Idx,
typename T >
693 template< Index Idx,
typename T >
703 template<
typename ... Args >
706 static_assert( ( ComparableExceptAnyAndVariant<Args> && ... ),
"Input Types should be COMPARABLE!" );
711 template<
typename ... Ts >
716 template<
typename T >
719 template<
typename T >
722 template<
typename T >
725 template<
typename ... Cnds >
731 "Predicate with 'auto' argument aren't ALLOWED!" );
736 "Inconsistent 'Return type'!" );
742 template<
typename ... Cnds >
743 inline constexpr
auto operator()( Cnds && ... cnds ) requires has_type< std::common_type< underlying_t< Cnds >... > >
745 constexpr
auto generic_lambda = []<
typename T, T... ints >
748 ( f( std::get< ints >( tup ) ), ... );
753 constexpr
auto has_return_value = !std::is_same_v< return_t, void >;
763 using namespace details;
765 if( fallthrough && !( *fallthrough ) )
return;
767 constexpr
auto amount_args =
amount_args_v< decltype( cnd.func ) >;
769 if constexpr( amount_args == 0 )
771 if( fallthrough && *fallthrough )
775 fallthrough = cnd.fallthrough;
781 auto res = cnd.cnd( tup_ );
785 if constexpr( amount_args == 1 && !
std::is_same_v< decltype( res ),
bool > )
787 if constexpr( has_return_value )
789 return_value =
static_cast< return_t
>( cnd.func( std::move( *res ) ) );
793 cnd.func( std::move( *res ) );
796 else if constexpr( amount_args == 0 )
798 if constexpr( has_return_value )
800 return_value =
static_cast< return_t
>( cnd.func() );
812 fallthrough = cnd.fallthrough;
815 if constexpr( has_return_value )
817 return return_value.
value();
826 template<
typename ... Ts >
837 template<
typename ... Ts >
838 inline static constexpr
auto eswitch( Ts && ... ts )
847 template< StdPair T >
848 inline static constexpr
auto eswitch( T && pair )
850 if constexpr( std::is_rvalue_reference_v< T&& > )
852 return eswitch_impl( std::move( pair.first ), std::move( pair.second ) );
860 template< StdTuple T >
861 inline static constexpr
auto eswitch( T && tup )
863 auto expand_tuple = [] <
typename _T, _T ... ints >
872 template< Condition Cnd, Callable Func >
879 bool fallthrough =
false;
886 template<
typename T,
typename F >
893 template< Condition T, Callable Func >
894 inline static constexpr
auto operator%( T && cnd, Func && f )
901 template<
typename Cnd, ReturnValueNoneVo
id Func >
904 cp.fallthrough =
true;
906 return std::move( cp );
910 class predicate_condition
916 template<
typename T >
918 : pred_(
std::forward< T >( pred ) )
922 template< StdTuple TSrcTuple >
923 constexpr
bool operator()(
const TSrcTuple & src_tuple )
const
925 static_assert( !is_out_of_range< std::tuple_size_v< TSrcTuple > >(),
926 "Case Index is OUT OF RANGE" );
928 return pred_( std::get< Is >( src_tuple )... );
931 template< std::
size_t MaxIndex >
934 constexpr
std::array< bool,
sizeof...( Is ) > list{ ( Is >= MaxIndex )... };
940 template<
typename R,
typename... Args,
Index Idx >
941 inline static constexpr
auto operator,( R(*pred)(Args...), Idx )
946 template< IsNotCndPredicate Pred, Index Idx >
947 inline static constexpr
auto operator,( Pred && pred, Idx )
950 std::forward< Pred >( pred ) );
954 predicate_condition< P, I..., Idx::eswitch_index >
957 template< IsCndPredicate Pred, Index Idx >
958 inline static constexpr
auto operator,( Pred && pred, Idx idx )
967 template< Condition Cnd >
968 inline static constexpr
auto case_( Cnd && cnd )
970 return std::move( cnd );
973 template<
typename ... Ts >
974 inline static constexpr
auto case_( Ts &&... values )
976 auto lmbd = []<
typename T, T ... ints >(
std::index_sequence< ints... >&&,
auto &&... values )
981 std::tuple< Ts... >( std::forward< Ts >( values )... ) );
985 std::forward< Ts >( values )... );
990 template<
typename ... Args >
991 inline static constexpr
auto any_from( Args &&... args )
998 template<
typename T >
1026 #define Case( ... ) case_( __VA_ARGS__ ) % [&]
1029 #define Default ( _1 == extension::any{} ) % [&]