right.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. term<double> unity = {{1.0}};
  30. using plus_expr_type = yap::expression<
  31. yap::expr_kind::plus,
  32. bh::tuple<ref<term<double> &>, term<int>>>;
  33. {
  34. plus_expr_type plus_expr = unity + term<int>{{1}};
  35. BOOST_MPL_ASSERT((std::is_same<
  36. decltype(yap::right(std::move(plus_expr))),
  37. term<int> &&>));
  38. }
  39. {
  40. plus_expr_type plus_expr = unity + term<int>{{1}};
  41. BOOST_MPL_ASSERT(
  42. (std::is_same<decltype(yap::right(plus_expr)), term<int> &>));
  43. }
  44. {
  45. plus_expr_type const plus_expr = unity + term<int>{{1}};
  46. BOOST_MPL_ASSERT((std::is_same<
  47. decltype(yap::right(plus_expr)),
  48. term<int> const &>));
  49. }
  50. {
  51. term<double> unity = {{1.0}};
  52. using plus_expr_type = yap::expression<
  53. yap::expr_kind::plus,
  54. bh::tuple<ref<term<double> &>, term<int>>>;
  55. plus_expr_type plus_expr = unity + term<int>{{1}};
  56. using plus_plus_expr_type = yap::expression<
  57. yap::expr_kind::plus,
  58. bh::tuple<ref<plus_expr_type &>, term<int>>>;
  59. {
  60. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  61. ref<plus_expr_type &> plus_expr_ref =
  62. bh::front(plus_plus_expr.elements);
  63. BOOST_MPL_ASSERT(
  64. (std::is_same<
  65. decltype(yap::right(std::move(plus_expr_ref))),
  66. term<int> &>));
  67. }
  68. {
  69. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  70. ref<plus_expr_type &> plus_expr_ref =
  71. bh::front(plus_plus_expr.elements);
  72. BOOST_MPL_ASSERT((std::is_same<
  73. decltype(yap::right(plus_expr_ref)),
  74. term<int> &>));
  75. }
  76. {
  77. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  78. ref<plus_expr_type &> const plus_expr_ref =
  79. bh::front(plus_plus_expr.elements);
  80. BOOST_MPL_ASSERT((std::is_same<
  81. decltype(yap::right(plus_expr_ref)),
  82. term<int> &>));
  83. }
  84. }
  85. {
  86. term<double> unity = {{1.0}};
  87. using plus_expr_type = yap::expression<
  88. yap::expr_kind::plus,
  89. bh::tuple<ref<term<double> &>, term<int>>>;
  90. plus_expr_type const plus_expr = unity + term<int>{{1}};
  91. using plus_plus_expr_type = yap::expression<
  92. yap::expr_kind::plus,
  93. bh::tuple<ref<plus_expr_type const &>, term<int>>>;
  94. {
  95. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  96. ref<plus_expr_type const &> plus_expr_ref =
  97. bh::front(plus_plus_expr.elements);
  98. BOOST_MPL_ASSERT(
  99. (std::is_same<
  100. decltype(yap::right(std::move(plus_expr_ref))),
  101. term<int> const &>));
  102. }
  103. {
  104. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  105. ref<plus_expr_type const &> plus_expr_ref =
  106. bh::front(plus_plus_expr.elements);
  107. BOOST_MPL_ASSERT((std::is_same<
  108. decltype(yap::right(plus_expr_ref)),
  109. term<int> const &>));
  110. }
  111. {
  112. plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
  113. ref<plus_expr_type const &> const plus_expr_ref =
  114. bh::front(plus_plus_expr.elements);
  115. BOOST_MPL_ASSERT((std::is_same<
  116. decltype(yap::right(plus_expr_ref)),
  117. term<int> const &>));
  118. }
  119. }
  120. }
  121. {
  122. user_term<double> unity = {{1.0}};
  123. using plus_expr_type = user_expr<
  124. yap::expr_kind::plus,
  125. bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
  126. {
  127. plus_expr_type plus_expr = unity + user_term<int>{{1}};
  128. BOOST_MPL_ASSERT((std::is_same<
  129. decltype(yap::right(std::move(plus_expr))),
  130. user_term<int> &&>));
  131. }
  132. {
  133. plus_expr_type plus_expr = unity + user_term<int>{{1}};
  134. BOOST_MPL_ASSERT((std::is_same<
  135. decltype(yap::right(plus_expr)),
  136. user_term<int> &>));
  137. }
  138. {
  139. plus_expr_type const plus_expr = unity + user_term<int>{{1}};
  140. BOOST_MPL_ASSERT((std::is_same<
  141. decltype(yap::right(plus_expr)),
  142. user_term<int> const &>));
  143. }
  144. {
  145. user_term<double> unity = {{1.0}};
  146. using plus_expr_type = user_expr<
  147. yap::expr_kind::plus,
  148. bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
  149. plus_expr_type plus_expr = unity + user_term<int>{{1}};
  150. using plus_plus_expr_type = user_expr<
  151. yap::expr_kind::plus,
  152. bh::tuple<user_ref<plus_expr_type &>, user_term<int>>>;
  153. {
  154. plus_plus_expr_type plus_plus_expr =
  155. plus_expr + user_term<int>{{1}};
  156. user_ref<plus_expr_type &> plus_expr_ref =
  157. bh::front(plus_plus_expr.elements);
  158. BOOST_MPL_ASSERT(
  159. (std::is_same<
  160. decltype(yap::right(std::move(plus_expr_ref))),
  161. user_term<int> &>));
  162. }
  163. {
  164. plus_plus_expr_type plus_plus_expr =
  165. plus_expr + user_term<int>{{1}};
  166. user_ref<plus_expr_type &> plus_expr_ref =
  167. bh::front(plus_plus_expr.elements);
  168. BOOST_MPL_ASSERT((std::is_same<
  169. decltype(yap::right(plus_expr_ref)),
  170. user_term<int> &>));
  171. }
  172. {
  173. plus_plus_expr_type plus_plus_expr =
  174. plus_expr + user_term<int>{{1}};
  175. user_ref<plus_expr_type &> const plus_expr_ref =
  176. bh::front(plus_plus_expr.elements);
  177. BOOST_MPL_ASSERT((std::is_same<
  178. decltype(yap::right(plus_expr_ref)),
  179. user_term<int> &>));
  180. }
  181. }
  182. {
  183. user_term<double> unity = {{1.0}};
  184. using plus_expr_type = user_expr<
  185. yap::expr_kind::plus,
  186. bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
  187. plus_expr_type const plus_expr = unity + user_term<int>{{1}};
  188. using plus_plus_expr_type = user_expr<
  189. yap::expr_kind::plus,
  190. bh::tuple<user_ref<plus_expr_type const &>, user_term<int>>>;
  191. {
  192. plus_plus_expr_type plus_plus_expr =
  193. plus_expr + user_term<int>{{1}};
  194. user_ref<plus_expr_type const &> plus_expr_ref =
  195. bh::front(plus_plus_expr.elements);
  196. BOOST_MPL_ASSERT(
  197. (std::is_same<
  198. decltype(yap::right(std::move(plus_expr_ref))),
  199. user_term<int> const &>));
  200. }
  201. {
  202. plus_plus_expr_type plus_plus_expr =
  203. plus_expr + user_term<int>{{1}};
  204. user_ref<plus_expr_type const &> plus_expr_ref =
  205. bh::front(plus_plus_expr.elements);
  206. BOOST_MPL_ASSERT((std::is_same<
  207. decltype(yap::right(plus_expr_ref)),
  208. user_term<int> const &>));
  209. }
  210. {
  211. plus_plus_expr_type plus_plus_expr =
  212. plus_expr + user_term<int>{{1}};
  213. user_ref<plus_expr_type const &> const plus_expr_ref =
  214. bh::front(plus_plus_expr.elements);
  215. BOOST_MPL_ASSERT((std::is_same<
  216. decltype(yap::right(plus_expr_ref)),
  217. user_term<int> const &>));
  218. }
  219. }
  220. }
  221. return 0;
  222. }