Last active
May 6, 2019 08:44
-
-
Save gofer/55fc3d0db49e59cf8f9ce2e9e68028a1 to your computer and use it in GitHub Desktop.
Range Iterator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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