misc.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*=============================================================================
  2. Copyright (C) 1999-2003 Jaakko Jarvi
  3. Copyright (c) 2001-2011 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #include <boost/detail/lightweight_test.hpp>
  8. #include <boost/fusion/sequence/intrinsic.hpp>
  9. #include <boost/fusion/support/is_sequence.hpp>
  10. #include <boost/fusion/mpl.hpp>
  11. #include <boost/mpl/find.hpp>
  12. #include <boost/mpl/equal.hpp>
  13. #include <boost/mpl/int.hpp>
  14. #include <boost/mpl/integral_c.hpp>
  15. #include <boost/mpl/is_sequence.hpp>
  16. #include <boost/type_traits/is_same.hpp>
  17. #include <string>
  18. #if !defined(FUSION_AT)
  19. #define FUSION_AT at_c
  20. #endif
  21. #if !defined(FUSION_SIZE)
  22. #define FUSION_SIZE boost::fusion::result_of::size
  23. #endif
  24. template <typename S1, typename S2>
  25. struct is_same
  26. {
  27. };
  28. struct test_intrinsics1
  29. {
  30. // test at, begin, end, next, prior, advance, size, deref, etc.
  31. typedef boost::fusion::FUSION_SEQUENCE<int, float, bool, char> sequence;
  32. typedef boost::mpl::begin<sequence>::type first;
  33. typedef boost::mpl::next<first>::type second;
  34. typedef boost::mpl::next<second>::type third;
  35. typedef boost::mpl::next<third>::type fourth;
  36. typedef boost::mpl::end<sequence>::type last;
  37. BOOST_STATIC_ASSERT((boost::is_same<
  38. boost::mpl::deref<first>::type, int>::value));
  39. BOOST_STATIC_ASSERT((boost::is_same<
  40. boost::mpl::deref<second>::type, float>::value));
  41. BOOST_STATIC_ASSERT((boost::is_same<
  42. boost::mpl::deref<third>::type, bool>::value));
  43. BOOST_STATIC_ASSERT((boost::is_same<
  44. boost::mpl::deref<fourth>::type, char>::value));
  45. BOOST_STATIC_ASSERT((boost::is_same<
  46. boost::mpl::at_c<sequence, 2>::type, bool>::value));
  47. BOOST_STATIC_ASSERT((boost::is_same<
  48. boost::mpl::front<sequence>::type, int>::value));
  49. BOOST_STATIC_ASSERT((boost::is_same<
  50. boost::mpl::deref<
  51. boost::mpl::advance_c<second, 2>::type>::type, char>::value));
  52. BOOST_STATIC_ASSERT((boost::mpl::size<sequence>::value == 4));
  53. BOOST_STATIC_ASSERT(!(boost::mpl::empty<sequence>::value));
  54. BOOST_STATIC_ASSERT((boost::mpl::distance<second, fourth>::value == 2));
  55. #if !defined(FUSION_FORWARD_ONLY) // list has no back/prev
  56. typedef boost::mpl::prior<last>::type fourth_;
  57. typedef boost::mpl::prior<fourth_>::type third_;
  58. typedef boost::mpl::prior<third_>::type second_;
  59. typedef boost::mpl::prior<second_>::type first_;
  60. BOOST_STATIC_ASSERT((boost::is_same<
  61. boost::mpl::deref<first_>::type, int>::value));
  62. BOOST_STATIC_ASSERT((boost::is_same<
  63. boost::mpl::deref<second_>::type, float>::value));
  64. BOOST_STATIC_ASSERT((boost::is_same<
  65. boost::mpl::deref<third_>::type, bool>::value));
  66. BOOST_STATIC_ASSERT((boost::is_same<
  67. boost::mpl::deref<fourth_>::type, char>::value));
  68. BOOST_STATIC_ASSERT((boost::is_same<
  69. boost::mpl::back<sequence>::type, char>::value));
  70. #endif
  71. };
  72. struct test_intrinsics2
  73. {
  74. typedef boost::fusion::FUSION_SEQUENCE<> seq0;
  75. #if !defined(BOOST_FUSION_SEQUENCE_CONVERSION_IS_NOT_SEQUENCE__TYPE_PRESERVING)
  76. #if !defined(FUSION_FORWARD_ONLY) // list has no back/prev
  77. typedef boost::fusion::FUSION_SEQUENCE<int> target1;
  78. typedef boost::mpl::push_back<seq0, int>::type seq1;
  79. BOOST_STATIC_ASSERT((boost::mpl::equal<seq1, target1>::value));
  80. typedef boost::fusion::FUSION_SEQUENCE<int, double> target2;
  81. typedef boost::mpl::push_back<seq1, double>::type seq2;
  82. BOOST_STATIC_ASSERT((boost::mpl::equal<seq2, target2>::value));
  83. #endif
  84. typedef boost::fusion::FUSION_SEQUENCE<int> target3;
  85. typedef boost::mpl::push_front<seq0, int>::type seq3;
  86. BOOST_STATIC_ASSERT((boost::mpl::equal<seq3, target3>::value));
  87. typedef boost::fusion::FUSION_SEQUENCE<double, int> target4;
  88. typedef boost::mpl::push_front<seq3, double>::type seq4;
  89. BOOST_STATIC_ASSERT((boost::mpl::equal<seq4, target4>::value));
  90. #endif
  91. };
  92. void
  93. test()
  94. {
  95. using namespace boost::fusion;
  96. { // testing const sequences
  97. const FUSION_SEQUENCE<int, float> t1(5, 3.3f);
  98. BOOST_TEST(FUSION_AT<0>(t1) == 5);
  99. BOOST_TEST(FUSION_AT<1>(t1) == 3.3f);
  100. }
  101. { // testing at<N> works with MPL integral constants
  102. const FUSION_SEQUENCE<int, char> t1(101, 'z');
  103. BOOST_TEST(boost::fusion::at<boost::mpl::int_<0> >(t1) == 101);
  104. BOOST_TEST(boost::fusion::at<boost::mpl::int_<1> >(t1) == 'z');
  105. // explicitly try something other than mpl::int_
  106. BOOST_TEST((boost::fusion::at<boost::mpl::integral_c<long, 0> >(t1) == 101));
  107. BOOST_TEST((boost::fusion::at<boost::mpl::integral_c<long, 1> >(t1) == 'z'));
  108. }
  109. { // testing size & empty
  110. typedef FUSION_SEQUENCE<int, float, double> t1;
  111. typedef FUSION_SEQUENCE<> t2;
  112. BOOST_STATIC_ASSERT(FUSION_SIZE<t1>::value == 3);
  113. BOOST_STATIC_ASSERT(FUSION_SIZE<t2>::value == 0);
  114. BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<t1>::value);
  115. BOOST_STATIC_ASSERT(boost::fusion::result_of::empty<t2>::value);
  116. }
  117. { // testing front & back
  118. typedef FUSION_SEQUENCE<int, float, std::string> tup;
  119. tup t(1, 2.2f, "Kimpo");
  120. BOOST_TEST(front(t) == 1);
  121. #if !defined(FUSION_FORWARD_ONLY) // list has no back
  122. BOOST_TEST(back(t) == "Kimpo");
  123. #endif
  124. }
  125. { // testing is_sequence
  126. typedef FUSION_SEQUENCE<int, float, double> t1;
  127. typedef FUSION_SEQUENCE<> t2;
  128. typedef FUSION_SEQUENCE<char> t3;
  129. BOOST_STATIC_ASSERT(traits::is_sequence<t1>::value);
  130. BOOST_STATIC_ASSERT(traits::is_sequence<t2>::value);
  131. BOOST_STATIC_ASSERT(traits::is_sequence<t3>::value);
  132. BOOST_STATIC_ASSERT(!traits::is_sequence<int>::value);
  133. BOOST_STATIC_ASSERT(!traits::is_sequence<char>::value);
  134. }
  135. { // testing mpl::is_sequence
  136. typedef FUSION_SEQUENCE<int, float, double> t1;
  137. typedef FUSION_SEQUENCE<> t2;
  138. typedef FUSION_SEQUENCE<char> t3;
  139. BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t1>::value);
  140. BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t2>::value);
  141. BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t3>::value);
  142. }
  143. { // testing mpl compatibility
  144. // test begin, end, next, prior, advance, size, deref, etc.
  145. //~ typedef FUSION_SEQUENCE<int, float, bool, char> tuple_type;
  146. //~ test_intrinsics1<tuple_type> test1;
  147. //~ (void)test1; // prevent unused variable warning
  148. // test an algorithm
  149. typedef FUSION_SEQUENCE<int, float, double> t1;
  150. typedef boost::mpl::find<t1, float>::type iter;
  151. typedef boost::mpl::deref<iter>::type type;
  152. BOOST_STATIC_ASSERT((boost::is_same<type, float>::value));
  153. }
  154. }