Jarod42's lookup-table solution is probably the fastest and easiest but, just for completeness sake, a more or less verbatim replacement of the original code might be
template< std::size_t I, std::size_t... Is >
void call_foo( bool switch1, bool switch2, bool switch3, std::index_sequence<I,Is...> )
{
if( switch1 == bool(I&1) && switch2 == bool(I&2) && switch3 == bool(I&4) )
foo<bool(I&1),bool(I&2),bool(I&4)>();
if constexpr( sizeof...(Is) > 0 )
call_foo( switch1, switch2, switch3, std::index_sequence<Is...>{} );
}
// to be used as
call_foo( true, false, true, std::make_index_sequence<2*2*2>{} );
with an extra index_sequence, this can be also generalized to arbitrary bools count.
A fully generic c++17 version taking a functor may look like:
template< class F, class... T, std::size_t... Js, std::size_t I, std::size_t... Is >
void untemplatize_impl( F&& f, std::index_sequence<Js...> bits, std::index_sequence<I,Is...>, T... bools )
{
if( I == ( ( unsigned(bools)<<Js ) | ... ) )
std::forward<F>(f).template operator()<bool(I&(1<<Js))...>();
if constexpr( sizeof...(Is) > 0 )
untemplatize_impl( std::forward<F>(f), bits, std::index_sequence<Is...>{}, bools... );
}
template< class F, class... T > // SFINAEd, if needed
void untemplatize( F&& f, T... bools )
{
untemplatize_impl( std::forward<F>(f), std::make_index_sequence<sizeof...(T)>{}, std::make_index_sequence<(1u<<sizeof...(T))>{}, bools... );
}
// to be used as
untemplatize( foo{}, false, true, true );
the same thing being possible in c++11 as well, but much more messy.