I would like to create an std::index_sequence
which holds multiple of given number.
Let's say I want to hold values like 0, 3, 6, 9, ...
or 0, 2, 4, 6, 8, 10, ...
.
How to create such a custom sequence?
I want to use it by giving number of values to generate and step between consecutive values.
I'd use a "normal" index sequence and multiply it by M
as below:
template <std::size_t M, std::size_t N>
auto make_index_sequence_as_multiple_of() {
return []<std::size_t... I>(std::index_sequence<I...>) {
return std::index_sequence<(I * M)...>{};
}(std::make_index_sequence<N>{});
}
Example: You could create a sequence of 5 indices as multiples of 3 like so:
int main() {
auto is = make_index_sequence_as_multiple_of<3, 5>();
static_assert(
std::is_same_v<std::index_sequence<0, 3, 6, 9, 12>, decltype(is)>);
}
Pre C++20 version:
namespace detail {
template<std::size_t M, std::size_t... I>
auto helper(std::index_sequence<I...>) {
return std::index_sequence<(I * M)...>{};
}
} // namespace detail
template <std::size_t M, std::size_t N>
auto make_index_sequence_as_multiple_of() {
return detail::helper<M>(std::make_index_sequence<N>{});
}
If you want the type instead of an object, you could just hide the creation and use decltype
to figure out the type. Here's pre C++20 version of that:
namespace detail {
template <std::size_t M, std::size_t... I>
auto helper(std::index_sequence<I...>) {
return std::index_sequence<(I * M)...>{};
}
} // namespace detail
template <std::size_t M, std::size_t N>
using make_index_sequence_as_multiple_of =
decltype(detail::helper<M>(std::make_index_sequence<N>{}));