• 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/expression.hpp>
7 
8 #include <boost/test/minimal.hpp>
9 
10 
11 template<typename T>
12 using term = boost::yap::terminal<boost::yap::expression, T>;
13 
14 template<typename T>
15 using ref = boost::yap::expression_ref<boost::yap::expression, T>;
16 
17 namespace yap = boost::yap;
18 namespace bh = boost::hana;
19 
20 
21 namespace user {
22 
23     struct number
24     {
25         double value;
26     };
27 
28     struct eval_xform
29     {
30         auto
operator ()user::eval_xform31         operator()(yap::expr_tag<yap::expr_kind::terminal>, number const & n)
32         {
33             return n;
34         }
35 
36         template<typename Expr>
operator ()user::eval_xform37         decltype(auto) operator()(
38             yap::expression<yap::expr_kind::negate, bh::tuple<Expr>> const &
39                 expr)
40         {
41             number const n = transform(yap::value(expr), *this);
42             return number{-n.value};
43         }
44 
45         template<typename Expr1, typename Expr2>
operator ()user::eval_xform46         decltype(auto) operator()(yap::expression<
47                                   yap::expr_kind::plus,
48                                   bh::tuple<Expr1, Expr2>> const & expr)
49         {
50             number const lhs = transform(yap::left(expr), *this);
51             number const rhs = transform(yap::right(expr), *this);
52             return number{lhs.value + rhs.value};
53         }
54     };
55 }
56 
57 template<typename Expr>
make_ref(Expr && expr)58 auto make_ref(Expr && expr)
59 {
60     using type = yap::detail::operand_type_t<yap::expression, Expr>;
61     return yap::detail::make_operand<type>{}(static_cast<Expr &&>(expr));
62 }
63 
test_main(int,char * [])64 int test_main(int, char * [])
65 {
66 {
67     {
68         term<user::number> a{{1.0}};
69 
70         {
71             user::number result = transform(a, user::eval_xform{});
72             BOOST_CHECK(result.value == 1);
73         }
74 
75         {
76             user::number result = transform(make_ref(a), user::eval_xform{});
77             BOOST_CHECK(result.value == 1);
78         }
79 
80         {
81             user::number result = transform(-a, user::eval_xform{});
82             BOOST_CHECK(result.value == -1);
83         }
84 
85         {
86             auto expr = make_ref(a);
87             user::number result = transform(-expr, user::eval_xform{});
88             BOOST_CHECK(result.value == -1);
89         }
90 
91         {
92             auto expr = -a;
93             user::number result = transform(expr, user::eval_xform{});
94             BOOST_CHECK(result.value == -1);
95         }
96 
97         {
98             auto expr1 = make_ref(a);
99             auto expr2 = make_ref(expr1);
100             user::number result = transform(expr2, user::eval_xform{});
101             BOOST_CHECK(result.value == 1);
102         }
103 
104         {
105             auto expr1 = -a;
106             auto expr2 = make_ref(expr1);
107             user::number result = transform(expr2, user::eval_xform{});
108             BOOST_CHECK(result.value == -1);
109         }
110 
111         {
112             auto expr1 = make_ref(a);
113             auto expr2 = -expr1;
114             user::number result = transform(expr2, user::eval_xform{});
115             BOOST_CHECK(result.value == -1);
116         }
117 
118         {
119             auto expr1 = a;
120             auto expr2 = make_ref(expr1);
121             auto expr3 = make_ref(expr2);
122             user::number result = transform(expr3, user::eval_xform{});
123             BOOST_CHECK(result.value == 1);
124         }
125 
126         {
127             auto expr1 = -a;
128             auto expr2 = make_ref(expr1);
129             auto expr3 = make_ref(expr2);
130             user::number result = transform(expr3, user::eval_xform{});
131             BOOST_CHECK(result.value == -1);
132         }
133 
134         {
135             auto expr1 = make_ref(a);
136             auto expr2 = -expr1;
137             auto expr3 = make_ref(expr2);
138             user::number result = transform(expr3, user::eval_xform{});
139             BOOST_CHECK(result.value == -1);
140         }
141 
142         {
143             auto expr1 = make_ref(a);
144             auto expr2 = make_ref(expr1);
145             auto expr3 = -expr2;
146             user::number result = transform(expr3, user::eval_xform{});
147             BOOST_CHECK(result.value == -1);
148         }
149     }
150 
151     {
152         user::number result =
153             transform(-term<user::number>{{1.0}}, user::eval_xform{});
154         BOOST_CHECK(result.value == -1);
155     }
156 }
157 
158 {
159     term<user::number> a{{1.0}};
160     term<user::number> x{{41.0}};
161 
162     {
163         user::number result = transform(a + x, user::eval_xform{});
164         BOOST_CHECK(result.value == 42);
165     }
166 
167 
168     {
169         user::number result =
170             transform(make_ref(a) + make_ref(x), user::eval_xform{});
171         BOOST_CHECK(result.value == 42);
172     }
173 
174     {
175         user::number result = transform(make_ref(a) + x, user::eval_xform{});
176         BOOST_CHECK(result.value == 42);
177     }
178 
179     {
180         user::number result = transform(a + make_ref(x), user::eval_xform{});
181         BOOST_CHECK(result.value == 42);
182     }
183 
184     {
185         user::number result = transform(a + x, user::eval_xform{});
186         BOOST_CHECK(result.value == 42);
187     }
188 
189 
190     {
191         user::number result =
192             transform(-make_ref(a) + make_ref(x), user::eval_xform{});
193         BOOST_CHECK(result.value == 40);
194     }
195 
196     {
197         user::number result = transform(-make_ref(a) + x, user::eval_xform{});
198         BOOST_CHECK(result.value == 40);
199     }
200 
201     {
202         user::number result = transform(-a + make_ref(x), user::eval_xform{});
203         BOOST_CHECK(result.value == 40);
204     }
205 
206     {
207         user::number result = transform(-a + x, user::eval_xform{});
208         BOOST_CHECK(result.value == 40);
209     }
210 
211 
212     {
213         user::number result =
214             transform(make_ref(a) + -make_ref(x), user::eval_xform{});
215         BOOST_CHECK(result.value == -40);
216     }
217 
218     {
219         user::number result = transform(make_ref(a) + -x, user::eval_xform{});
220         BOOST_CHECK(result.value == -40);
221     }
222 
223     {
224         user::number result = transform(a + -make_ref(x), user::eval_xform{});
225         BOOST_CHECK(result.value == -40);
226     }
227 
228     {
229         user::number result = transform(a + -x, user::eval_xform{});
230         BOOST_CHECK(result.value == -40);
231     }
232 
233 
234     {
235         user::number result =
236             transform(-make_ref(a) + -make_ref(x), user::eval_xform{});
237         BOOST_CHECK(result.value == -42);
238     }
239 
240     {
241         user::number result = transform(-make_ref(a) + -x, user::eval_xform{});
242         BOOST_CHECK(result.value == -42);
243     }
244 
245     {
246         user::number result = transform(-a + -make_ref(x), user::eval_xform{});
247         BOOST_CHECK(result.value == -42);
248     }
249 
250     {
251         user::number result = transform(-a + -x, user::eval_xform{});
252         BOOST_CHECK(result.value == -42);
253     }
254 }
255 
256 return 0;
257 }
258