Skip to content

Instantly share code, notes, and snippets.

@CaseyCarter
Created January 17, 2016 18:57
Show Gist options
  • Save CaseyCarter/a3a39ebc4d4f6fe3c907 to your computer and use it in GitHub Desktop.
Save CaseyCarter/a3a39ebc4d4f6fe3c907 to your computer and use it in GitHub Desktop.
#include <experimental/ranges/concepts>
#include <experimental/ranges/functional>
#include <experimental/ranges/iterator>
namespace ranges = std::experimental::ranges;
ranges::Integral{I}
class integer_range {
I lo_ = 0;
I hi_ = 0;
struct cursor {
using difference_type = std::make_signed_t<I>;
I i_ = 0;
cursor() = default;
explicit cursor(I i) : i_{i} {}
I read() const { return i_; }
void next() { ++i_; }
void prev() { --i_; }
void advance(difference_type n) { i_ += n; }
difference_type distance_to(const cursor& that) const
{ return that.i_ - i_; }
bool equal(const cursor& that) const
{ return that.i_ == i_; }
};
public:
integer_range() = default;
integer_range(I lo, I hi) : lo_{lo}, hi_{hi >= lo ? hi : lo} {}
using iterator = ranges::basic_iterator<cursor>;
iterator begin() const { return cursor{lo_}; }
iterator end() const { return cursor{hi_}; }
};
template <ranges::Integral I>
integer_range<I> irange(I hi) {
return {I{0}, hi};
}
template <ranges::Integral I1, ranges::Integral I2>
integer_range<ranges::common_type_t<I1, I2>> irange(I1 lo, I2 hi) {
return {lo, hi};
}
static_assert(ranges::View<integer_range<int>>());
static_assert(ranges::RandomAccessRange<integer_range<int>>());
static_assert(sizeof(integer_range<int>::iterator) == sizeof(int));
int sum_for_loop(int lo, int hi) {
int total = 0;
for (auto i = lo; i < hi; ++i) {
total += i;
}
return total;
}
int sum_range(int lo, int hi) {
int total = 0;
for (auto i : irange(lo, hi)) {
total += i;
}
return total;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment