Skip to content

Instantly share code, notes, and snippets.

@ericniebler
Last active May 4, 2016 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ericniebler/9241968 to your computer and use it in GitHub Desktop.
Save ericniebler/9241968 to your computer and use it in GitHub Desktop.
a counted range, and slide working with counted and non-counted iterators
#include <vector>
#include <utility>
#include <iostream>
#include <algorithm>
#include <range/v3/range.hpp>
using namespace ranges;
template<typename It>
class counted_range : public range_facade<counted_range<It>>
{
friend range_core_access;
It it_;
iterator_difference_t<It> n_;
auto current() const -> decltype(*it_)
{ return *it_; }
bool done() const
{ return 0 == n_; }
bool equal(counted_range<It> const &that) const
{ return n_ == that.n_; }
void next() { ++it_, --n_; }
CONCEPT_REQUIRES(BidirectionalIterator<It>())
void prev()
{ --it_, ++n_; }
CONCEPT_REQUIRES(RandomAccessIterator<It>())
void advance(iterator_difference_t<It> n)
{ it_ += n, n_ -= n; }
CONCEPT_REQUIRES(RandomAccessIterator<It>())
iterator_difference_t<It>
distance_to(counted_range<It> const &that) const
{ return n_ - that.n_; }
public:
counted_range(It it, iterator_difference_t<It> n)
: it_(it), n_(n)
{}
};
template<typename It>
counted_range<It> counted(It it, iterator_difference_t<It> n)
{
return {it, n};
}
struct my_vector
: range_adaptor<my_vector, std::vector<int>>
{
my_vector() = default;
my_vector(std::initializer_list<int> i)
: range_adaptor_t<my_vector>{i}
{}
};
template<typename I,
CONCEPT_REQUIRES_(RandomAccessIterator<I>())>
iterator_range<I> slide(I f, I l, I p)
{
if(p < f) return {p, std::rotate(p, f, l) };
if(l < p) return {std::rotate(f, l, p), p };
return { f, l };
}
int main()
{
// Make a vector
my_vector v {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
// This works:
slide(next(v.begin(), 5), next(v.begin(), 7), next(v.begin(), 17));
for_each(v, [](int i){std::cout << i << ' ';});
std::cout << std::endl;
// Make a counted range of the vector:
auto r = counted(begin(v), distance(v));
// This works, too
slide(next(r.begin(), 15), next(r.begin(), 17), next(r.begin(), 5));
for_each(r, [](int i){std::cout << i << ' ';});
std::cout << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment