Skip to content

Instantly share code, notes, and snippets.

@gofer
Last active May 6, 2019 08:44
Show Gist options
  • Save gofer/55fc3d0db49e59cf8f9ce2e9e68028a1 to your computer and use it in GitHub Desktop.
Save gofer/55fc3d0db49e59cf8f9ce2e9e68028a1 to your computer and use it in GitHub Desktop.
Range Iterator
#ifndef __RANGE_H__
#define __RANGE_H__
#include <cassert>
class NumberIterator : public std::iterator<std::bidirectional_iterator_tag, int64_t, std::ptrdiff_t, int64_t*, int64_t&>
{
private:
int64_t n, d;
public:
#if __cplusplus >= 201103L
using iterator_category = std::bidirectional_iterator_tag;
using value_type = int64_t;
using difference_type = std::ptrdiff_t;
using pointer = int64_t*;
using reference = int64_t&;
#else
typedef std::bidirectional_iterator_tag iterator_category;
typedef int64_t value_type;
typedef std::ptrdiff_t difference_type;
typedef int64_t* pointer;
typedef int64_t& reference;
#endif /* __cplusplus >= 201103L */
NumberIterator(int64_t n, int64_t d = +1) : n(n), d(d) { assert(d != 0); }
int64_t operator*() const { return n; }
NumberIterator& operator++() { d > 0 ? ++n : --n; return *this; }
NumberIterator operator++(int) { d > 0 ? ++n : --n; return NumberIterator(d > 0 ? n - 1 : n + 1, d); }
NumberIterator& operator--() { d > 0 ? --n : ++n; return *this; }
NumberIterator operator--(int) { d > 0 ? --n : ++n; return NumberIterator(d > 0 ? n + 1 : n - 1, d); }
bool operator==(const NumberIterator &itr) const { return n == *itr; }
bool operator!=(const NumberIterator &itr) const { return n != *itr; }
bool operator< (const NumberIterator &itr) const { return d > 0 ? n < *itr : n > *itr; }
bool operator<=(const NumberIterator &itr) const { return d > 0 ? n <= *itr : n >= *itr; }
bool operator> (const NumberIterator &itr) const { return d > 0 ? n > *itr : n < *itr; }
bool operator>=(const NumberIterator &itr) const { return d > 0 ? n >= *itr : n <= *itr; }
};
class Range
{
private:
int64_t src, dst;
public:
Range(int64_t src, int64_t dst) : src(src), dst(dst) {}
NumberIterator begin() const { return NumberIterator(src, src < dst ? +1 : -1); }
NumberIterator end() const { return NumberIterator(dst, src < dst ? +1 : -1); }
NumberIterator rbegin() const { return NumberIterator(dst, src < dst ? -1 : +1); }
NumberIterator rend() const { return NumberIterator(src, src < dst ? -1 : +1); }
};
namespace std {
template<> struct hash<Range> {
size_t operator()(const Range &key) const {
return (*key.begin() & 0x5555555555555555L) | (*key.end() & 0xAAAAAAAAAAAAAAAAL);
}
};
};
#endif /* __RANGE_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment