Let's say we have the following type
template <bool... Values>
struct foo{};
I want to create a variadic template from a constexpr
array bool tab[N]
. In other words, I want to do something like:
constexpr bool tab[3] = {true,false,true};
using ty1 = foo<tab[0], tab[1], tab[2]>;
But I want to do it programmatically. For now, I've tried the following:
template <std::size_t N, std::size_t... I>
auto
mk_foo_ty(const bool (&tab)[N], std::index_sequence<I...>)
{
// error: template argument for template type parameter must be a type
return foo<tab[I]...>{};
}
// error (see mk_foo_ty)
using ty2 = decltype(mk_ty(tab, std::make_index_sequence<3>{}));
// error: expected '(' for function-style cast or type construction
using ty3 = foo<(tab[std::make_index_sequence<3>])...>;
I'm not even sure if it's possible. Maybe resorting to something like Boost.Preprocessor, but I don't like the idea. So, does anyone have an idea? Thanks!
EDIT
I have on one side a framework of constexpr
square matrices of booleans which can be created at compile-time using xor, negation, etc.
On the other side, I have a framework of templates which statically creates operations using informations encoded in variadic templates using boolean as parameters.
My goal is to bridge the gap between these two frameworks. Thus, I can't go with hardcoded solutions.
EDIT 2
I've found this question with the same problem and a nice answer, which is very close to the T.C.'s one (using a pointer). The extern
linkage is also very important.
However, I realize I forgot a key element. My bool
array is contained in a matrix
structure to be able to overload operators ^, |, etc.:
template <std::size_t N>
struct matrix
{
const bool data_[N*N];
template<typename... Values>
constexpr matrix(Values... values) noexcept
: data_{static_cast<bool>(values)...}
{}
constexpr bool operator [](std::size_t index) const noexcept
{
return data_[index];
}
}
Thus, if we apply T.C's solution:
template<std::size_t N, const bool (&Tab)[N], class>
struct ty1_helper;
template<std::size_t N, const bool (&Tab)[N], std::size_t... Is>
struct ty1_helper<N, Tab, std::index_sequence<Is...>>
{
using type = foo<Tab[Is]...>;
};
template<std::size_t N, const bool (&Tab)[N]>
using ty1 = typename ty1_helper<N, Tab, std::make_index_sequence<N>>::type;
Compilers complain about passing a non-type parameter :
// error: non-type template argument does not refer to any declaration
// using t = make_output_template<m.data_, std::make_index_sequence<3>>;
// ^~~~~~~
using t = ty1<3, m.data_>;