iterator_test.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. Copyright (c) Marshall Clow 2013.
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. For more information, see http://www.boost.org
  6. */
  7. #ifndef ITERATOR_TEST_H
  8. #define ITERATOR_TEST_H
  9. /*
  10. A set of iterator adapters for constructing test cases
  11. From an iterator (or a pointer), you can make any class of iterator.
  12. Assuming you want to degrade the capabilities.
  13. Modeled closely on work that Howard Hinnant did for libc++.
  14. */
  15. #include <iterator>
  16. // == Input Iterator ==
  17. template <typename It>
  18. class input_iterator {
  19. public:
  20. typedef std::input_iterator_tag iterator_category;
  21. typedef typename std::iterator_traits<It>::value_type value_type;
  22. typedef typename std::iterator_traits<It>::difference_type difference_type;
  23. typedef It pointer;
  24. typedef typename std::iterator_traits<It>::reference reference;
  25. BOOST_CXX14_CONSTEXPR It base() const {return it_;}
  26. BOOST_CXX14_CONSTEXPR input_iterator() : it_() {}
  27. BOOST_CXX14_CONSTEXPR explicit input_iterator(It it) : it_(it) {}
  28. template <typename U>
  29. BOOST_CXX14_CONSTEXPR input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
  30. BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
  31. BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
  32. BOOST_CXX14_CONSTEXPR input_iterator& operator++() {++it_; return *this;}
  33. BOOST_CXX14_CONSTEXPR input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;}
  34. BOOST_CXX14_CONSTEXPR friend bool operator==(const input_iterator& x, const input_iterator& y)
  35. {return x.it_ == y.it_;}
  36. BOOST_CXX14_CONSTEXPR friend bool operator!=(const input_iterator& x, const input_iterator& y)
  37. {return !(x == y);}
  38. private:
  39. It it_;
  40. template <typename U> friend class input_iterator;
  41. };
  42. template <typename T, typename U>
  43. BOOST_CXX14_CONSTEXPR inline bool
  44. operator==(const input_iterator<T>& x, const input_iterator<U>& y)
  45. {
  46. return x.base() == y.base();
  47. }
  48. template <typename T, typename U>
  49. BOOST_CXX14_CONSTEXPR inline bool
  50. operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
  51. {
  52. return !(x == y);
  53. }
  54. // == Forward Iterator ==
  55. template <typename It>
  56. class forward_iterator {
  57. public:
  58. typedef std::forward_iterator_tag iterator_category;
  59. typedef typename std::iterator_traits<It>::value_type value_type;
  60. typedef typename std::iterator_traits<It>::difference_type difference_type;
  61. typedef It pointer;
  62. typedef typename std::iterator_traits<It>::reference reference;
  63. BOOST_CXX14_CONSTEXPR It base() const {return it_;}
  64. BOOST_CXX14_CONSTEXPR forward_iterator() : it_() {}
  65. BOOST_CXX14_CONSTEXPR explicit forward_iterator(It it) : it_(it) {}
  66. template <typename U>
  67. BOOST_CXX14_CONSTEXPR forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
  68. BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
  69. BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
  70. BOOST_CXX14_CONSTEXPR forward_iterator& operator++() {++it_; return *this;}
  71. BOOST_CXX14_CONSTEXPR forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;}
  72. BOOST_CXX14_CONSTEXPR friend bool operator==(const forward_iterator& x, const forward_iterator& y)
  73. {return x.it_ == y.it_;}
  74. BOOST_CXX14_CONSTEXPR friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
  75. {return !(x == y);}
  76. private:
  77. It it_;
  78. template <typename U> friend class forward_iterator;
  79. };
  80. template <typename T, typename U>
  81. BOOST_CXX14_CONSTEXPR inline bool
  82. operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
  83. {
  84. return x.base() == y.base();
  85. }
  86. template <typename T, typename U>
  87. BOOST_CXX14_CONSTEXPR inline bool
  88. operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
  89. {
  90. return !(x == y);
  91. }
  92. // == Bidirectional Iterator ==
  93. template <typename It>
  94. class bidirectional_iterator
  95. {
  96. public:
  97. typedef std::bidirectional_iterator_tag iterator_category;
  98. typedef typename std::iterator_traits<It>::value_type value_type;
  99. typedef typename std::iterator_traits<It>::difference_type difference_type;
  100. typedef It pointer;
  101. typedef typename std::iterator_traits<It>::reference reference;
  102. BOOST_CXX14_CONSTEXPR It base() const {return it_;}
  103. BOOST_CXX14_CONSTEXPR bidirectional_iterator() : it_() {}
  104. BOOST_CXX14_CONSTEXPR explicit bidirectional_iterator(It it) : it_(it) {}
  105. template <typename U>
  106. BOOST_CXX14_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
  107. BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
  108. BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
  109. BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator++() {++it_; return *this;}
  110. BOOST_CXX14_CONSTEXPR bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
  111. BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator--() {--it_; return *this;}
  112. BOOST_CXX14_CONSTEXPR bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;}
  113. private:
  114. It it_;
  115. template <typename U> friend class bidirectional_iterator;
  116. };
  117. template <typename T, typename U>
  118. BOOST_CXX14_CONSTEXPR inline bool
  119. operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
  120. {
  121. return x.base() == y.base();
  122. }
  123. template <typename T, typename U>
  124. BOOST_CXX14_CONSTEXPR inline bool
  125. operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
  126. {
  127. return !(x == y);
  128. }
  129. // == Random Access Iterator ==
  130. template <typename It>
  131. class random_access_iterator {
  132. public:
  133. typedef std::random_access_iterator_tag iterator_category;
  134. typedef typename std::iterator_traits<It>::value_type value_type;
  135. typedef typename std::iterator_traits<It>::difference_type difference_type;
  136. typedef It pointer;
  137. typedef typename std::iterator_traits<It>::reference reference;
  138. BOOST_CXX14_CONSTEXPR It base() const {return it_;}
  139. BOOST_CXX14_CONSTEXPR random_access_iterator() : it_() {}
  140. BOOST_CXX14_CONSTEXPR explicit random_access_iterator(It it) : it_(it) {}
  141. template <typename U>
  142. BOOST_CXX14_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
  143. BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
  144. BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
  145. BOOST_CXX14_CONSTEXPR random_access_iterator& operator++() {++it_; return *this;}
  146. BOOST_CXX14_CONSTEXPR random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;}
  147. BOOST_CXX14_CONSTEXPR random_access_iterator& operator--() {--it_; return *this;}
  148. BOOST_CXX14_CONSTEXPR random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;}
  149. BOOST_CXX14_CONSTEXPR random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
  150. BOOST_CXX14_CONSTEXPR random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;}
  151. BOOST_CXX14_CONSTEXPR friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;}
  152. BOOST_CXX14_CONSTEXPR random_access_iterator& operator-=(difference_type n) {return *this += -n;}
  153. BOOST_CXX14_CONSTEXPR random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;}
  154. BOOST_CXX14_CONSTEXPR reference operator[](difference_type n) const {return it_[n];}
  155. private:
  156. It it_;
  157. template <typename U> friend class random_access_iterator;
  158. };
  159. template <typename T, typename U>
  160. BOOST_CXX14_CONSTEXPR inline bool
  161. operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  162. {
  163. return x.base() == y.base();
  164. }
  165. template <typename T, typename U>
  166. BOOST_CXX14_CONSTEXPR inline bool
  167. operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  168. {
  169. return !(x == y);
  170. }
  171. template <typename T, typename U>
  172. BOOST_CXX14_CONSTEXPR inline bool
  173. operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  174. {
  175. return x.base() < y.base();
  176. }
  177. template <typename T, typename U>
  178. BOOST_CXX14_CONSTEXPR inline bool
  179. operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  180. {
  181. return !(y < x);
  182. }
  183. template <typename T, typename U>
  184. BOOST_CXX14_CONSTEXPR inline bool
  185. operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  186. {
  187. return y < x;
  188. }
  189. template <typename T, typename U>
  190. BOOST_CXX14_CONSTEXPR inline bool
  191. operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  192. {
  193. return !(x < y);
  194. }
  195. template <typename T, typename U>
  196. BOOST_CXX14_CONSTEXPR inline typename std::iterator_traits<T>::difference_type
  197. operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  198. {
  199. return x.base() - y.base();
  200. }
  201. // == Output Iterator ==
  202. template <typename It>
  203. class output_iterator {
  204. public:
  205. typedef std::output_iterator_tag iterator_category;
  206. typedef void value_type;
  207. typedef typename std::iterator_traits<It>::difference_type difference_type;
  208. typedef It pointer;
  209. typedef typename std::iterator_traits<It>::reference reference;
  210. BOOST_CXX14_CONSTEXPR It base() const {return it_;}
  211. BOOST_CXX14_CONSTEXPR output_iterator () {}
  212. BOOST_CXX14_CONSTEXPR explicit output_iterator(It it) : it_(it) {}
  213. template <typename U>
  214. BOOST_CXX14_CONSTEXPR output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
  215. BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
  216. BOOST_CXX14_CONSTEXPR output_iterator& operator++() {++it_; return *this;}
  217. BOOST_CXX14_CONSTEXPR output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;}
  218. private:
  219. It it_;
  220. template <typename U> friend class output_iterator;
  221. };
  222. // No comparison operators for output iterators
  223. // == Get the base of an iterator; used for comparisons ==
  224. template <typename Iter>
  225. BOOST_CXX14_CONSTEXPR inline Iter base(output_iterator<Iter> i) { return i.base(); }
  226. template <typename Iter>
  227. BOOST_CXX14_CONSTEXPR inline Iter base(input_iterator<Iter> i) { return i.base(); }
  228. template <typename Iter>
  229. BOOST_CXX14_CONSTEXPR inline Iter base(forward_iterator<Iter> i) { return i.base(); }
  230. template <typename Iter>
  231. BOOST_CXX14_CONSTEXPR inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
  232. template <typename Iter>
  233. BOOST_CXX14_CONSTEXPR inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
  234. template <typename Iter> // everything else
  235. BOOST_CXX14_CONSTEXPR inline Iter base(Iter i) { return i; }
  236. #endif // ITERATORS_H