test_iterators.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* Copyright 2016-2018 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/poly_collection for library home page.
  7. */
  8. #include "test_iterators.hpp"
  9. #include <boost/core/lightweight_test.hpp>
  10. #include <iterator>
  11. #include <type_traits>
  12. #include "any_types.hpp"
  13. #include "base_types.hpp"
  14. #include "function_types.hpp"
  15. #include "test_utilities.hpp"
  16. using namespace test_utilities;
  17. template<typename Iterator>
  18. using is_input=std::is_base_of<
  19. std::input_iterator_tag,
  20. typename std::iterator_traits<Iterator>::iterator_category
  21. >;
  22. template<typename Iterator>
  23. using is_forward=std::is_base_of<
  24. std::forward_iterator_tag,
  25. typename std::iterator_traits<Iterator>::iterator_category
  26. >;
  27. template<typename Iterator>
  28. using is_random_access=std::is_base_of<
  29. std::random_access_iterator_tag,
  30. typename std::iterator_traits<Iterator>::iterator_category
  31. >;
  32. template<typename Type,typename PolyCollection>
  33. void test_iterators(PolyCollection& p)
  34. {
  35. using local_base_iterator=typename PolyCollection::local_base_iterator;
  36. using const_local_base_iterator=
  37. typename PolyCollection::const_local_base_iterator;
  38. using local_iterator=typename PolyCollection::template local_iterator<Type>;
  39. using const_local_iterator=
  40. typename PolyCollection::template const_local_iterator<Type>;
  41. using base_segment_info=typename PolyCollection::base_segment_info;
  42. using const_base_segment_info=
  43. typename PolyCollection::const_base_segment_info;
  44. using const_segment_info=
  45. typename PolyCollection::template const_segment_info<Type>;
  46. using segment_info=typename PolyCollection::template segment_info<Type>;
  47. static_assert(is_random_access<local_iterator>::value,
  48. "local_iterator must be random access");
  49. static_assert(is_random_access<const_local_iterator>::value,
  50. "const_local_iterator must be random access");
  51. static_assert(std::is_base_of<const_segment_info,segment_info>::value,
  52. "segment_info must derive from const_segment_info");
  53. {
  54. local_iterator lit,lit2;
  55. const_local_iterator clit,clit2(lit); /* sorry about the names */
  56. lit=lit2;
  57. clit=clit2;
  58. clit=lit;
  59. }
  60. const PolyCollection& cp=p;
  61. std::size_t n=0;
  62. local_base_iterator lbfirst=p.begin(typeid(Type)),
  63. lblast=p.end(typeid(Type));
  64. const_local_base_iterator clbfirst=cp.begin(typeid(Type)),
  65. clblast=cp.end(typeid(Type));
  66. local_iterator lfirst=p.template begin<Type>(),
  67. llast=p.template end<Type>();
  68. const_local_iterator clfirst=cp.template begin<Type>(),
  69. cllast=cp.template end<Type>();
  70. base_segment_info bi=p.segment(typeid(Type));
  71. const_base_segment_info cbi=cp.segment(typeid(Type));
  72. segment_info i=p.template segment<Type>();
  73. const_segment_info ci=cp.template segment<Type>();
  74. BOOST_TEST(clbfirst==cp.cbegin(typeid(Type)));
  75. BOOST_TEST(clblast==cp.cend(typeid(Type)));
  76. BOOST_TEST(clfirst==cp.template cbegin<Type>());
  77. BOOST_TEST(cllast==cp.template cend<Type>());
  78. BOOST_TEST(lbfirst==bi.begin());
  79. BOOST_TEST(lblast==bi.end());
  80. BOOST_TEST(clbfirst==bi.cbegin());
  81. BOOST_TEST(clbfirst==cbi.begin());
  82. BOOST_TEST(clblast==bi.cend());
  83. BOOST_TEST(clblast==cbi.end());
  84. BOOST_TEST(lfirst==i.begin());
  85. BOOST_TEST(llast==i.end());
  86. BOOST_TEST(clfirst==i.cbegin());
  87. BOOST_TEST(clfirst==ci.begin());
  88. BOOST_TEST(cllast==i.cend());
  89. BOOST_TEST(cllast==ci.end());
  90. for(;lbfirst!=lblast;++lbfirst,++clbfirst,++lfirst,++clfirst){
  91. BOOST_TEST(lfirst==static_cast<local_iterator>(lbfirst));
  92. BOOST_TEST(static_cast<local_base_iterator>(lfirst)==lbfirst);
  93. BOOST_TEST(clfirst==static_cast<const_local_iterator>(clbfirst));
  94. BOOST_TEST(static_cast<const_local_base_iterator>(clfirst)==clbfirst);
  95. BOOST_TEST(clfirst==lfirst);
  96. BOOST_TEST(&*lfirst==&*static_cast<local_iterator>(lbfirst));
  97. BOOST_TEST(&*clfirst==&*static_cast<const_local_iterator>(clbfirst));
  98. BOOST_TEST(&*clfirst==&*lfirst);
  99. Type& r=p.template begin<Type>()[n];
  100. const Type& cr=cp.template begin<Type>()[n];
  101. BOOST_TEST(&*lfirst==&r);
  102. BOOST_TEST(&*clfirst==&cr);
  103. ++n;
  104. }
  105. BOOST_TEST(clbfirst==clblast);
  106. BOOST_TEST(lfirst==llast);
  107. BOOST_TEST(clfirst==cllast);
  108. BOOST_TEST(lfirst==static_cast<local_iterator>(llast));
  109. BOOST_TEST(clfirst==static_cast<const_local_iterator>(cllast));
  110. BOOST_TEST(clfirst==llast);
  111. BOOST_TEST((std::ptrdiff_t)n==p.end(typeid(Type))-p.begin(typeid(Type)));
  112. BOOST_TEST(
  113. (std::ptrdiff_t)n==p.template end<Type>()-p.template begin<Type>());
  114. for(auto s:p.segment_traversal()){
  115. if(s.type_info()==typeid(Type)){
  116. const auto& cs=s;
  117. BOOST_TEST(
  118. s.template begin<Type>()==
  119. static_cast<local_iterator>(s.begin()));
  120. BOOST_TEST(
  121. s.template end<Type>()==
  122. static_cast<local_iterator>(s.end()));
  123. BOOST_TEST(
  124. cs.template begin<Type>()==
  125. static_cast<const_local_iterator>(cs.begin()));
  126. BOOST_TEST(
  127. cs.template end<Type>()==
  128. static_cast<const_local_iterator>(cs.end()));
  129. BOOST_TEST(
  130. cs.template cbegin<Type>()==
  131. static_cast<const_local_iterator>(cs.cbegin()));
  132. BOOST_TEST(
  133. cs.template cend<Type>()==
  134. static_cast<const_local_iterator>(cs.cend()));
  135. }
  136. }
  137. }
  138. template<typename PolyCollection,typename ValueFactory,typename... Types>
  139. void test_iterators()
  140. {
  141. using value_type=typename PolyCollection::value_type;
  142. using iterator=typename PolyCollection::iterator;
  143. using const_iterator=typename PolyCollection::const_iterator;
  144. using local_base_iterator=typename PolyCollection::local_base_iterator;
  145. using const_local_base_iterator=
  146. typename PolyCollection::const_local_base_iterator;
  147. using const_base_segment_info=
  148. typename PolyCollection::const_base_segment_info;
  149. using base_segment_info=typename PolyCollection::base_segment_info;
  150. using base_segment_info_iterator=
  151. typename PolyCollection::base_segment_info_iterator;
  152. using const_base_segment_info_iterator=
  153. typename PolyCollection::const_base_segment_info_iterator;
  154. using const_segment_traversal_info=
  155. typename PolyCollection::const_segment_traversal_info;
  156. using segment_traversal_info=
  157. typename PolyCollection::segment_traversal_info;
  158. static_assert(is_forward<iterator>::value,
  159. "iterator must be forward");
  160. static_assert(is_forward<const_iterator>::value,
  161. "const_iterator must be forward");
  162. static_assert(is_random_access<local_base_iterator>::value,
  163. "local_base_iterator must be random access");
  164. static_assert(is_random_access<const_local_base_iterator>::value,
  165. "const_local_base_iterator must be random access");
  166. static_assert(std::is_base_of<
  167. const_base_segment_info,base_segment_info>::value,
  168. "base_segment_info must derive from const_base_segment_info");
  169. static_assert(is_input<base_segment_info_iterator>::value,
  170. "base_segment_info_iterator must be input");
  171. static_assert(is_input<const_base_segment_info_iterator>::value,
  172. "const_base_segment_info_iterator must be input");
  173. static_assert(std::is_base_of<
  174. const_segment_traversal_info,segment_traversal_info>::value,
  175. "const_segment_traversal_info must derive "\
  176. "from segment_traversal_info");
  177. {
  178. iterator it,it2;
  179. const_iterator cit,cit2(it);
  180. local_base_iterator lbit,lbit2;
  181. const_local_base_iterator clbit,clbit2(lbit);
  182. base_segment_info_iterator sit,sit2;
  183. const_base_segment_info_iterator csit,csit2(csit);
  184. it=it2;
  185. cit=cit2;
  186. cit=it;
  187. lbit=lbit2;
  188. clbit=clbit2;
  189. clbit=lbit;
  190. sit=sit2;
  191. csit=csit2;
  192. csit=sit;
  193. }
  194. PolyCollection p;
  195. const PolyCollection& cp=p;
  196. ValueFactory v;
  197. fill<constraints<>,Types...>(p,v,2);
  198. {
  199. std::size_t n=0;
  200. iterator first=p.begin(),last=p.end();
  201. const_iterator cfirst=cp.begin(),clast=cp.end();
  202. BOOST_TEST(cfirst==cp.cbegin());
  203. BOOST_TEST(clast==cp.cend());
  204. for(;first!=last;++first,++cfirst){
  205. BOOST_TEST(first==cfirst);
  206. BOOST_TEST(&*first==&*cfirst);
  207. ++n;
  208. }
  209. BOOST_TEST(cfirst==clast);
  210. BOOST_TEST(last==clast);
  211. BOOST_TEST(n==p.size());
  212. }
  213. {
  214. std::size_t n=0;
  215. base_segment_info_iterator first=p.segment_traversal().begin(),
  216. last=p.segment_traversal().end();
  217. const_base_segment_info_iterator cfirst=cp.segment_traversal().begin(),
  218. clast=cp.segment_traversal().end();
  219. BOOST_TEST(cfirst==cp.segment_traversal().cbegin());
  220. BOOST_TEST(clast==cp.segment_traversal().cend());
  221. for(;first!=last;++first,++cfirst){
  222. BOOST_TEST(first==cfirst);
  223. std::size_t m=0;
  224. local_base_iterator lbfirst=first->begin(),lblast=first->end();
  225. const_local_base_iterator clbfirst=cfirst->begin(),clblast=cfirst->end();
  226. BOOST_TEST(clbfirst==cfirst->cbegin());
  227. BOOST_TEST(clblast==cfirst->cend());
  228. BOOST_TEST(lbfirst==p.begin(first->type_info()));
  229. BOOST_TEST(lblast==p.end(first->type_info()));
  230. BOOST_TEST(clbfirst==cp.begin(first->type_info()));
  231. BOOST_TEST(clblast==cp.end(first->type_info()));
  232. BOOST_TEST(clbfirst==cp.cbegin(first->type_info()));
  233. BOOST_TEST(clblast==cp.cend(first->type_info()));
  234. for(;lbfirst!=lblast;++lbfirst,++clbfirst){
  235. BOOST_TEST(lbfirst==clbfirst);
  236. BOOST_TEST(&*lbfirst==&*clbfirst);
  237. value_type& r=first->begin()[m];
  238. const value_type& cr=cfirst->begin()[m];
  239. BOOST_TEST(&*lbfirst==&r);
  240. BOOST_TEST(&*clbfirst==&cr);
  241. ++m;
  242. }
  243. BOOST_TEST(clbfirst==clblast);
  244. BOOST_TEST(lblast==clblast);
  245. BOOST_TEST((std::ptrdiff_t)m==first->end()-first->begin());
  246. BOOST_TEST((std::ptrdiff_t)m==cfirst->end()-cfirst->begin());
  247. BOOST_TEST((std::ptrdiff_t)m==cfirst->cend()-cfirst->cbegin());
  248. n+=m;
  249. }
  250. BOOST_TEST(cfirst==clast);
  251. BOOST_TEST(last==clast);
  252. BOOST_TEST(n==p.size());
  253. }
  254. do_((test_iterators<Types>(p),0)...);
  255. }
  256. void test_iterators()
  257. {
  258. test_iterators<
  259. any_types::collection,auto_increment,
  260. any_types::t1,any_types::t2,any_types::t3,
  261. any_types::t4,any_types::t5>();
  262. test_iterators<
  263. base_types::collection,auto_increment,
  264. base_types::t1,base_types::t2,base_types::t3,
  265. base_types::t4,base_types::t5>();
  266. test_iterators<
  267. function_types::collection,auto_increment,
  268. function_types::t1,function_types::t2,function_types::t3,
  269. function_types::t4,function_types::t5>();
  270. }