tuple_for_each.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*=============================================================================
  2. Copyright (c) 2017 Paul Fultz II
  3. tuple_for_each.cpp
  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/hof/unpack.hpp>
  8. #include <boost/hof/proj.hpp>
  9. #include <boost/hof/function.hpp>
  10. #include <boost/hof/reveal.hpp>
  11. #include "test.hpp"
  12. struct tuple_for_each_f
  13. {
  14. template<class Sequence, class F>
  15. constexpr auto operator()(Sequence&& s, F && f) const BOOST_HOF_RETURNS
  16. (
  17. boost::hof::unpack(boost::hof::proj(boost::hof::forward<F>(f)))(boost::hof::forward<Sequence>(s)), boost::hof::forward<F>(f)
  18. );
  19. };
  20. BOOST_HOF_STATIC_FUNCTION(tuple_for_each) = tuple_for_each_f{};
  21. BOOST_HOF_TEST_CASE()
  22. {
  23. std::tuple<int, short, char> tp{ 1, 2, 3 };
  24. {
  25. int s = 0;
  26. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  27. BOOST_HOF_TEST_CHECK( s == 123 );
  28. }
  29. {
  30. int s = 0;
  31. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  32. BOOST_HOF_TEST_CHECK( s == 123 );
  33. }
  34. }
  35. BOOST_HOF_TEST_CASE()
  36. {
  37. std::tuple<int, short, char> const tp{ 1, 2, 3 };
  38. {
  39. int s = 0;
  40. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  41. BOOST_HOF_TEST_CHECK( s == 123 );
  42. }
  43. {
  44. int s = 0;
  45. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  46. BOOST_HOF_TEST_CHECK( s == 123 );
  47. }
  48. }
  49. // #if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 8
  50. // #else
  51. BOOST_HOF_TEST_CASE()
  52. {
  53. std::tuple<std::unique_ptr<int>, std::unique_ptr<int>, std::unique_ptr<int>> tp{ std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)), std::unique_ptr<int>(new int(3)) };
  54. int s = 0;
  55. tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } );
  56. BOOST_HOF_TEST_CHECK( s == 123 );
  57. }
  58. BOOST_HOF_TEST_CASE()
  59. {
  60. auto tp = boost::hof::pack(1, 2, 3);
  61. {
  62. int s = 0;
  63. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  64. BOOST_HOF_TEST_CHECK( s == 123 );
  65. }
  66. {
  67. int s = 0;
  68. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  69. BOOST_HOF_TEST_CHECK( s == 123 );
  70. }
  71. }
  72. BOOST_HOF_TEST_CASE()
  73. {
  74. const auto tp = boost::hof::pack(1, 2, 3);
  75. {
  76. int s = 0;
  77. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  78. BOOST_HOF_TEST_CHECK( s == 123 );
  79. }
  80. {
  81. int s = 0;
  82. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  83. BOOST_HOF_TEST_CHECK( s == 123 );
  84. }
  85. }
  86. // #endif
  87. BOOST_HOF_TEST_CASE()
  88. {
  89. std::pair<int, short> tp{ 1, 2 };
  90. {
  91. int s = 0;
  92. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  93. BOOST_HOF_TEST_CHECK( s == 12 );
  94. }
  95. {
  96. int s = 0;
  97. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  98. BOOST_HOF_TEST_CHECK( s == 12 );
  99. }
  100. }
  101. BOOST_HOF_TEST_CASE()
  102. {
  103. std::pair<int, short> const tp{ 1, 2 };
  104. {
  105. int s = 0;
  106. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  107. BOOST_HOF_TEST_CHECK( s == 12 );
  108. }
  109. {
  110. int s = 0;
  111. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  112. BOOST_HOF_TEST_CHECK( s == 12 );
  113. }
  114. }
  115. BOOST_HOF_TEST_CASE()
  116. {
  117. std::array<int, 3> tp{{ 1, 2, 3 }};
  118. {
  119. int s = 0;
  120. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  121. BOOST_HOF_TEST_CHECK( s == 123 );
  122. }
  123. {
  124. int s = 0;
  125. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  126. BOOST_HOF_TEST_CHECK( s == 123 );
  127. }
  128. }
  129. BOOST_HOF_TEST_CASE()
  130. {
  131. std::array<int, 3> const tp{{ 1, 2, 3 }};
  132. {
  133. int s = 0;
  134. tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
  135. BOOST_HOF_TEST_CHECK( s == 123 );
  136. }
  137. {
  138. int s = 0;
  139. tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
  140. BOOST_HOF_TEST_CHECK( s == 123 );
  141. }
  142. }
  143. BOOST_HOF_TEST_CASE()
  144. {
  145. std::tuple<> tp;
  146. BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
  147. BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
  148. }
  149. BOOST_HOF_TEST_CASE()
  150. {
  151. BOOST_HOF_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
  152. BOOST_HOF_STATIC_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 );
  153. }
  154. BOOST_HOF_TEST_CASE()
  155. {
  156. std::array<int, 0> tp;
  157. BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 );
  158. BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 );
  159. }
  160. struct assert_is_integral
  161. {
  162. template<class T> constexpr bool operator()( T ) const
  163. {
  164. BOOST_HOF_STATIC_TEST_CHECK( std::is_integral<T>::value );
  165. return true;
  166. }
  167. };
  168. BOOST_HOF_TEST_CASE()
  169. {
  170. #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
  171. auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
  172. #else
  173. constexpr auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() );
  174. #endif
  175. (void)r;
  176. }
  177. BOOST_HOF_TEST_CASE()
  178. {
  179. #if !BOOST_HOF_HAS_CONSTEXPR_TUPLE
  180. auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
  181. #else
  182. constexpr auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() );
  183. #endif
  184. (void)r;
  185. }