iterator.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #include <string>
  7. #include <boost/static_assert.hpp>
  8. #include <boost/detail/lightweight_test.hpp>
  9. #include <boost/fusion/support/category_of.hpp>
  10. #include <boost/fusion/iterator/deref.hpp>
  11. #include <boost/fusion/iterator/next.hpp>
  12. #include <boost/fusion/iterator/prior.hpp>
  13. #include <boost/fusion/iterator/equal_to.hpp>
  14. #include <boost/fusion/iterator/distance.hpp>
  15. #include <boost/fusion/iterator/advance.hpp>
  16. #include <boost/fusion/iterator/value_of.hpp>
  17. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  18. #include <boost/fusion/sequence/intrinsic/end.hpp>
  19. #include <boost/fusion/sequence/intrinsic/at.hpp>
  20. #include <boost/fusion/sequence/intrinsic/value_at.hpp>
  21. void test()
  22. {
  23. using boost::fusion::next;
  24. using namespace boost::fusion;
  25. using namespace boost;
  26. { // Testing deref, next, prior, begin, end
  27. char const* s = "Hello";
  28. typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
  29. seq_type v(1, 'x', 3.3, s);
  30. boost::fusion::result_of::begin<seq_type>::type i(v);
  31. BOOST_TEST(*i == 1);
  32. BOOST_TEST(*next(i) == 'x');
  33. BOOST_TEST(*next(next(i)) == 3.3);
  34. BOOST_TEST(*next(next(next(i))) == s);
  35. next(next(next(next(i)))); // end
  36. #if !defined(FUSION_NO_PRIOR)
  37. BOOST_TEST(*prior(next(next(next(i)))) == 3.3);
  38. BOOST_TEST(*prior(prior(next(next(next(i))))) == 'x');
  39. BOOST_TEST(*prior(prior(prior(next(next(next(i)))))) == 1);
  40. #endif
  41. BOOST_TEST(*begin(v) == 1);
  42. #if !defined(FUSION_NO_PRIOR)
  43. BOOST_TEST(*prior(end(v)) == s);
  44. #endif
  45. *i = 3;
  46. BOOST_TEST(*i == 3);
  47. BOOST_TEST(&*i == &at_c<0>(v));
  48. // prove that it is mutable
  49. *i = 987;
  50. BOOST_TEST(*i == 987);
  51. }
  52. { // Testing const sequence and const iterator
  53. char const* s = "Hello";
  54. typedef FUSION_SEQUENCE<int, char, double, char const*> const seq_type;
  55. seq_type t(1, 'x', 3.3, s);
  56. boost::fusion::result_of::begin<seq_type>::type i(t);
  57. BOOST_TEST(*i == 1);
  58. BOOST_TEST(*next(i) == 'x');
  59. BOOST_TEST(*begin(t) == 1);
  60. #if !defined(FUSION_NO_PRIOR)
  61. BOOST_TEST(*prior(end(t)) == s);
  62. #endif
  63. #ifdef FUSION_TEST_FAIL
  64. *i = 3; // must not compile
  65. #endif
  66. }
  67. { // Testing iterator equality
  68. typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
  69. typedef FUSION_SEQUENCE<int, char, double, char const*> const cseq_type;
  70. typedef boost::fusion::result_of::begin<seq_type>::type vi1;
  71. typedef boost::fusion::result_of::begin<cseq_type>::type vi2;
  72. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi1>::value));
  73. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi1 const>::value));
  74. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi2>::value));
  75. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi2>::value));
  76. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi2 const>::value));
  77. BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi2 const>::value));
  78. }
  79. {
  80. typedef FUSION_SEQUENCE<int, int> seq_type;
  81. typedef boost::fusion::result_of::begin<seq_type>::type begin_type;
  82. typedef boost::fusion::result_of::end<seq_type>::type end_type;
  83. typedef boost::fusion::result_of::next<begin_type>::type i1;
  84. typedef boost::fusion::result_of::next<i1>::type i2;
  85. BOOST_STATIC_ASSERT((is_same<end_type, i2>::value));
  86. }
  87. { // testing deref, next, prior, begin, end
  88. char const* s = "Hello";
  89. typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
  90. seq_type t(1, 'x', 3.3, s);
  91. boost::fusion::result_of::begin<seq_type>::type i(t);
  92. BOOST_TEST(*i == 1);
  93. BOOST_TEST(*next(i) == 'x');
  94. BOOST_TEST(*next(next(i)) == 3.3);
  95. BOOST_TEST(*next(next(next(i))) == s);
  96. next(next(next(next(i)))); // end
  97. #ifdef FUSION_TEST_FAIL
  98. next(next(next(next(next(i))))); // past the end: must not compile
  99. #endif
  100. #if !defined(FUSION_NO_PRIOR)
  101. BOOST_TEST(*prior(next(next(next(i)))) == 3.3);
  102. BOOST_TEST(*prior(prior(next(next(next(i))))) == 'x');
  103. BOOST_TEST(*prior(prior(prior(next(next(next(i)))))) == 1);
  104. #endif
  105. BOOST_TEST(*begin(t) == 1);
  106. #if !defined(FUSION_NO_PRIOR)
  107. BOOST_TEST(*prior(end(t)) == s);
  108. #endif
  109. *i = 3;
  110. BOOST_TEST(*i == 3);
  111. BOOST_TEST(*i == at_c<0>(t));
  112. }
  113. { // Testing distance
  114. typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
  115. seq_type t(1, 'x', 3.3, "Hello");
  116. BOOST_STATIC_ASSERT((boost::fusion::result_of::distance<
  117. boost::fusion::result_of::begin<seq_type>::type
  118. , boost::fusion::result_of::end<seq_type>::type >::value == 4));
  119. BOOST_TEST(distance(begin(t), end(t)).value == 4);
  120. }
  121. { // Testing tuple iterator boost::fusion::result_of::value_of, boost::fusion::result_of::deref, boost::fusion::result_of::value_at
  122. typedef FUSION_SEQUENCE<int, char&> seq_type;
  123. typedef boost::fusion::result_of::begin<seq_type>::type i0;
  124. typedef boost::fusion::result_of::next<i0>::type i1;
  125. typedef boost::fusion::result_of::next<boost::fusion::result_of::begin<const seq_type>::type>::type i2;
  126. BOOST_STATIC_ASSERT((
  127. is_same<boost::fusion::result_of::value_at_c<seq_type, 0>::type, int>::value));
  128. BOOST_STATIC_ASSERT((
  129. is_same<boost::fusion::result_of::value_at_c<seq_type, 1>::type, char&>::value));
  130. BOOST_STATIC_ASSERT((
  131. is_same<traits::category_of<i0>::type, FUSION_TRAVERSAL_TAG>::value));
  132. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i0>::type, int&>::value));
  133. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i1>::type, char&>::value));
  134. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i2>::type, char&>::value));
  135. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i0>::type, int>::value));
  136. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i1>::type, char&>::value));
  137. BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i2>::type, char&>::value));
  138. }
  139. { // Testing advance
  140. typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
  141. seq_type t(1, 'x', 3.3, "Hello");
  142. BOOST_TEST(*advance_c<0>(begin(t)) == at_c<0>(t));
  143. BOOST_TEST(*advance_c<1>(begin(t)) == at_c<1>(t));
  144. BOOST_TEST(*advance_c<2>(begin(t)) == at_c<2>(t));
  145. BOOST_TEST(*advance_c<3>(begin(t)) == at_c<3>(t));
  146. #if !defined(FUSION_NO_PRIOR)
  147. BOOST_TEST(*advance_c<-1>(end(t)) == at_c<3>(t));
  148. BOOST_TEST(*advance_c<-2>(end(t)) == at_c<2>(t));
  149. BOOST_TEST(*advance_c<-3>(end(t)) == at_c<1>(t));
  150. BOOST_TEST(*advance_c<-4>(end(t)) == at_c<0>(t));
  151. #endif
  152. BOOST_TEST(&*advance_c<0>(begin(t)) == &at_c<0>(t));
  153. BOOST_TEST(&*advance_c<1>(begin(t)) == &at_c<1>(t));
  154. BOOST_TEST(&*advance_c<2>(begin(t)) == &at_c<2>(t));
  155. BOOST_TEST(&*advance_c<3>(begin(t)) == &at_c<3>(t));
  156. }
  157. }