Skip to content
Snippets Groups Projects
Commit e1800140 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

add and use constexpr_switch

parent ee50d56f
No related branches found
No related tags found
No related merge requests found
...@@ -35,22 +35,17 @@ constexpr decltype ( auto ) apply ( F && f, Tuple && t ) { ...@@ -35,22 +35,17 @@ constexpr decltype ( auto ) apply ( F && f, Tuple && t ) {
} }
   
template < class ... Params > template < class ... Params >
struct CheckInput; struct CheckInput {
static bool checkInput ( const std::shared_ptr < OperationAbstraction > & operation, unsigned index ) {
bool res = false;
   
template < > auto lambda = [ & ] ( auto I ) {
struct CheckInput < > { res = ( bool ) std::dynamic_pointer_cast < std::decay_t < std::tuple_element_t < decltype ( I )::value, std::tuple < Params ... > > > > ( operation->getProxyAbstraction ( ) );
static bool checkInput ( const std::shared_ptr < OperationAbstraction > &, unsigned ) { };
throw std::logic_error ( "Out of types to check" );
}
};
   
template < class Param, class ... Params > ext::constexpr_switch < sizeof ... ( Params ) > ( index, lambda );
struct CheckInput < Param, Params ... > {
static bool checkInput ( const std::shared_ptr < OperationAbstraction > & operation, unsigned index ) { return res;
if ( index == 0 )
return ( bool ) std::dynamic_pointer_cast < typename std::decay < Param >::type > ( operation->getProxyAbstraction ( ) );
else
return CheckInput < Params ... >::checkInput ( operation, index - 1 );
} }
}; };
   
......
...@@ -51,6 +51,22 @@ inline auto move_copy ( const T & param ) { ...@@ -51,6 +51,22 @@ inline auto move_copy ( const T & param ) {
} }
} }
   
namespace detail {
template < class F, std::size_t ... Is >
void constexpr_switch ( const std::size_t i, F && f, std::index_sequence < Is ... > ) {
[ ] ( ... ) { } (
( i == Is && ( ( void ) std::forward < F > ( f ) . operator ( ) ( std::integral_constant < size_t, Is > ( ) ), false ) ) ...
);
}
} // namespace detail
template < std::size_t N, class F >
void constexpr_switch ( const std::size_t i, F && f ) {
detail::constexpr_switch ( i, std::forward < F > ( f ), std::make_index_sequence < N > { } );
}
} /* namespace ext */ } /* namespace ext */
   
#endif /* __UTILITY_HPP_ */ #endif /* __UTILITY_HPP_ */
...@@ -16,4 +16,41 @@ TEST_CASE ( "Utility", "[unit][std][bits]" ) { ...@@ -16,4 +16,41 @@ TEST_CASE ( "Utility", "[unit][std][bits]" ) {
ext::ptr_value < Foo > val ( Foo { } ); ext::ptr_value < Foo > val ( Foo { } );
CHECK ( val->bar ( ) == 1 ); CHECK ( val->bar ( ) == 1 );
} }
SECTION ( "Constexp switch" ) {
{
auto const t = std::make_tuple(42, 'z', 3.14, 13, 0, "Hello, World!");
auto lambda = [ & ] ( auto I ) {
if constexpr ( I == 0 )
CHECK ( std::get < decltype ( I )::value > ( t ) == 42 );
else if constexpr ( I == 1 )
CHECK ( std::get < decltype ( I )::value > ( t ) == 'z' );
else if constexpr ( I == 2 )
CHECK ( std::get < decltype ( I )::value > ( t ) == 3.14 );
else if constexpr ( I == 3 )
CHECK ( std::get < decltype ( I )::value > ( t ) == 13 );
else if constexpr ( I == 4 )
CHECK ( std::get < decltype ( I )::value > ( t ) == 0 );
else // constexpr ( I == 5 )
CHECK ( std::get < decltype ( I )::value > ( t ) == std::string ( "Hello, World!" ) );
};
for (std::size_t i = 0; i < std::tuple_size<decltype(t)>::value; ++i) {
ext::constexpr_switch < std::tuple_size<decltype(t)>::value > ( i, lambda );
}
}
{
auto const t = std::array<int, 4>{{0,1,2,3}};
auto lambda = [ & ] ( auto I ) {
CHECK ( std::get < decltype ( I )::value > ( t ) == I );
};
for (std::size_t i = 0; i < t.size(); ++i) {
ext::constexpr_switch < std::tuple_size<decltype(t)>::value > ( i, lambda );
}
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment