filter_iterator_test.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright David Abrahams 2003, Jeremy Siek 2004.
  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. #include <boost/iterator/filter_iterator.hpp>
  6. #include <boost/iterator/reverse_iterator.hpp>
  7. #include <boost/iterator/new_iterator_tests.hpp>
  8. #include <boost/type_traits/is_convertible.hpp>
  9. #include <boost/concept_check.hpp>
  10. #include <boost/concept_archetype.hpp>
  11. #include <boost/iterator/iterator_concepts.hpp>
  12. #include <boost/iterator/iterator_archetypes.hpp>
  13. #include <boost/cstdlib.hpp>
  14. #include <deque>
  15. #include <iostream>
  16. using boost::dummyT;
  17. struct one_or_four
  18. {
  19. bool operator()(dummyT x) const
  20. {
  21. return x.foo() == 1 || x.foo() == 4;
  22. }
  23. };
  24. template <class T> struct undefined;
  25. template <class T> struct see_type;
  26. // Test filter iterator
  27. int main()
  28. {
  29. // Concept checks
  30. // Adapting old-style iterators
  31. {
  32. typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter;
  33. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  34. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  35. boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
  36. }
  37. {
  38. typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter;
  39. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  40. boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
  41. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  42. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  43. boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
  44. }
  45. {
  46. typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter;
  47. boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
  48. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  49. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  50. }
  51. {
  52. typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter;
  53. boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
  54. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  55. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  56. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  57. }
  58. {
  59. typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter;
  60. boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
  61. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  62. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  63. }
  64. {
  65. typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
  66. boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
  67. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  68. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  69. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  70. }
  71. {
  72. typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter;
  73. boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
  74. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  75. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  76. }
  77. {
  78. typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter;
  79. boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
  80. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  81. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  82. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  83. }
  84. // Adapting new-style iterators
  85. {
  86. typedef boost::iterator_archetype<
  87. const dummyT
  88. , boost::iterator_archetypes::readable_iterator_t
  89. , boost::single_pass_traversal_tag
  90. > BaseIter;
  91. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  92. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  93. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  94. boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
  95. }
  96. #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
  97. {
  98. typedef boost::iterator_archetype<
  99. dummyT
  100. , boost::iterator_archetypes::readable_writable_iterator_t
  101. , boost::single_pass_traversal_tag
  102. > BaseIter;
  103. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  104. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  105. boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
  106. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  107. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  108. boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
  109. }
  110. #endif
  111. {
  112. typedef boost::iterator_archetype<
  113. const dummyT
  114. , boost::iterator_archetypes::readable_iterator_t
  115. , boost::forward_traversal_tag
  116. > BaseIter;
  117. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  118. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  119. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  120. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  121. }
  122. #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
  123. {
  124. typedef boost::iterator_archetype<
  125. dummyT
  126. , boost::iterator_archetypes::readable_writable_iterator_t
  127. , boost::forward_traversal_tag
  128. > BaseIter;
  129. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  130. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  131. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  132. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  133. }
  134. {
  135. typedef boost::iterator_archetype<
  136. const dummyT
  137. , boost::iterator_archetypes::readable_lvalue_iterator_t
  138. , boost::forward_traversal_tag
  139. > BaseIter;
  140. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  141. boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
  142. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  143. boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
  144. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  145. }
  146. {
  147. typedef boost::iterator_archetype<
  148. dummyT
  149. , boost::iterator_archetypes::writable_lvalue_iterator_t
  150. , boost::forward_traversal_tag
  151. > BaseIter;
  152. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  153. boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
  154. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  155. boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
  156. boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
  157. }
  158. #endif
  159. {
  160. typedef boost::iterator_archetype<
  161. const dummyT
  162. , boost::iterator_archetypes::readable_iterator_t
  163. , boost::random_access_traversal_tag
  164. > BaseIter;
  165. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  166. boost::function_requires< boost::InputIteratorConcept<Iter> >();
  167. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  168. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  169. }
  170. #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
  171. {
  172. typedef boost::iterator_archetype<
  173. dummyT
  174. , boost::iterator_archetypes::readable_writable_iterator_t
  175. , boost::random_access_traversal_tag
  176. > BaseIter;
  177. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  178. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  179. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  180. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  181. }
  182. {
  183. typedef boost::iterator_archetype<
  184. const dummyT
  185. , boost::iterator_archetypes::readable_lvalue_iterator_t
  186. , boost::random_access_traversal_tag
  187. > BaseIter;
  188. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  189. boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
  190. boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
  191. boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
  192. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  193. }
  194. {
  195. typedef boost::iterator_archetype<
  196. dummyT
  197. , boost::iterator_archetypes::writable_lvalue_iterator_t
  198. , boost::random_access_traversal_tag
  199. > BaseIter;
  200. typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
  201. boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
  202. boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
  203. boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
  204. boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
  205. }
  206. #endif
  207. // Run-time tests
  208. dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
  209. dummyT(3), dummyT(4), dummyT(5) };
  210. const int N = sizeof(array)/sizeof(dummyT);
  211. typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter;
  212. boost::bidirectional_readable_iterator_test(
  213. filter_iter(one_or_four(), array, array+N)
  214. , dummyT(1), dummyT(4));
  215. BOOST_STATIC_ASSERT(
  216. (!boost::is_convertible<
  217. boost::iterator_traversal<filter_iter>::type
  218. , boost::random_access_traversal_tag
  219. >::value
  220. ));
  221. //# endif
  222. // On compilers not supporting partial specialization, we can do more type
  223. // deduction with deque iterators than with pointers... unless the library
  224. // is broken ;-(
  225. std::deque<dummyT> array2;
  226. std::copy(array+0, array+N, std::back_inserter(array2));
  227. boost::bidirectional_readable_iterator_test(
  228. boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
  229. dummyT(1), dummyT(4));
  230. boost::bidirectional_readable_iterator_test(
  231. boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
  232. dummyT(1), dummyT(4));
  233. boost::bidirectional_readable_iterator_test(
  234. boost::make_filter_iterator(
  235. one_or_four()
  236. , boost::make_reverse_iterator(array2.end())
  237. , boost::make_reverse_iterator(array2.begin())
  238. ),
  239. dummyT(4), dummyT(1));
  240. boost::bidirectional_readable_iterator_test(
  241. filter_iter(array+0, array+N),
  242. dummyT(1), dummyT(4));
  243. boost::bidirectional_readable_iterator_test(
  244. filter_iter(one_or_four(), array, array + N),
  245. dummyT(1), dummyT(4));
  246. return boost::report_errors();
  247. }