Guest User

Untitled

a guest
Apr 24th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.71 KB | None | 0 0
  1. #ifndef ALGORITHMS_ITERATOR_H
  2. #define ALGORITHMS_ITERATOR_H
  3.  
  4. #include <iterator>
  5. #include <iostream>
  6.  
  7. /// brief Random access const_iterator over a container with index operation
  8. /// note no copy assignment / move assignment.
  9. template<typename A>
  10. class const_index_iterator {
  11. typedef const_index_iterator<A> self_type;
  12. public:
  13. typedef typename A::value_type value_type;
  14. typedef value_type& reference;
  15. typedef value_type* pointer;
  16. typedef typename A::difference_type difference_type;
  17. typedef std::random_access_iterator_tag iterator_category;
  18.  
  19. const_index_iterator(const A& a, const typename A::size_type ix)
  20. : a_(a), ix_(ix) {
  21. // + 1 because of end().
  22. assert(ix_ < a_.size() + 1 && ix_ >= 0 && "Index is out of bounds.");
  23. }
  24.  
  25. // Arithmetic
  26. self_type operator++() {
  27. ++ix_;
  28. check_ix();
  29. return *this;
  30. }
  31.  
  32. self_type operator++(int dummy) { return operator++(); }
  33.  
  34. self_type& operator+=(difference_type n) {
  35. ix_ += n;
  36. check_ix();
  37. return *this;
  38. }
  39.  
  40. self_type operator--() {
  41. --ix_;
  42. check_ix();
  43. return *this;
  44. }
  45.  
  46. self_type operator--(int dummy) { return operator--(); }
  47.  
  48. self_type& operator-=(difference_type n) {
  49. return operator+=(-n);
  50. }
  51.  
  52. friend const_index_iterator<A> operator+(const const_index_iterator<A>& a,
  53. const difference_type n) {
  54. return const_index_iterator<A>(a.a_, a.ix_ + n);
  55. }
  56.  
  57. friend difference_type operator-(const const_index_iterator<A>& a,
  58. const const_index_iterator<A>& b) {
  59. return a.ix_ - b.ix_;
  60. }
  61.  
  62. // Dereference
  63. const value_type& operator[](const difference_type ix) const {
  64. check_dereference(ix);
  65. return a_[ix];
  66. }
  67.  
  68. const value_type& operator*() const {
  69. check_dereference();
  70. return a_[ix_];
  71. }
  72.  
  73. const value_type* operator->() const {
  74. check_dereference();
  75. assert(ix_ < a_.size());
  76. return &(a_[ix_]);
  77. }
  78.  
  79. // Logical
  80. bool operator==(const self_type& rhs) const { return ix_ == rhs.ix_; }
  81.  
  82. bool operator!=(const self_type& rhs) const { return !operator==(rhs); }
  83.  
  84. bool operator>(const self_type& rhs) const { return ix_ > rhs.ix_; }
  85.  
  86. bool operator<=(const self_type& rhs) const { return !operator>(rhs); }
  87.  
  88. bool operator<(const self_type& rhs) const { return ix_ < rhs.ix_; }
  89.  
  90. bool operator>=(const self_type& rhs) const { return !operator<(rhs); }
  91.  
  92. protected:
  93. void check_ix() const { check_ix(ix_); }
  94.  
  95. void check_ix(const difference_type ix) const {
  96. assert(ix < a_.size() + 1 && ix >= 0 && "Index is out of bounds.");
  97. }
  98.  
  99. void check_dereference() const { check_dereference(ix_); }
  100.  
  101. void check_dereference(const difference_type ix) const {
  102. assert(ix < a_.size() && ix >= 0
  103. && "The iterator cannot be dereferenced because it is out of "
  104. "bounds");
  105. }
  106.  
  107. const A& a_;
  108. typename A::size_type ix_;
  109. };
  110.  
  111.  
  112. template<typename A>
  113. const_index_iterator<A> operator+(const typename
  114. const_index_iterator<A>::difference_type n,
  115. const const_index_iterator<A>& a) {
  116. return operator+(a, n);
  117. }
  118.  
  119. template<typename A>
  120. const_index_iterator<A> operator-(const const_index_iterator<A>& a,
  121. const typename
  122. const_index_iterator<A>::difference_type n) {
  123. return operator+(a, -n);
  124. }
  125.  
  126. /// brief Random access const_iterator over a container with index operation
  127. /// note no copy assignment / move assignment.
  128. template<typename A>
  129. class index_iterator : public const_index_iterator<A> {
  130. typedef const_index_iterator<A> Base;
  131. typedef index_iterator<A> self_type;
  132. public:
  133. typedef typename A::value_type value_type;
  134. typedef value_type& reference;
  135. typedef value_type* pointer;
  136. typedef typename A::difference_type difference_type;
  137. typedef std::random_access_iterator_tag iterator_category;
  138.  
  139. index_iterator(A& a, const typename A::size_type ix)
  140. : Base::const_index_iterator(a, ix) {}
  141.  
  142. // Arithmetic
  143. friend index_iterator<A> operator+(const index_iterator<A>& a,
  144. const difference_type n) {
  145. return index_iterator<A>(a.mutable_a(), a.ix_ + n);
  146. }
  147.  
  148. friend difference_type operator-(const index_iterator<A>& a,
  149. const index_iterator<A>& b) {
  150. return a.ix_ - b.ix_;
  151. }
  152.  
  153. // Dereference
  154. using Base::operator*;
  155. using Base::operator->;
  156.  
  157. value_type& operator[](const difference_type ix) const {
  158. check_dereference(ix);
  159. return mutable_a()[ix];
  160. }
  161.  
  162. value_type& operator*() const {
  163. check_dereference();
  164. return mutable_a()[ix_];
  165. }
  166.  
  167. value_type* operator->() const {
  168. check_dereference();
  169. return &(mutable_a()[ix_]);
  170. }
  171.  
  172. private:
  173. A& mutable_a() const { return const_cast<A&>(a_); }
  174. using Base::a_;
  175. using Base::ix_;
  176. using Base::check_dereference;
  177.  
  178. };
  179.  
  180. template<typename A>
  181. index_iterator<A> operator+(const typename
  182. index_iterator<A>::difference_type n,
  183. const index_iterator<A>& a) {
  184. return operator+(a, n);
  185. }
  186.  
  187. template<typename A>
  188. index_iterator<A> operator-(const index_iterator<A>& a,
  189. const typename
  190. index_iterator<A>::difference_type n) {
  191. return operator+(a, -n);
  192. }
  193.  
  194. template<typename A>
  195. typename A::difference_type distance(const const_index_iterator<A>& a,
  196. const const_index_iterator<A>& b) {
  197. return a - b;
  198. }
  199.  
  200. #endif //ALGORITHMS_ITERATOR_H
Add Comment
Please, Sign In to add comment