Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic constexpr type-selector

Sorry for the pompous name, I would like to create a constexpr function, which accepts a variable number of boolean template arguments, and returns the "template index" of the first true value, in C++11 (C++14 only solutions welcome but won't be accepted as the answer).

For example, calling this function Selector

Selector< false, false >() == 0 // none of the template argument is true
Selector< true, false, true >() == 1 // first true template argument is the first one
Selector< false, false, true, false >() == 3 // .. and here it's the third one

A typical use of this, and the reason why I call it a "type-selector", would be

Selector< std::is_pointer<T>::value, std::is_arithmetic<T>::value >()

and the reason why I'd like it to be a constexpr is for use in partial template specialisation.

I'm not exactly sure how to go about this, although I think that using variadic templates, constexpr template specialisation (for the 0 case), and recursion (is it possible to "consume" template arguments, like shift in bash?), this should be doable.

like image 395
Jonathan H Avatar asked Jan 08 '23 11:01

Jonathan H


1 Answers

#include <cstddef>
#include <type_traits>

template <std::size_t I, bool... Bs>
struct selector;

template <std::size_t I, bool... Bs>
struct selector<I, true, Bs...> : std::integral_constant<std::size_t, I> {};

template <std::size_t I, bool... Bs>
struct selector<I, false, Bs...> : selector<I+1, Bs...> {};

template <std::size_t I>
struct selector<I> : std::integral_constant<std::size_t, 0> {};

template <bool... Bs>
constexpr std::size_t Selector()
{
    return selector<1, Bs...>::value;
}

DEMO

like image 100
Piotr Skotnicki Avatar answered Jan 10 '23 01:01

Piotr Skotnicki