The single-argument irange
can be easily implemented with views::iota
:
template <std::integral I>
auto irange(I end) {
return std::views::iota(I{0}, end);
}
Note that irange
is only for integers, and iota
requires its arguments to have the same signed-ness - so we use I{0}
instead of simply 0
to handle unsigned types.
But in order to do the full complete of irange
, we need another range adapter that isn't in C++20: views::stride
. You can get that one from range-v3. And then write these as an object for further convenience:
struct irange_t {
template <std::integral I>
constexpr auto operator()(I end) const {
return std::views::iota(I{0}, end);
}
template <std::integral I>
constexpr auto operator()(I begin, I end) const {
return std::views::iota(begin, end);
}
template <std::integral I, std::integral S>
constexpr auto operator()(I begin, I end, S step) const {
return std::views::iota(begin, end) | ranges::views::stride(step);
}
};
inline constexpr irange_t irange{};