deref.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. plus_expr_type plus_expr = unity + term<int>{{1}};
  34. {
  35. ref<term<double> &> ref = bh::front(plus_expr.elements);
  36. BOOST_MPL_ASSERT((std::is_same<
  37. decltype(yap::deref(std::move(ref))),
  38. term<double> &>));
  39. BOOST_CHECK(yap::value(ref) == 1.0);
  40. }
  41. {
  42. ref<term<double> &> ref = bh::front(plus_expr.elements);
  43. BOOST_MPL_ASSERT(
  44. (std::is_same<decltype(yap::deref(ref)), term<double> &>));
  45. BOOST_CHECK(yap::value(ref) == 1.0);
  46. }
  47. {
  48. ref<term<double> &> const ref = bh::front(plus_expr.elements);
  49. BOOST_MPL_ASSERT(
  50. (std::is_same<decltype(yap::deref(ref)), term<double> &>));
  51. BOOST_CHECK(yap::value(ref) == 1.0);
  52. }
  53. {
  54. term<double> const unity = {{1.0}};
  55. yap::expression<
  56. yap::expr_kind::plus,
  57. bh::tuple<ref<term<double> const &>, term<int>>>
  58. plus_expr = unity + term<int>{{1}};
  59. {
  60. ref<term<double> const &> ref = bh::front(plus_expr.elements);
  61. BOOST_MPL_ASSERT((std::is_same<
  62. decltype(yap::deref(std::move(ref))),
  63. term<double> const &>));
  64. BOOST_CHECK(yap::value(ref) == 1.0);
  65. }
  66. {
  67. ref<term<double> const &> ref = bh::front(plus_expr.elements);
  68. BOOST_MPL_ASSERT((std::is_same<
  69. decltype(yap::deref(ref)),
  70. term<double> const &>));
  71. BOOST_CHECK(yap::value(ref) == 1.0);
  72. }
  73. {
  74. ref<term<double> const &> const ref =
  75. bh::front(plus_expr.elements);
  76. BOOST_MPL_ASSERT((std::is_same<
  77. decltype(yap::deref(ref)),
  78. term<double> const &>));
  79. BOOST_CHECK(yap::value(ref) == 1.0);
  80. }
  81. }
  82. }
  83. {
  84. user_term<double> unity = {{1.0}};
  85. using plus_expr_type = user_expr<
  86. yap::expr_kind::plus,
  87. bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
  88. plus_expr_type plus_expr = unity + user_term<int>{{1}};
  89. {
  90. user_ref<user_term<double> &> ref = bh::front(plus_expr.elements);
  91. BOOST_MPL_ASSERT((std::is_same<
  92. decltype(yap::deref(std::move(ref))),
  93. user_term<double> &>));
  94. BOOST_CHECK(yap::value(ref) == 1.0);
  95. }
  96. {
  97. user_ref<user_term<double> &> ref = bh::front(plus_expr.elements);
  98. BOOST_MPL_ASSERT(
  99. (std::is_same<decltype(yap::deref(ref)), user_term<double> &>));
  100. BOOST_CHECK(yap::value(ref) == 1.0);
  101. }
  102. {
  103. user_ref<user_term<double> &> const ref =
  104. bh::front(plus_expr.elements);
  105. BOOST_MPL_ASSERT(
  106. (std::is_same<decltype(yap::deref(ref)), user_term<double> &>));
  107. BOOST_CHECK(yap::value(ref) == 1.0);
  108. }
  109. {
  110. user_term<double> const unity = {{1.0}};
  111. user_expr<
  112. yap::expr_kind::plus,
  113. bh::tuple<user_ref<user_term<double> const &>, user_term<int>>>
  114. plus_expr = unity + user_term<int>{{1}};
  115. {
  116. user_ref<user_term<double> const &> ref =
  117. bh::front(plus_expr.elements);
  118. BOOST_MPL_ASSERT((std::is_same<
  119. decltype(yap::deref(std::move(ref))),
  120. user_term<double> const &>));
  121. BOOST_CHECK(yap::value(ref) == 1.0);
  122. }
  123. {
  124. user_ref<user_term<double> const &> ref =
  125. bh::front(plus_expr.elements);
  126. BOOST_MPL_ASSERT((std::is_same<
  127. decltype(yap::deref(ref)),
  128. user_term<double> const &>));
  129. BOOST_CHECK(yap::value(ref) == 1.0);
  130. }
  131. {
  132. user_ref<user_term<double> const &> const ref =
  133. bh::front(plus_expr.elements);
  134. BOOST_MPL_ASSERT((std::is_same<
  135. decltype(yap::deref(ref)),
  136. user_term<double> const &>));
  137. BOOST_CHECK(yap::value(ref) == 1.0);
  138. }
  139. }
  140. }
  141. return 0;
  142. }