test_iterators.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef ITERATORS_H
  9. #define ITERATORS_H
  10. #include <iterator>
  11. #include <stdexcept>
  12. #include <cstddef>
  13. #include <cassert>
  14. #include "test_macros.h"
  15. #if TEST_STD_VER >= 11
  16. #define DELETE_FUNCTION = delete
  17. #else
  18. #define DELETE_FUNCTION
  19. #endif
  20. template <class It>
  21. class output_iterator
  22. {
  23. It it_;
  24. template <class U> friend class output_iterator;
  25. public:
  26. typedef std::output_iterator_tag iterator_category;
  27. typedef void value_type;
  28. typedef typename std::iterator_traits<It>::difference_type difference_type;
  29. typedef It pointer;
  30. typedef typename std::iterator_traits<It>::reference reference;
  31. It base() const {return it_;}
  32. output_iterator () {}
  33. explicit output_iterator(It it) : it_(it) {}
  34. template <class U>
  35. output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
  36. reference operator*() const {return *it_;}
  37. output_iterator& operator++() {++it_; return *this;}
  38. output_iterator operator++(int)
  39. {output_iterator tmp(*this); ++(*this); return tmp;}
  40. template <class T>
  41. void operator,(T const &) DELETE_FUNCTION;
  42. };
  43. template <class It,
  44. class ItTraits = It>
  45. class input_iterator
  46. {
  47. typedef std::iterator_traits<ItTraits> Traits;
  48. It it_;
  49. template <class U, class T> friend class input_iterator;
  50. public:
  51. typedef std::input_iterator_tag iterator_category;
  52. typedef typename Traits::value_type value_type;
  53. typedef typename Traits::difference_type difference_type;
  54. typedef It pointer;
  55. typedef typename Traits::reference reference;
  56. TEST_CONSTEXPR_CXX14 It base() const {return it_;}
  57. TEST_CONSTEXPR_CXX14 input_iterator() : it_() {}
  58. explicit TEST_CONSTEXPR_CXX14 input_iterator(It it) : it_(it) {}
  59. template <class U, class T>
  60. TEST_CONSTEXPR_CXX14 input_iterator(const input_iterator<U, T>& u) :it_(u.it_) {}
  61. TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
  62. TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
  63. TEST_CONSTEXPR_CXX14 input_iterator& operator++() {++it_; return *this;}
  64. TEST_CONSTEXPR_CXX14 input_iterator operator++(int)
  65. {input_iterator tmp(*this); ++(*this); return tmp;}
  66. friend TEST_CONSTEXPR_CXX14 bool operator==(const input_iterator& x, const input_iterator& y)
  67. {return x.it_ == y.it_;}
  68. friend TEST_CONSTEXPR_CXX14 bool operator!=(const input_iterator& x, const input_iterator& y)
  69. {return !(x == y);}
  70. template <class T>
  71. void operator,(T const &) DELETE_FUNCTION;
  72. };
  73. template <class T, class TV, class U, class UV>
  74. inline
  75. bool
  76. operator==(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
  77. {
  78. return x.base() == y.base();
  79. }
  80. template <class T, class TV, class U, class UV>
  81. inline
  82. bool
  83. operator!=(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
  84. {
  85. return !(x == y);
  86. }
  87. template <class It>
  88. class forward_iterator
  89. {
  90. It it_;
  91. template <class U> friend class forward_iterator;
  92. public:
  93. typedef std::forward_iterator_tag iterator_category;
  94. typedef typename std::iterator_traits<It>::value_type value_type;
  95. typedef typename std::iterator_traits<It>::difference_type difference_type;
  96. typedef It pointer;
  97. typedef typename std::iterator_traits<It>::reference reference;
  98. TEST_CONSTEXPR_CXX14 It base() const {return it_;}
  99. TEST_CONSTEXPR_CXX14 forward_iterator() : it_() {}
  100. explicit TEST_CONSTEXPR_CXX14 forward_iterator(It it) : it_(it) {}
  101. template <class U>
  102. TEST_CONSTEXPR_CXX14 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
  103. TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
  104. TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
  105. TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
  106. TEST_CONSTEXPR_CXX14 forward_iterator operator++(int)
  107. {forward_iterator tmp(*this); ++(*this); return tmp;}
  108. friend TEST_CONSTEXPR_CXX14 bool operator==(const forward_iterator& x, const forward_iterator& y)
  109. {return x.it_ == y.it_;}
  110. friend TEST_CONSTEXPR_CXX14 bool operator!=(const forward_iterator& x, const forward_iterator& y)
  111. {return !(x == y);}
  112. template <class T>
  113. void operator,(T const &) DELETE_FUNCTION;
  114. };
  115. template <class T, class U>
  116. inline
  117. bool TEST_CONSTEXPR_CXX14
  118. operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
  119. {
  120. return x.base() == y.base();
  121. }
  122. template <class T, class U>
  123. inline
  124. bool TEST_CONSTEXPR_CXX14
  125. operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
  126. {
  127. return !(x == y);
  128. }
  129. template <class It>
  130. class bidirectional_iterator
  131. {
  132. It it_;
  133. template <class U> friend class bidirectional_iterator;
  134. public:
  135. typedef std::bidirectional_iterator_tag iterator_category;
  136. typedef typename std::iterator_traits<It>::value_type value_type;
  137. typedef typename std::iterator_traits<It>::difference_type difference_type;
  138. typedef It pointer;
  139. typedef typename std::iterator_traits<It>::reference reference;
  140. TEST_CONSTEXPR_CXX14 It base() const {return it_;}
  141. TEST_CONSTEXPR_CXX14 bidirectional_iterator() : it_() {}
  142. explicit TEST_CONSTEXPR_CXX14 bidirectional_iterator(It it) : it_(it) {}
  143. template <class U>
  144. TEST_CONSTEXPR_CXX14 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
  145. TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
  146. TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
  147. TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
  148. TEST_CONSTEXPR_CXX14 bidirectional_iterator operator++(int)
  149. {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
  150. TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
  151. TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int)
  152. {bidirectional_iterator tmp(*this); --(*this); return tmp;}
  153. template <class T>
  154. void operator,(T const &) DELETE_FUNCTION;
  155. };
  156. template <class T, class U>
  157. inline
  158. bool TEST_CONSTEXPR_CXX14
  159. operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
  160. {
  161. return x.base() == y.base();
  162. }
  163. template <class T, class U>
  164. inline
  165. bool TEST_CONSTEXPR_CXX14
  166. operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
  167. {
  168. return !(x == y);
  169. }
  170. template <class It>
  171. class random_access_iterator
  172. {
  173. It it_;
  174. template <class U> friend class random_access_iterator;
  175. public:
  176. typedef std::random_access_iterator_tag iterator_category;
  177. typedef typename std::iterator_traits<It>::value_type value_type;
  178. typedef typename std::iterator_traits<It>::difference_type difference_type;
  179. typedef It pointer;
  180. typedef typename std::iterator_traits<It>::reference reference;
  181. TEST_CONSTEXPR_CXX14 It base() const {return it_;}
  182. TEST_CONSTEXPR_CXX14 random_access_iterator() : it_() {}
  183. explicit TEST_CONSTEXPR_CXX14 random_access_iterator(It it) : it_(it) {}
  184. template <class U>
  185. TEST_CONSTEXPR_CXX14 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
  186. TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
  187. TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
  188. TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}
  189. TEST_CONSTEXPR_CXX14 random_access_iterator operator++(int)
  190. {random_access_iterator tmp(*this); ++(*this); return tmp;}
  191. TEST_CONSTEXPR_CXX14 random_access_iterator& operator--() {--it_; return *this;}
  192. TEST_CONSTEXPR_CXX14 random_access_iterator operator--(int)
  193. {random_access_iterator tmp(*this); --(*this); return tmp;}
  194. TEST_CONSTEXPR_CXX14 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
  195. TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n) const
  196. {random_access_iterator tmp(*this); tmp += n; return tmp;}
  197. friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n, random_access_iterator x)
  198. {x += n; return x;}
  199. TEST_CONSTEXPR_CXX14 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
  200. TEST_CONSTEXPR_CXX14 random_access_iterator operator-(difference_type n) const
  201. {random_access_iterator tmp(*this); tmp -= n; return tmp;}
  202. TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
  203. template <class T>
  204. void operator,(T const &) DELETE_FUNCTION;
  205. };
  206. template <class T, class U>
  207. inline
  208. bool TEST_CONSTEXPR_CXX14
  209. operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  210. {
  211. return x.base() == y.base();
  212. }
  213. template <class T, class U>
  214. inline
  215. bool TEST_CONSTEXPR_CXX14
  216. operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  217. {
  218. return !(x == y);
  219. }
  220. template <class T, class U>
  221. inline
  222. bool TEST_CONSTEXPR_CXX14
  223. operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  224. {
  225. return x.base() < y.base();
  226. }
  227. template <class T, class U>
  228. inline
  229. bool TEST_CONSTEXPR_CXX14
  230. operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  231. {
  232. return !(y < x);
  233. }
  234. template <class T, class U>
  235. inline
  236. bool TEST_CONSTEXPR_CXX14
  237. operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  238. {
  239. return y < x;
  240. }
  241. template <class T, class U>
  242. inline
  243. bool TEST_CONSTEXPR_CXX14
  244. operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  245. {
  246. return !(x < y);
  247. }
  248. template <class T, class U>
  249. inline TEST_CONSTEXPR_CXX14
  250. typename std::iterator_traits<T>::difference_type
  251. operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
  252. {
  253. return x.base() - y.base();
  254. }
  255. template <class Iter>
  256. inline TEST_CONSTEXPR_CXX14 Iter base(output_iterator<Iter> i) { return i.base(); }
  257. template <class Iter>
  258. inline TEST_CONSTEXPR_CXX14 Iter base(input_iterator<Iter> i) { return i.base(); }
  259. template <class Iter>
  260. inline TEST_CONSTEXPR_CXX14 Iter base(forward_iterator<Iter> i) { return i.base(); }
  261. template <class Iter>
  262. inline TEST_CONSTEXPR_CXX14 Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
  263. template <class Iter>
  264. inline TEST_CONSTEXPR_CXX14 Iter base(random_access_iterator<Iter> i) { return i.base(); }
  265. template <class Iter> // everything else
  266. inline TEST_CONSTEXPR_CXX14 Iter base(Iter i) { return i; }
  267. template <typename T>
  268. struct ThrowingIterator {
  269. typedef std::bidirectional_iterator_tag iterator_category;
  270. typedef ptrdiff_t difference_type;
  271. typedef const T value_type;
  272. typedef const T * pointer;
  273. typedef const T & reference;
  274. enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
  275. // Constructors
  276. ThrowingIterator ()
  277. : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
  278. ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference)
  279. : begin_(first), end_(last), current_(first), action_(action), index_(index) {}
  280. ThrowingIterator (const ThrowingIterator &rhs)
  281. : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}
  282. ThrowingIterator & operator= (const ThrowingIterator &rhs)
  283. {
  284. if (action_ == TAAssignment)
  285. {
  286. if (index_ == 0)
  287. #ifndef TEST_HAS_NO_EXCEPTIONS
  288. throw std::runtime_error ("throw from iterator assignment");
  289. #else
  290. assert(false);
  291. #endif
  292. else
  293. --index_;
  294. }
  295. begin_ = rhs.begin_;
  296. end_ = rhs.end_;
  297. current_ = rhs.current_;
  298. action_ = rhs.action_;
  299. index_ = rhs.index_;
  300. return *this;
  301. }
  302. // iterator operations
  303. reference operator*() const
  304. {
  305. if (action_ == TADereference)
  306. {
  307. if (index_ == 0)
  308. #ifndef TEST_HAS_NO_EXCEPTIONS
  309. throw std::runtime_error ("throw from iterator dereference");
  310. #else
  311. assert(false);
  312. #endif
  313. else
  314. --index_;
  315. }
  316. return *current_;
  317. }
  318. ThrowingIterator & operator++()
  319. {
  320. if (action_ == TAIncrement)
  321. {
  322. if (index_ == 0)
  323. #ifndef TEST_HAS_NO_EXCEPTIONS
  324. throw std::runtime_error ("throw from iterator increment");
  325. #else
  326. assert(false);
  327. #endif
  328. else
  329. --index_;
  330. }
  331. ++current_;
  332. return *this;
  333. }
  334. ThrowingIterator operator++(int)
  335. {
  336. ThrowingIterator temp = *this;
  337. ++(*this);
  338. return temp;
  339. }
  340. ThrowingIterator & operator--()
  341. {
  342. if (action_ == TADecrement)
  343. {
  344. if (index_ == 0)
  345. #ifndef TEST_HAS_NO_EXCEPTIONS
  346. throw std::runtime_error ("throw from iterator decrement");
  347. #else
  348. assert(false);
  349. #endif
  350. else
  351. --index_;
  352. }
  353. --current_;
  354. return *this;
  355. }
  356. ThrowingIterator operator--(int) {
  357. ThrowingIterator temp = *this;
  358. --(*this);
  359. return temp;
  360. }
  361. bool operator== (const ThrowingIterator &rhs) const
  362. {
  363. if (action_ == TAComparison)
  364. {
  365. if (index_ == 0)
  366. #ifndef TEST_HAS_NO_EXCEPTIONS
  367. throw std::runtime_error ("throw from iterator comparison");
  368. #else
  369. assert(false);
  370. #endif
  371. else
  372. --index_;
  373. }
  374. bool atEndL = current_ == end_;
  375. bool atEndR = rhs.current_ == rhs.end_;
  376. if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
  377. if (atEndL) return true; // both are at the end (or empty)
  378. return current_ == rhs.current_;
  379. }
  380. private:
  381. const T* begin_;
  382. const T* end_;
  383. const T* current_;
  384. ThrowingAction action_;
  385. mutable size_t index_;
  386. };
  387. template <typename T>
  388. bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
  389. { return a.operator==(b); }
  390. template <typename T>
  391. bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
  392. { return !a.operator==(b); }
  393. template <typename T>
  394. struct NonThrowingIterator {
  395. typedef std::bidirectional_iterator_tag iterator_category;
  396. typedef ptrdiff_t difference_type;
  397. typedef const T value_type;
  398. typedef const T * pointer;
  399. typedef const T & reference;
  400. // Constructors
  401. NonThrowingIterator ()
  402. : begin_(nullptr), end_(nullptr), current_(nullptr) {}
  403. NonThrowingIterator (const T *first, const T* last)
  404. : begin_(first), end_(last), current_(first) {}
  405. NonThrowingIterator (const NonThrowingIterator &rhs)
  406. : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {}
  407. NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT
  408. {
  409. begin_ = rhs.begin_;
  410. end_ = rhs.end_;
  411. current_ = rhs.current_;
  412. return *this;
  413. }
  414. // iterator operations
  415. reference operator*() const TEST_NOEXCEPT
  416. {
  417. return *current_;
  418. }
  419. NonThrowingIterator & operator++() TEST_NOEXCEPT
  420. {
  421. ++current_;
  422. return *this;
  423. }
  424. NonThrowingIterator operator++(int) TEST_NOEXCEPT
  425. {
  426. NonThrowingIterator temp = *this;
  427. ++(*this);
  428. return temp;
  429. }
  430. NonThrowingIterator & operator--() TEST_NOEXCEPT
  431. {
  432. --current_;
  433. return *this;
  434. }
  435. NonThrowingIterator operator--(int) TEST_NOEXCEPT
  436. {
  437. NonThrowingIterator temp = *this;
  438. --(*this);
  439. return temp;
  440. }
  441. bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
  442. {
  443. bool atEndL = current_ == end_;
  444. bool atEndR = rhs.current_ == rhs.end_;
  445. if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
  446. if (atEndL) return true; // both are at the end (or empty)
  447. return current_ == rhs.current_;
  448. }
  449. private:
  450. const T* begin_;
  451. const T* end_;
  452. const T* current_;
  453. };
  454. template <typename T>
  455. bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
  456. { return a.operator==(b); }
  457. template <typename T>
  458. bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
  459. { return !a.operator==(b); }
  460. #undef DELETE_FUNCTION
  461. #endif // ITERATORS_H