value.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright (C) 2016-2018 T. Zachary Laine
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/yap/expression.hpp>
  7. #include <boost/mpl/assert.hpp>
  8. #include <boost/test/minimal.hpp>
  9. template<typename T>
  10. using term = boost::yap::terminal<boost::yap::expression, T>;
  11. template<typename T>
  12. using ref = boost::yap::expression_ref<boost::yap::expression, T>;
  13. namespace yap = boost::yap;
  14. namespace bh = boost::hana;
  15. template<boost::yap::expr_kind Kind, typename Tuple>
  16. struct user_expr
  17. {
  18. static boost::yap::expr_kind const kind = Kind;
  19. Tuple elements;
  20. };
  21. BOOST_YAP_USER_BINARY_OPERATOR(plus, user_expr, user_expr)
  22. template<typename T>
  23. using user_term = boost::yap::terminal<user_expr, T>;
  24. template<typename T>
  25. using user_ref = boost::yap::expression_ref<user_expr, T>;
  26. int test_main(int, char * [])
  27. {
  28. {
  29. {
  30. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(1.0)), double &&>));
  31. BOOST_CHECK(yap::value(1.0) == 1.0);
  32. }
  33. {
  34. double d = 2.0;
  35. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(d)), double &>));
  36. BOOST_CHECK(yap::value(d) == 2.0);
  37. }
  38. {
  39. double const d = 3.0;
  40. BOOST_MPL_ASSERT(
  41. (std::is_same<decltype(yap::value(d)), double const &>));
  42. BOOST_CHECK(yap::value(d) == 3.0);
  43. }
  44. }
  45. {
  46. {
  47. term<double> td = {{1.0}};
  48. BOOST_MPL_ASSERT(
  49. (std::is_same<decltype(yap::value(std::move(td))), double &&>));
  50. BOOST_CHECK(yap::value(std::move(td)) == 1.0);
  51. }
  52. {
  53. term<double> td = {{2.0}};
  54. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(td)), double &>));
  55. BOOST_CHECK(yap::value(td) == 2.0);
  56. }
  57. {
  58. term<double> const td = {{3.0}};
  59. BOOST_MPL_ASSERT(
  60. (std::is_same<decltype(yap::value(td)), double const &>));
  61. BOOST_CHECK(yap::value(td) == 3.0);
  62. }
  63. term<double> unity = {{1.0}};
  64. using plus_expr_type = yap::expression<
  65. yap::expr_kind::plus,
  66. bh::tuple<ref<term<double> &>, term<int>>>;
  67. plus_expr_type plus_expr = unity + term<int>{{1}};
  68. {
  69. ref<term<double> &> ref = bh::front(plus_expr.elements);
  70. BOOST_MPL_ASSERT(
  71. (std::is_same<decltype(yap::value(std::move(ref))), double &>));
  72. }
  73. {
  74. ref<term<double> &> ref = bh::front(plus_expr.elements);
  75. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(ref)), double &>));
  76. }
  77. {
  78. ref<term<double> &> const ref = bh::front(plus_expr.elements);
  79. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(ref)), double &>));
  80. }
  81. {
  82. term<double> const unity = {{1.0}};
  83. yap::expression<
  84. yap::expr_kind::plus,
  85. bh::tuple<ref<term<double> const &>, term<int>>>
  86. plus_expr = unity + term<int>{{1}};
  87. {
  88. ref<term<double> const &> ref = bh::front(plus_expr.elements);
  89. BOOST_MPL_ASSERT((std::is_same<
  90. decltype(yap::value(std::move(ref))),
  91. double const &>));
  92. }
  93. {
  94. ref<term<double> const &> ref = bh::front(plus_expr.elements);
  95. BOOST_MPL_ASSERT(
  96. (std::is_same<decltype(yap::value(ref)), double const &>));
  97. }
  98. {
  99. ref<term<double> const &> const ref = bh::front(plus_expr.elements);
  100. BOOST_MPL_ASSERT(
  101. (std::is_same<decltype(yap::value(ref)), double const &>));
  102. }
  103. }
  104. }
  105. {
  106. {
  107. user_term<double> td = {{1.0}};
  108. BOOST_MPL_ASSERT(
  109. (std::is_same<decltype(yap::value(std::move(td))), double &&>));
  110. BOOST_CHECK(yap::value(std::move(td)) == 1.0);
  111. }
  112. {
  113. user_term<double> td = {{2.0}};
  114. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(td)), double &>));
  115. BOOST_CHECK(yap::value(td) == 2.0);
  116. }
  117. {
  118. user_term<double> const td = {{3.0}};
  119. BOOST_MPL_ASSERT(
  120. (std::is_same<decltype(yap::value(td)), double const &>));
  121. BOOST_CHECK(yap::value(td) == 3.0);
  122. }
  123. user_term<double> unity = {{1.0}};
  124. using plus_expr_type = user_expr<
  125. yap::expr_kind::plus,
  126. bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
  127. plus_expr_type plus_expr = unity + user_term<int>{{1}};
  128. {
  129. user_ref<user_term<double> &> ref = bh::front(plus_expr.elements);
  130. BOOST_MPL_ASSERT(
  131. (std::is_same<decltype(yap::value(std::move(ref))), double &>));
  132. }
  133. {
  134. user_ref<user_term<double> &> ref = bh::front(plus_expr.elements);
  135. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(ref)), double &>));
  136. }
  137. {
  138. user_ref<user_term<double> &> const ref = bh::front(plus_expr.elements);
  139. BOOST_MPL_ASSERT((std::is_same<decltype(yap::value(ref)), double &>));
  140. }
  141. {
  142. user_term<double> const unity = {{1.0}};
  143. user_expr<
  144. yap::expr_kind::plus,
  145. bh::tuple<user_ref<user_term<double> const &>, user_term<int>>>
  146. plus_expr = unity + user_term<int>{{1}};
  147. {
  148. user_ref<user_term<double> const &> ref =
  149. bh::front(plus_expr.elements);
  150. BOOST_MPL_ASSERT((std::is_same<
  151. decltype(yap::value(std::move(ref))),
  152. double const &>));
  153. }
  154. {
  155. user_ref<user_term<double> const &> ref =
  156. bh::front(plus_expr.elements);
  157. BOOST_MPL_ASSERT(
  158. (std::is_same<decltype(yap::value(ref)), double const &>));
  159. }
  160. {
  161. user_ref<user_term<double> const &> const ref =
  162. bh::front(plus_expr.elements);
  163. BOOST_MPL_ASSERT(
  164. (std::is_same<decltype(yap::value(ref)), double const &>));
  165. }
  166. }
  167. }
  168. return 0;
  169. }