new_iterator_tests.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #ifndef BOOST_NEW_ITERATOR_TESTS_HPP
  2. # define BOOST_NEW_ITERATOR_TESTS_HPP
  3. //
  4. // Copyright (c) David Abrahams 2001.
  5. // Copyright (c) Jeremy Siek 2001-2003.
  6. // Copyright (c) Thomas Witt 2002.
  7. //
  8. // Use, modification and distribution is subject to the
  9. // Boost Software License, Version 1.0.
  10. // (See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. //
  13. // This is meant to be the beginnings of a comprehensive, generic
  14. // test suite for STL concepts such as iterators and containers.
  15. //
  16. // Revision History:
  17. // 28 Oct 2002 Started update for new iterator categories
  18. // (Jeremy Siek)
  19. // 28 Apr 2002 Fixed input iterator requirements.
  20. // For a == b a++ == b++ is no longer required.
  21. // See 24.1.1/3 for details.
  22. // (Thomas Witt)
  23. // 08 Feb 2001 Fixed bidirectional iterator test so that
  24. // --i is no longer a precondition.
  25. // (Jeremy Siek)
  26. // 04 Feb 2001 Added lvalue test, corrected preconditions
  27. // (David Abrahams)
  28. # include <iterator>
  29. # include <boost/static_assert.hpp>
  30. # include <boost/concept_archetype.hpp> // for detail::dummy_constructor
  31. # include <boost/pending/iterator_tests.hpp>
  32. # include <boost/iterator/is_readable_iterator.hpp>
  33. # include <boost/iterator/is_lvalue_iterator.hpp>
  34. # include <boost/type_traits/is_same.hpp>
  35. # include <boost/mpl/bool.hpp>
  36. # include <boost/mpl/and.hpp>
  37. # include <boost/iterator/detail/config_def.hpp>
  38. # include <boost/detail/is_incrementable.hpp>
  39. # include <boost/core/lightweight_test.hpp>
  40. namespace boost {
  41. // Do separate tests for *i++ so we can treat, e.g., smart pointers,
  42. // as readable and/or writable iterators.
  43. template <class Iterator, class T>
  44. void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
  45. {
  46. T v2(*i1++);
  47. BOOST_TEST(v == v2);
  48. }
  49. template <class Iterator, class T>
  50. void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
  51. {}
  52. template <class Iterator, class T>
  53. void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
  54. {
  55. ++i1; // we just wrote into that position
  56. *i1++ = v;
  57. Iterator x(i1++);
  58. (void)x;
  59. }
  60. template <class Iterator, class T>
  61. void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
  62. {}
  63. // Preconditions: *i == v
  64. template <class Iterator, class T>
  65. void readable_iterator_test(const Iterator i1, T v)
  66. {
  67. Iterator i2(i1); // Copy Constructible
  68. typedef typename std::iterator_traits<Iterator>::reference ref_t;
  69. ref_t r1 = *i1;
  70. ref_t r2 = *i2;
  71. T v1 = r1;
  72. T v2 = r2;
  73. BOOST_TEST(v1 == v);
  74. BOOST_TEST(v2 == v);
  75. # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
  76. readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
  77. // I think we don't really need this as it checks the same things as
  78. // the above code.
  79. BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
  80. # endif
  81. }
  82. template <class Iterator, class T>
  83. void writable_iterator_test(Iterator i, T v, T v2)
  84. {
  85. Iterator i2(i); // Copy Constructible
  86. *i2 = v;
  87. # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
  88. writable_iterator_traversal_test(
  89. i, v2, mpl::and_<
  90. detail::is_incrementable<Iterator>
  91. , detail::is_postfix_incrementable<Iterator>
  92. >());
  93. # endif
  94. }
  95. template <class Iterator>
  96. void swappable_iterator_test(Iterator i, Iterator j)
  97. {
  98. Iterator i2(i), j2(j);
  99. typename std::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
  100. iter_swap(i2, j2);
  101. typename std::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
  102. BOOST_TEST(bi == aj && bj == ai);
  103. }
  104. template <class Iterator, class T>
  105. void constant_lvalue_iterator_test(Iterator i, T v1)
  106. {
  107. Iterator i2(i);
  108. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  109. typedef typename std::iterator_traits<Iterator>::reference reference;
  110. BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
  111. const T& v2 = *i2;
  112. BOOST_TEST(v1 == v2);
  113. # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  114. BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
  115. BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
  116. # endif
  117. }
  118. template <class Iterator, class T>
  119. void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
  120. {
  121. Iterator i2(i);
  122. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  123. typedef typename std::iterator_traits<Iterator>::reference reference;
  124. BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
  125. T& v3 = *i2;
  126. BOOST_TEST(v1 == v3);
  127. // A non-const lvalue iterator is not neccessarily writable, but we
  128. // are assuming the value_type is assignable here
  129. *i = v2;
  130. T& v4 = *i2;
  131. BOOST_TEST(v2 == v4);
  132. # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  133. BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
  134. BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
  135. # endif
  136. }
  137. template <class Iterator, class T>
  138. void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
  139. {
  140. Iterator i2;
  141. Iterator i3(i);
  142. i2 = i;
  143. BOOST_TEST(i2 == i3);
  144. BOOST_TEST(i != j);
  145. BOOST_TEST(i2 != j);
  146. readable_iterator_test(i, val1);
  147. readable_iterator_test(i2, val1);
  148. readable_iterator_test(i3, val1);
  149. BOOST_TEST(i == i2++);
  150. BOOST_TEST(i != ++i3);
  151. readable_iterator_test(i2, val2);
  152. readable_iterator_test(i3, val2);
  153. readable_iterator_test(i, val1);
  154. }
  155. template <class Iterator, class T>
  156. void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
  157. {
  158. forward_readable_iterator_test(i, j, val1, val2);
  159. Iterator i2 = i;
  160. ++i2;
  161. swappable_iterator_test(i, i2);
  162. }
  163. // bidirectional
  164. // Preconditions: *i == v1, *++i == v2
  165. template <class Iterator, class T>
  166. void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
  167. {
  168. Iterator j(i);
  169. ++j;
  170. forward_readable_iterator_test(i, j, v1, v2);
  171. ++i;
  172. Iterator i1 = i, i2 = i;
  173. BOOST_TEST(i == i1--);
  174. BOOST_TEST(i != --i2);
  175. readable_iterator_test(i, v2);
  176. readable_iterator_test(i1, v1);
  177. readable_iterator_test(i2, v1);
  178. --i;
  179. BOOST_TEST(i == i1);
  180. BOOST_TEST(i == i2);
  181. ++i1;
  182. ++i2;
  183. readable_iterator_test(i, v1);
  184. readable_iterator_test(i1, v2);
  185. readable_iterator_test(i2, v2);
  186. }
  187. // random access
  188. // Preconditions: [i,i+N) is a valid range
  189. template <class Iterator, class TrueVals>
  190. void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
  191. {
  192. bidirectional_readable_iterator_test(i, vals[0], vals[1]);
  193. const Iterator j = i;
  194. int c;
  195. for (c = 0; c < N-1; ++c)
  196. {
  197. BOOST_TEST(i == j + c);
  198. BOOST_TEST(*i == vals[c]);
  199. typename std::iterator_traits<Iterator>::value_type x = j[c];
  200. BOOST_TEST(*i == x);
  201. BOOST_TEST(*i == *(j + c));
  202. BOOST_TEST(*i == *(c + j));
  203. ++i;
  204. BOOST_TEST(i > j);
  205. BOOST_TEST(i >= j);
  206. BOOST_TEST(j <= i);
  207. BOOST_TEST(j < i);
  208. }
  209. Iterator k = j + N - 1;
  210. for (c = 0; c < N-1; ++c)
  211. {
  212. BOOST_TEST(i == k - c);
  213. BOOST_TEST(*i == vals[N - 1 - c]);
  214. typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
  215. BOOST_TEST(*i == x);
  216. Iterator q = k - c;
  217. BOOST_TEST(*i == *q);
  218. BOOST_TEST(i > j);
  219. BOOST_TEST(i >= j);
  220. BOOST_TEST(j <= i);
  221. BOOST_TEST(j < i);
  222. --i;
  223. }
  224. }
  225. } // namespace boost
  226. # include <boost/iterator/detail/config_undef.hpp>
  227. #endif // BOOST_NEW_ITERATOR_TESTS_HPP