That is, given a constexpr std::array<int,2>{1,2}
pass it to some function or helper class that would spit out the type std::integer_sequence<int, 1, 2>
?
It seems easy to jump from the type world to the "constexpr value" world (e.g., to do the reverse conversion), but hard or impossible to do the reverse.
It seems like you can do it in C++17, at the cost of introducing a lambda at the call site:
template <size_t N, typename F, size_t... indexes>
constexpr auto make_seq_helper(F f, std::index_sequence<indexes...> is) {
return std::integer_sequence<int, std::get<indexes>(f())...>{};
}
template <typename F>
constexpr auto make_seq(F f) {
constexpr size_t N = f().size();
using indexes = std::make_index_sequence<N>;
return make_seq_helper<N>(f, indexes{});
};
Calling make_seq
like this:
constexpr std::array a{7, 15, 28};
auto x = make_seq([](){ return a; });
Results in an x
with type std::integer_sequence<int, 7, 15, 28>
. I'm not sure if the lambda use can be removed.
If array have external linkage, you might do something like:
template <auto& Arr, size_t... Is>
constexpr auto make_seq_impl(std::index_sequence<Is...>) {
using T = typename std::decay_t<decltype(Arr)>::value_type;
return std::integer_sequence<T, Arr[Is]...>{};
}
template <auto& Arr>
constexpr auto make_seq() {
return make_seq_impl<Arr>(std::make_index_sequence<Arr.size()>());
}
constexpr std::array a{7, 15, 28};
int main()
{
[[maybe_unused]]auto x = make_seq<a>();
static_assert(std::is_same<std::integer_sequence<int, 7, 15, 28>, decltype(x)>::value, "!");
}
Demo
Or, with structure way, you might do:
template <const auto& Arr, typename Seq = std::make_index_sequence<std::size(Arr)>>
struct make_seq;
template <typename T, std::size_t N, const std::array<T, N>& Arr, std::size_t ... Is>
struct make_seq<Arr, std::index_sequence<Is...>>
{
using type = std::integer_sequence<T, Arr[Is]...>;
};
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With