3

With ranges merged into C++20 I was hoping we will get the equivalent of boost::irange in C++, but googling did not find anything...

I know about std::views::iota but that does not do the same thing, in particular single argument overload takes start, not end.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • Isn't it fairly easy to write a utility that accepts the upper bound and returns a `std::views::iota` properly initialized? – StoryTeller - Unslander Monica Sep 05 '19 at 09:11
  • for future readers: this is not a duplicate: I ask for a specific c++20 replacement for boost:irange, not for "neatest way to loop over a range of integers" – NoSenseEtAl Sep 06 '19 at 14:48
  • It is worth noting that the amount of code that the ranges library pulls in are quite substantial, and this is probably also the case for boost - so there's still something to be said for simpler, bespoke, `irange` implementations. – einpoklum Jun 01 '21 at 19:27

2 Answers2

2

Is there a boost::irange equivalent in C++20?

Not directly, but it's easy to provide your own equivalent utility function.

template<std::semiregular Bound>
auto irange(Bound b)
{
     return std::ranges::iota_view(0, b);
}
lubgr
  • 37,368
  • 3
  • 66
  • 117
2

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{};
Barry
  • 286,269
  • 29
  • 621
  • 977