Advertisement
Guest User

Untitled

a guest
Dec 14th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.20 KB | None | 0 0
  1. #ifndef RANGE_HPP
  2. #define RANGE_HPP
  3.  
  4. #include <cstddef>
  5. #include <iterator>
  6.  
  7. /**
  8.  * Class should behave the same way as range in python.
  9.  * @tparam T For simplicity T will be numeric type.
  10.  */
  11.  
  12. template<typename T>
  13. class Range {
  14.  
  15.     struct Iterator {
  16.         using value_type = T;
  17.         using iterator_category = std::forward_iterator_tag;
  18.         using difference_type = ptrdiff_t;
  19.         using pointer = const T *;
  20.         using reference = const T &;
  21.  
  22.         Iterator(T from, T to, T step) : to_(to), step_(step), current_(from) {};
  23.  
  24.         Iterator() : Iterator(0, 0, 0) {};
  25.  
  26.         T &operator*() {
  27.             return current_;
  28.         }
  29.  
  30.         T *operator->() {
  31.             return &current_;
  32.         }
  33.  
  34.         bool operator==(Iterator const &that) const {
  35.             return (that.current_ == current_ && that.step_ == step_ && to_ == that.to_) ||
  36.                    (!canDereference() && !that.canDereference());
  37.         }
  38.  
  39.         bool operator!=(Iterator const &that) const {
  40.             return !(that == *this);
  41.         }
  42.  
  43.         Iterator &operator++() {
  44.             current_ += step_;
  45.             return *this;
  46.         }
  47.  
  48.         Iterator operator++(int) {
  49.             Iterator copy = *this;
  50.             current_ += step_;
  51.             return copy;
  52.         }
  53.  
  54.     private:
  55.         friend Range;
  56.         T to_;
  57.         T step_;
  58.         T current_;
  59.  
  60.         bool canDereference() const {
  61.             return current_ * sgn(step_) < to_ * sgn(step_);
  62.         }
  63.  
  64.         T sgn(T val) const {
  65.             return (T(0) < val) - (val < T(0));
  66.         }
  67.     };
  68.  
  69. public:
  70.     using iterator = Iterator;
  71.     using const_iterator = Iterator;
  72.  
  73.     Range(T from, T to, T step) : from_(from), to_(to), step_(step) {};
  74.  
  75.     iterator begin() const { return Iterator(from_, to_, step_); }
  76.  
  77.     iterator end() const { return Iterator(0, 0, 0); }
  78.  
  79. private:
  80.     T from_, to_, step_;
  81. };
  82.  
  83. template<typename T>
  84. auto range(T from, T to, T step) {
  85.     return Range<T>(from, to, step);
  86. }
  87.  
  88. template<typename T>
  89. auto range(T from, T to) {
  90.     return Range<T>(from, to, 1);
  91. }
  92.  
  93. template<typename T>
  94. auto range(T to) {
  95.     return Range<T>(0, to, 1);
  96. }
  97.  
  98. #endif // RANGE_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement