/Src/Dependencies/Boost/libs/iterator/test/iterator_adaptor_test.cpp

http://hadesmem.googlecode.com/ · C++ · 337 lines · 259 code · 56 blank · 22 comment · 7 complexity · 18c3c15f350d54e687a9cb5b61f8f78f MD5 · raw file

  1. // (C) Copyright Thomas Witt 2003.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org for most recent version including documentation.
  6. #include <boost/config.hpp>
  7. #include <iostream>
  8. #include <algorithm>
  9. #include <functional>
  10. #include <numeric>
  11. #include <boost/iterator/iterator_adaptor.hpp>
  12. #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
  13. # include <boost/iterator/is_readable_iterator.hpp>
  14. # include <boost/iterator/is_lvalue_iterator.hpp>
  15. #endif
  16. #include <boost/pending/iterator_tests.hpp>
  17. # include <boost/type_traits/broken_compiler_spec.hpp>
  18. # include <boost/detail/lightweight_test.hpp>
  19. #include <stdlib.h>
  20. #include <vector>
  21. #include <deque>
  22. #include <set>
  23. #include <list>
  24. #include "static_assert_same.hpp"
  25. #include <boost/iterator/detail/config_def.hpp>
  26. using boost::dummyT;
  27. struct mult_functor {
  28. typedef int result_type;
  29. typedef int argument_type;
  30. // Functors used with transform_iterator must be
  31. // DefaultConstructible, as the transform_iterator must be
  32. // DefaultConstructible to satisfy the requirements for
  33. // TrivialIterator.
  34. mult_functor() { }
  35. mult_functor(int aa) : a(aa) { }
  36. int operator()(int b) const { return a * b; }
  37. int a;
  38. };
  39. template <class Pair>
  40. struct select1st_
  41. : public std::unary_function<Pair, typename Pair::first_type>
  42. {
  43. const typename Pair::first_type& operator()(const Pair& x) const {
  44. return x.first;
  45. }
  46. typename Pair::first_type& operator()(Pair& x) const {
  47. return x.first;
  48. }
  49. };
  50. struct one_or_four {
  51. bool operator()(dummyT x) const {
  52. return x.foo() == 1 || x.foo() == 4;
  53. }
  54. };
  55. typedef std::deque<int> storage;
  56. typedef std::deque<int*> pointer_deque;
  57. typedef std::set<storage::iterator> iterator_set;
  58. template <class T> struct foo;
  59. void blah(int) { }
  60. struct my_gen
  61. {
  62. typedef int result_type;
  63. my_gen() : n(0) { }
  64. int operator()() { return ++n; }
  65. int n;
  66. };
  67. template <class V>
  68. struct ptr_iterator
  69. : boost::iterator_adaptor<
  70. ptr_iterator<V>
  71. , V*
  72. , V
  73. , boost::random_access_traversal_tag
  74. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
  75. , V&
  76. #endif
  77. >
  78. {
  79. private:
  80. typedef boost::iterator_adaptor<
  81. ptr_iterator<V>
  82. , V*
  83. , V
  84. , boost::random_access_traversal_tag
  85. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
  86. , V&
  87. #endif
  88. > super_t;
  89. public:
  90. ptr_iterator() { }
  91. ptr_iterator(V* d) : super_t(d) { }
  92. template <class V2>
  93. ptr_iterator(
  94. const ptr_iterator<V2>& x
  95. , typename boost::enable_if_convertible<V2*, V*>::type* = 0
  96. )
  97. : super_t(x.base())
  98. {}
  99. };
  100. // Non-functional iterator for category modification checking
  101. template <class Iter, class Traversal>
  102. struct modify_traversal
  103. : boost::iterator_adaptor<
  104. modify_traversal<Iter, Traversal>
  105. , Iter
  106. , boost::use_default
  107. , Traversal
  108. >
  109. {};
  110. template <class T>
  111. struct fwd_iterator
  112. : boost::iterator_adaptor<
  113. fwd_iterator<T>
  114. , boost::forward_iterator_archetype<T>
  115. >
  116. {
  117. private:
  118. typedef boost::iterator_adaptor<
  119. fwd_iterator<T>
  120. , boost::forward_iterator_archetype<T>
  121. > super_t;
  122. public:
  123. fwd_iterator() { }
  124. fwd_iterator(boost::forward_iterator_archetype<T> d) : super_t(d) { }
  125. };
  126. template <class T>
  127. struct in_iterator
  128. : boost::iterator_adaptor<
  129. in_iterator<T>
  130. , boost::input_iterator_archetype_no_proxy<T>
  131. >
  132. {
  133. private:
  134. typedef boost::iterator_adaptor<
  135. in_iterator<T>
  136. , boost::input_iterator_archetype_no_proxy<T>
  137. > super_t;
  138. public:
  139. in_iterator() { }
  140. in_iterator(boost::input_iterator_archetype_no_proxy<T> d) : super_t(d) { }
  141. };
  142. template <class Iter>
  143. struct constant_iterator
  144. : boost::iterator_adaptor<
  145. constant_iterator<Iter>
  146. , Iter
  147. , typename std::iterator_traits<Iter>::value_type const
  148. >
  149. {
  150. typedef boost::iterator_adaptor<
  151. constant_iterator<Iter>
  152. , Iter
  153. , typename std::iterator_traits<Iter>::value_type const
  154. > base_t;
  155. constant_iterator() {}
  156. constant_iterator(Iter it)
  157. : base_t(it) {}
  158. };
  159. char (& traversal2(boost::incrementable_traversal_tag) )[1];
  160. char (& traversal2(boost::single_pass_traversal_tag ) )[2];
  161. char (& traversal2(boost::forward_traversal_tag ) )[3];
  162. char (& traversal2(boost::bidirectional_traversal_tag) )[4];
  163. char (& traversal2(boost::random_access_traversal_tag) )[5];
  164. template <class Cat>
  165. struct traversal3
  166. {
  167. static typename boost::iterator_category_to_traversal<Cat>::type x;
  168. BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
  169. typedef char (&type)[value];
  170. };
  171. template <class Cat>
  172. typename traversal3<Cat>::type traversal(Cat);
  173. template <class Iter, class Trav>
  174. int static_assert_traversal(Iter* = 0, Trav* = 0)
  175. {
  176. typedef typename boost::iterator_category_to_traversal<
  177. BOOST_DEDUCED_TYPENAME Iter::iterator_category
  178. >::type t2;
  179. return static_assert_same<Trav,t2>::value;
  180. }
  181. int
  182. main()
  183. {
  184. dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
  185. dummyT(3), dummyT(4), dummyT(5) };
  186. const int N = sizeof(array)/sizeof(dummyT);
  187. // sanity check, if this doesn't pass the test is buggy
  188. boost::random_access_iterator_test(array, N, array);
  189. // Test the iterator_adaptor
  190. {
  191. ptr_iterator<dummyT> i(array);
  192. boost::random_access_iterator_test(i, N, array);
  193. ptr_iterator<const dummyT> j(array);
  194. boost::random_access_iterator_test(j, N, array);
  195. boost::const_nonconst_iterator_test(i, ++j);
  196. }
  197. int test;
  198. // Test the iterator_traits
  199. {
  200. // Test computation of defaults
  201. typedef ptr_iterator<int> Iter1;
  202. // don't use std::iterator_traits here to avoid VC++ problems
  203. test = static_assert_same<Iter1::value_type, int>::value;
  204. test = static_assert_same<Iter1::reference, int&>::value;
  205. test = static_assert_same<Iter1::pointer, int*>::value;
  206. test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
  207. #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
  208. BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
  209. #endif
  210. }
  211. {
  212. // Test computation of default when the Value is const
  213. typedef ptr_iterator<int const> Iter1;
  214. test = static_assert_same<Iter1::value_type, int>::value;
  215. test = static_assert_same<Iter1::reference, const int&>::value;
  216. #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
  217. BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
  218. # ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  219. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
  220. # endif
  221. #endif
  222. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
  223. test = static_assert_same<Iter1::pointer, int const*>::value;
  224. #endif
  225. }
  226. {
  227. // Test constant iterator idiom
  228. typedef ptr_iterator<int> BaseIter;
  229. typedef constant_iterator<BaseIter> Iter;
  230. test = static_assert_same<Iter::value_type, int>::value;
  231. test = static_assert_same<Iter::reference, int const&>::value;
  232. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
  233. test = static_assert_same<Iter::pointer, int const*>::value;
  234. #endif
  235. #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  236. BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
  237. BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
  238. #endif
  239. typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
  240. static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
  241. static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
  242. }
  243. // Test the iterator_adaptor
  244. {
  245. ptr_iterator<dummyT> i(array);
  246. boost::random_access_iterator_test(i, N, array);
  247. ptr_iterator<const dummyT> j(array);
  248. boost::random_access_iterator_test(j, N, array);
  249. boost::const_nonconst_iterator_test(i, ++j);
  250. }
  251. // check operator-> with a forward iterator
  252. {
  253. boost::forward_iterator_archetype<dummyT> forward_iter;
  254. typedef fwd_iterator<dummyT> adaptor_type;
  255. adaptor_type i(forward_iter);
  256. int zero = 0;
  257. if (zero) // don't do this, just make sure it compiles
  258. BOOST_TEST((*i).m_x == i->foo());
  259. }
  260. // check operator-> with an input iterator
  261. {
  262. boost::input_iterator_archetype_no_proxy<dummyT> input_iter;
  263. typedef in_iterator<dummyT> adaptor_type;
  264. adaptor_type i(input_iter);
  265. int zero = 0;
  266. if (zero) // don't do this, just make sure it compiles
  267. BOOST_TEST((*i).m_x == i->foo());
  268. }
  269. // check that base_type is correct
  270. {
  271. // Test constant iterator idiom
  272. typedef ptr_iterator<int> BaseIter;
  273. test = static_assert_same<BaseIter::base_type,int*>::value;
  274. test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value;
  275. typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
  276. test = static_assert_same<IncrementableIter::base_type,BaseIter>::value;
  277. }
  278. std::cout << "test successful " << std::endl;
  279. (void)test;
  280. return boost::report_errors();
  281. }