test_iterators.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef RANGES_TEST_ITERATORS_HPP
  10. #define RANGES_TEST_ITERATORS_HPP
  11. #include <iterator>
  12. #include <range/v3/range/dangling.hpp>
  13. template<class It, bool Sized = false>
  14. class Sentinel;
  15. template<class It>
  16. class OutputIterator;
  17. template<class It, bool Sized = false>
  18. class InputIterator;
  19. template<class It, bool Sized = false>
  20. class ForwardIterator;
  21. template<class It, bool Sized = false>
  22. class BidirectionalIterator;
  23. template<class It>
  24. class RandomAccessIterator;
  25. template<class Iter, bool Sized>
  26. constexpr /*c++14*/ Iter base(Sentinel<Iter, Sized> i) { return i.base(); }
  27. template<class Iter>
  28. constexpr /*c++14*/ Iter base(OutputIterator<Iter> i) { return i.base(); }
  29. template<class Iter, bool Sized>
  30. constexpr /*c++14*/ Iter base(InputIterator<Iter, Sized> i) { return i.base(); }
  31. template<class Iter, bool Sized>
  32. constexpr /*c++14*/ Iter base(ForwardIterator<Iter, Sized> i) { return i.base(); }
  33. template<class Iter, bool Sized>
  34. constexpr /*c++14*/ Iter base(BidirectionalIterator<Iter, Sized> i) { return i.base(); }
  35. template<class Iter>
  36. constexpr /*c++14*/ Iter base(RandomAccessIterator<Iter> i) { return i.base(); }
  37. template<class Iter> // everything else
  38. constexpr /*c++14*/ Iter base(Iter i) { return i; }
  39. template<class It, bool Sized>
  40. class Sentinel
  41. {
  42. It it_;
  43. public:
  44. constexpr /*c++14*/ Sentinel() : it_() {}
  45. constexpr /*c++14*/ explicit Sentinel(It it) : it_(it) {}
  46. constexpr /*c++14*/ It base() const { return it_; }
  47. constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const Sentinel& y)
  48. {
  49. RANGES_ENSURE(x.it_ == y.it_);
  50. return true;
  51. }
  52. constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const Sentinel& y)
  53. {
  54. RANGES_ENSURE(x.it_ == y.it_);
  55. return false;
  56. }
  57. template<typename I>
  58. constexpr /*c++14*/ friend bool operator==(const I& x, const Sentinel& y)
  59. {
  60. using ::base;
  61. return base(x) == y.it_;
  62. }
  63. template<typename I>
  64. constexpr /*c++14*/ friend bool operator!=(const I& x, const Sentinel& y)
  65. {
  66. return !(x == y);
  67. }
  68. template<typename I>
  69. constexpr /*c++14*/ friend bool operator==(const Sentinel& x, const I& y)
  70. {
  71. using ::base;
  72. return x.it_ == base(y);
  73. }
  74. template<typename I>
  75. constexpr /*c++14*/ friend bool operator!=(const Sentinel& x, const I& y)
  76. {
  77. return !(x == y);
  78. }
  79. };
  80. // For making sized iterator ranges:
  81. template<template<typename> class I, typename It>
  82. constexpr /*c++14*/
  83. auto CPP_auto_fun(operator-)(Sentinel<It, true> last, I<It> first)
  84. (
  85. return base(last) - base(first)
  86. )
  87. template<template<typename> class I, typename It>
  88. constexpr /*c++14*/
  89. auto CPP_auto_fun(operator-)(I<It> first, Sentinel<It, true> last)
  90. (
  91. return base(first) - base(last)
  92. )
  93. template<class It>
  94. class OutputIterator
  95. {
  96. It it_;
  97. template<class U> friend class OutputIterator;
  98. public:
  99. typedef std::output_iterator_tag iterator_category;
  100. typedef void value_type;
  101. typedef typename std::iterator_traits<It>::difference_type difference_type;
  102. typedef It pointer;
  103. typedef typename std::iterator_traits<It>::reference reference;
  104. constexpr /*c++14*/ It base() const {return it_;}
  105. constexpr /*c++14*/ OutputIterator () {}
  106. constexpr /*c++14*/ explicit OutputIterator(It it) : it_(it) {}
  107. template<class U, class = typename std::enable_if<std::is_convertible<U, It>{}>::type>
  108. constexpr /*c++14*/
  109. OutputIterator(const OutputIterator<U>& u) :it_(u.it_) {}
  110. constexpr /*c++14*/ reference operator*() const {return *it_;}
  111. constexpr /*c++14*/ OutputIterator& operator++() {++it_; return *this;}
  112. constexpr /*c++14*/ OutputIterator operator++(int)
  113. {OutputIterator tmp(*this); ++(*this); return tmp;}
  114. };
  115. template<class It, bool Sized>
  116. class InputIterator
  117. {
  118. It it_;
  119. template<class, bool> friend class InputIterator;
  120. public:
  121. typedef std::input_iterator_tag iterator_category;
  122. typedef typename std::iterator_traits<It>::value_type value_type;
  123. typedef typename std::iterator_traits<It>::difference_type difference_type;
  124. typedef It pointer;
  125. typedef typename std::iterator_traits<It>::reference reference;
  126. constexpr /*c++14*/ It base() const {return it_;}
  127. constexpr /*c++14*/ InputIterator() : it_() {}
  128. constexpr /*c++14*/ explicit InputIterator(It it) : it_(it) {}
  129. template<class U, bool USized>
  130. constexpr /*c++14*/ CPP_ctor(InputIterator)(const InputIterator<U, USized>& u)(
  131. requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}
  132. constexpr /*c++14*/ reference operator*() const {return *it_;}
  133. constexpr /*c++14*/ pointer operator->() const {return it_;}
  134. constexpr /*c++14*/ InputIterator& operator++() {++it_; return *this;}
  135. constexpr /*c++14*/ InputIterator operator++(int)
  136. {InputIterator tmp(*this); ++(*this); return tmp;}
  137. constexpr /*c++14*/
  138. friend bool operator==(const InputIterator& x, const InputIterator& y)
  139. {return x.it_ == y.it_;}
  140. constexpr /*c++14*/
  141. friend bool operator!=(const InputIterator& x, const InputIterator& y)
  142. {return !(x == y);}
  143. template<bool B = Sized, meta::if_c<B, int> = 42>
  144. constexpr /*c++14*/
  145. friend difference_type operator-(const InputIterator& x, const InputIterator& y)
  146. {return x.it_ - y.it_;}
  147. };
  148. template<class T, bool TSized, class U, bool USized>
  149. constexpr /*c++14*/
  150. bool
  151. operator==(const InputIterator<T, TSized>& x, const InputIterator<U, USized>& y)
  152. {
  153. return x.base() == y.base();
  154. }
  155. template<class T, bool TSized, class U, bool USized>
  156. constexpr /*c++14*/
  157. bool
  158. operator!=(const InputIterator<T, TSized>& x, const InputIterator<U, USized>& y)
  159. {
  160. return !(x == y);
  161. }
  162. template<class It, bool Sized>
  163. class ForwardIterator
  164. {
  165. It it_;
  166. template<class, bool> friend class ForwardIterator;
  167. public:
  168. typedef std::forward_iterator_tag iterator_category;
  169. typedef typename std::iterator_traits<It>::value_type value_type;
  170. typedef typename std::iterator_traits<It>::difference_type difference_type;
  171. typedef It pointer;
  172. typedef typename std::iterator_traits<It>::reference reference;
  173. constexpr /*c++14*/ It base() const {return it_;}
  174. constexpr /*c++14*/ ForwardIterator() : it_() {}
  175. constexpr /*c++14*/ explicit ForwardIterator(It it) : it_(it) {}
  176. template<class U, bool USized>
  177. constexpr /*c++14*/ CPP_ctor(ForwardIterator)(const ForwardIterator<U, USized>& u)(
  178. requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}
  179. constexpr /*c++14*/ reference operator*() const {return *it_;}
  180. constexpr /*c++14*/ pointer operator->() const {return it_;}
  181. constexpr /*c++14*/ ForwardIterator& operator++() {++it_; return *this;}
  182. constexpr /*c++14*/ ForwardIterator operator++(int)
  183. {ForwardIterator tmp(*this); ++(*this); return tmp;}
  184. constexpr /*c++14*/
  185. friend bool operator==(const ForwardIterator& x, const ForwardIterator& y)
  186. {return x.it_ == y.it_;}
  187. constexpr /*c++14*/
  188. friend bool operator!=(const ForwardIterator& x, const ForwardIterator& y)
  189. {return !(x == y);}
  190. };
  191. template<class T, bool TSized, class U, bool USized>
  192. constexpr /*c++14*/
  193. bool
  194. operator==(const ForwardIterator<T, TSized>& x, const ForwardIterator<U, USized>& y)
  195. {
  196. return x.base() == y.base();
  197. }
  198. template<class T, bool TSized, class U, bool USized>
  199. constexpr /*c++14*/
  200. bool
  201. operator!=(const ForwardIterator<T, TSized>& x, const ForwardIterator<U, USized>& y)
  202. {
  203. return !(x == y);
  204. }
  205. template<class It, bool Sized>
  206. class BidirectionalIterator
  207. {
  208. It it_;
  209. template<class, bool> friend class BidirectionalIterator;
  210. public:
  211. typedef std::bidirectional_iterator_tag iterator_category;
  212. typedef typename std::iterator_traits<It>::value_type value_type;
  213. typedef typename std::iterator_traits<It>::difference_type difference_type;
  214. typedef It pointer;
  215. typedef typename std::iterator_traits<It>::reference reference;
  216. constexpr /*c++14*/ It base() const {return it_;}
  217. constexpr /*c++14*/ BidirectionalIterator() : it_() {}
  218. constexpr /*c++14*/ explicit BidirectionalIterator(It it) : it_(it) {}
  219. template<class U, bool USized>
  220. constexpr /*c++14*/ CPP_ctor(BidirectionalIterator)(const BidirectionalIterator<U, USized>& u)(
  221. requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}
  222. constexpr /*c++14*/ reference operator*() const {return *it_;}
  223. constexpr /*c++14*/ pointer operator->() const {return it_;}
  224. constexpr /*c++14*/ BidirectionalIterator& operator++() {++it_; return *this;}
  225. constexpr /*c++14*/ BidirectionalIterator operator++(int)
  226. {BidirectionalIterator tmp(*this); ++(*this); return tmp;}
  227. constexpr /*c++14*/ BidirectionalIterator& operator--() {--it_; return *this;}
  228. constexpr /*c++14*/ BidirectionalIterator operator--(int)
  229. {BidirectionalIterator tmp(*this); --(*this); return tmp;}
  230. };
  231. template<class T, bool TSized, class U, bool USized>
  232. constexpr /*c++14*/
  233. bool
  234. operator==(const BidirectionalIterator<T, TSized>& x, const BidirectionalIterator<U, USized>& y)
  235. {
  236. return x.base() == y.base();
  237. }
  238. template<class T, bool TSized, class U, bool USized>
  239. constexpr /*c++14*/
  240. bool
  241. operator!=(const BidirectionalIterator<T, TSized>& x, const BidirectionalIterator<U, USized>& y)
  242. {
  243. return !(x == y);
  244. }
  245. template<class It>
  246. class RandomAccessIterator
  247. {
  248. It it_;
  249. template<class U> friend class RandomAccessIterator;
  250. public:
  251. typedef std::random_access_iterator_tag iterator_category;
  252. typedef typename std::iterator_traits<It>::value_type value_type;
  253. typedef typename std::iterator_traits<It>::difference_type difference_type;
  254. typedef It pointer;
  255. typedef typename std::iterator_traits<It>::reference reference;
  256. constexpr /*c++14*/ It base() const {return it_;}
  257. constexpr /*c++14*/ RandomAccessIterator() : it_() {}
  258. constexpr /*c++14*/ explicit RandomAccessIterator(It it) : it_(it) {}
  259. template<class U>
  260. constexpr /*c++14*/ CPP_ctor(RandomAccessIterator)(const RandomAccessIterator<U>& u)(
  261. requires (std::is_convertible<U, It>::value)) :it_(u.it_) {}
  262. constexpr /*c++14*/ reference operator*() const {return *it_;}
  263. constexpr /*c++14*/ pointer operator->() const {return it_;}
  264. constexpr /*c++14*/ RandomAccessIterator& operator++() {++it_; return *this;}
  265. constexpr /*c++14*/ RandomAccessIterator operator++(int)
  266. {RandomAccessIterator tmp(*this); ++(*this); return tmp;}
  267. constexpr /*c++14*/ RandomAccessIterator& operator--() {--it_; return *this;}
  268. constexpr /*c++14*/ RandomAccessIterator operator--(int)
  269. {RandomAccessIterator tmp(*this); --(*this); return tmp;}
  270. constexpr /*c++14*/
  271. RandomAccessIterator& operator+=(difference_type n) {it_ += n; return *this;}
  272. constexpr /*c++14*/
  273. RandomAccessIterator operator+(difference_type n) const
  274. {RandomAccessIterator tmp(*this); tmp += n; return tmp;}
  275. constexpr /*c++14*/
  276. friend RandomAccessIterator operator+(difference_type n, RandomAccessIterator x)
  277. {x += n; return x;}
  278. constexpr /*c++14*/
  279. RandomAccessIterator& operator-=(difference_type n) {return *this += -n;}
  280. constexpr /*c++14*/
  281. RandomAccessIterator operator-(difference_type n) const
  282. {RandomAccessIterator tmp(*this); tmp -= n; return tmp;}
  283. constexpr /*c++14*/
  284. reference operator[](difference_type n) const {return it_[n];}
  285. };
  286. template<class T, class U>
  287. constexpr /*c++14*/
  288. bool
  289. operator==(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  290. {
  291. return x.base() == y.base();
  292. }
  293. template<class T, class U>
  294. constexpr /*c++14*/
  295. bool
  296. operator!=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  297. {
  298. return !(x == y);
  299. }
  300. template<class T, class U>
  301. constexpr /*c++14*/
  302. bool
  303. operator<(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  304. {
  305. return x.base() < y.base();
  306. }
  307. template<class T, class U>
  308. constexpr /*c++14*/
  309. bool
  310. operator<=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  311. {
  312. return !(y < x);
  313. }
  314. template<class T, class U>
  315. constexpr /*c++14*/
  316. bool
  317. operator>(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  318. {
  319. return y < x;
  320. }
  321. template<class T, class U>
  322. constexpr /*c++14*/
  323. bool
  324. operator>=(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  325. {
  326. return !(x < y);
  327. }
  328. template<class T, class U>
  329. constexpr /*c++14*/
  330. auto CPP_auto_fun(operator-)(const RandomAccessIterator<T>& x, const RandomAccessIterator<U>& y)
  331. (
  332. return x.base() - y.base()
  333. )
  334. template<typename It, bool Sized = false>
  335. struct sentinel_type
  336. {
  337. using type = It;
  338. };
  339. template<typename T, bool Sized>
  340. struct sentinel_type<T*, Sized>
  341. {
  342. using type = Sentinel<T*, Sized>;
  343. };
  344. template<template<typename> class I, typename It, bool Sized>
  345. struct sentinel_type<I<It>, Sized>
  346. {
  347. using type = Sentinel<It, Sized>;
  348. };
  349. template<class I, class S>
  350. struct TestRange
  351. {
  352. I first;
  353. S second;
  354. constexpr I begin() const { return first; }
  355. constexpr S end() const { return second; }
  356. };
  357. template<class I, class S>
  358. TestRange<I, S> MakeTestRange(I i, S s)
  359. {
  360. return {i, s};
  361. }
  362. template<typename T>
  363. constexpr bool is_dangling(T)
  364. {
  365. return false;
  366. }
  367. constexpr bool is_dangling(::ranges::dangling)
  368. {
  369. return true;
  370. }
  371. #endif // RANGES_TEST_ITERATORS_HPP