transform.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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/yap.hpp>
  7. #include <boost/mpl/assert.hpp>
  8. #include <boost/test/minimal.hpp>
  9. #include <sstream>
  10. template<typename T>
  11. using term = boost::yap::terminal<boost::yap::minimal_expr, T>;
  12. namespace yap = boost::yap;
  13. namespace bh = boost::hana;
  14. struct iota_terminal_transform
  15. {
  16. template<typename T>
  17. auto operator()(boost::yap::expr_tag<boost::yap::expr_kind::terminal>, T && t)
  18. {
  19. return boost::yap::make_terminal(index_++);
  20. }
  21. template<typename CallableExpr, typename... Arg>
  22. auto operator()(boost::yap::expr_tag<boost::yap::expr_kind::call>,
  23. CallableExpr callable, Arg &&... arg)
  24. {
  25. return boost::yap::make_expression<boost::yap::expr_kind::call>(
  26. callable, boost::yap::transform(arg, *this)...);
  27. }
  28. int index_;
  29. };
  30. struct plus_expr_t
  31. {
  32. static yap::expr_kind const kind = yap::expr_kind::plus;
  33. bh::tuple<term<int>, term<int>> elements;
  34. };
  35. int test_main(int, char * [])
  36. {
  37. // Each node instantiated from from yap::expression.
  38. {
  39. auto plus_expr = yap::terminal<yap::expression, int>{{5}} + 6;
  40. BOOST_CHECK(yap::evaluate(plus_expr) == 11);
  41. BOOST_CHECK(
  42. yap::evaluate(
  43. yap::transform(plus_expr, iota_terminal_transform{0})) == 1);
  44. }
  45. // Each node instantiated from from yap::minimal_expr.
  46. {
  47. yap::minimal_expr<yap::expr_kind::plus, bh::tuple<term<int>, term<int>>>
  48. plus_expr;
  49. yap::evaluate(yap::transform(plus_expr, iota_terminal_transform{0}), 1);
  50. }
  51. // Leaves are instantiated from from yap::minimal_expr; nonterminal
  52. // expr_kind::plus does not even come from a template.
  53. {
  54. plus_expr_t plus_expr;
  55. yap::evaluate(yap::transform(plus_expr, iota_terminal_transform{0}), 1);
  56. }
  57. return 0;
  58. }