code_gen_samples.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. template<typename T>
  8. using term = boost::yap::terminal<boost::yap::expression, T>;
  9. namespace yap = boost::yap;
  10. namespace bh = boost::hana;
  11. namespace user {
  12. struct number
  13. {
  14. double value;
  15. friend number operator+(number lhs, number rhs)
  16. {
  17. return number{lhs.value + rhs.value};
  18. }
  19. friend number operator*(number lhs, number rhs)
  20. {
  21. return number{lhs.value * rhs.value};
  22. }
  23. };
  24. // A more efficient fused multiply-add operation would normally go here.
  25. number naxpy(number a, number x, number y)
  26. {
  27. return number{a.value * x.value + y.value};
  28. }
  29. // Transforms expressions of the form "a * x + y" to "naxpy(a, x, y)" via
  30. // the implicit transform customiztion point.
  31. template<typename Expr1, typename Expr2, typename Expr3>
  32. decltype(auto) transform_expression(yap::expression<
  33. yap::expr_kind::plus,
  34. bh::tuple<
  35. yap::expression<
  36. yap::expr_kind::multiplies,
  37. bh::tuple<Expr1, Expr2>>,
  38. Expr3>> const & expr)
  39. {
  40. return naxpy(
  41. evaluate(expr.left().left()),
  42. evaluate(expr.left().right()),
  43. evaluate(expr.right()));
  44. }
  45. }
  46. term<user::number> a{{1.0}};
  47. term<user::number> x{{42.0}};
  48. term<user::number> y{{3.0}};
  49. user::number
  50. eval_as_yap_expr(decltype((a * x + y) * (a * x + y) + (a * x + y)) & expr)
  51. {
  52. return yap::evaluate(expr);
  53. }
  54. user::number eval_as_yap_expr_4x(decltype(
  55. (a * x + y) * (a * x + y) + (a * x + y) + (a * x + y) * (a * x + y) +
  56. (a * x + y) + (a * x + y) * (a * x + y) + (a * x + y) +
  57. (a * x + y) * (a * x + y) + (a * x + y)) & expr)
  58. {
  59. return yap::evaluate(expr);
  60. }
  61. user::number eval_as_cpp_expr(user::number a, user::number x, user::number y)
  62. {
  63. return (a * x + y) * (a * x + y) + (a * x + y);
  64. }
  65. user::number eval_as_cpp_expr_4x(user::number a, user::number x, user::number y)
  66. {
  67. return (a * x + y) * (a * x + y) + (a * x + y) + (a * x + y) * (a * x + y) +
  68. (a * x + y) + (a * x + y) * (a * x + y) + (a * x + y) +
  69. (a * x + y) * (a * x + y) + (a * x + y);
  70. }
  71. int main()
  72. {
  73. auto expr = (a * x + y) * (a * x + y) + (a * x + y);
  74. user::number result_1 = eval_as_yap_expr(expr);
  75. user::number result_2 =
  76. eval_as_cpp_expr(yap::value(a), yap::value(x), yap::value(y));
  77. (void)result_1;
  78. (void)result_2;
  79. return 0;
  80. }