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