Skip to content

Instantly share code, notes, and snippets.

@tunabrain
Last active August 1, 2019 08:30
Show Gist options
  • Save tunabrain/59cfec16689c8fd94249099bcc99750e to your computer and use it in GitHub Desktop.
Save tunabrain/59cfec16689c8fd94249099bcc99750e to your computer and use it in GitHub Desktop.
Python ranges in C++
#ifndef RANGE_HPP_
#define RANGE_HPP_
template<typename T> class RangeIterator;
template<typename T>
class Range
{
T _start, _end, _step;
public:
Range(T start, T end, T step = T(1))
: _start(start), _end(end), _step(step)
{
}
RangeIterator<T> begin() const;
RangeIterator<T> end() const;
};
template<typename T>
Range<T> range(T end)
{
return Range<T>(T(0), end, T(1));
}
template<typename T>
Range<T> range(T start, T end, T step = T(1))
{
return Range<T>(start, end, step);
}
template<typename T>
class RangeIterator
{
T _pos, _step;
public:
RangeIterator(T pos, T step) : _pos(pos), _step(step) {}
bool operator!=(const RangeIterator &o) const { return _pos < o._pos; }
RangeIterator &operator++() { _pos += _step; return *this; }
RangeIterator operator++(int) { RangeIterator copy(*this); operator++(); return copy; }
T operator*() const { return _pos; }
};
template<typename T>
RangeIterator<T> Range<T>::begin() const { return RangeIterator<T>(_start, _step); }
template<typename T>
RangeIterator<T> Range<T>::end() const { return RangeIterator<T>(_end, _step); }
#endif /* RANGE_HPP_ */
@robpieke
Copy link

robpieke commented Sep 1, 2017

Alternative approach to RangeIterator::operator!= which supports negative step sizes (or at least seems to ... don't bank your production on this just yet):
bool operator!=(const RangeIterator &o) const { return (o._pos - _pos) * _step > T(0); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment