• 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/mpl/assert.hpp>
9 
10 #include <boost/test/minimal.hpp>
11 
12 
13 template<typename T>
14 using term = boost::yap::terminal<boost::yap::expression, T>;
15 
16 template<typename T>
17 using ref = boost::yap::expression_ref<boost::yap::expression, T>;
18 
19 namespace yap = boost::yap;
20 namespace bh = boost::hana;
21 
22 
23 template<boost::yap::expr_kind Kind, typename Tuple>
24 struct user_expr
25 {
26     static boost::yap::expr_kind const kind = Kind;
27 
28     Tuple elements;
29 };
30 
31 BOOST_YAP_USER_BINARY_OPERATOR(plus, user_expr, user_expr)
32 
33 template<typename T>
34 using user_term = boost::yap::terminal<user_expr, T>;
35 
36 template<typename T>
37 using user_ref = boost::yap::expression_ref<user_expr, T>;
38 
39 
test_main(int,char * [])40 int test_main(int, char * [])
41 {
42     {
43         term<double> unity = {{1.0}};
44         using plus_expr_type = yap::expression<
45             yap::expr_kind::plus,
46             bh::tuple<ref<term<double> &>, term<int>>>;
47 
48         {
49             plus_expr_type plus_expr = unity + term<int>{{1}};
50             BOOST_MPL_ASSERT((std::is_same<
51                               decltype(yap::right(std::move(plus_expr))),
52                               term<int> &&>));
53         }
54 
55         {
56             plus_expr_type plus_expr = unity + term<int>{{1}};
57             BOOST_MPL_ASSERT(
58                 (std::is_same<decltype(yap::right(plus_expr)), term<int> &>));
59         }
60 
61         {
62             plus_expr_type const plus_expr = unity + term<int>{{1}};
63             BOOST_MPL_ASSERT((std::is_same<
64                               decltype(yap::right(plus_expr)),
65                               term<int> const &>));
66         }
67 
68         {
69             term<double> unity = {{1.0}};
70             using plus_expr_type = yap::expression<
71                 yap::expr_kind::plus,
72                 bh::tuple<ref<term<double> &>, term<int>>>;
73             plus_expr_type plus_expr = unity + term<int>{{1}};
74 
75             using plus_plus_expr_type = yap::expression<
76                 yap::expr_kind::plus,
77                 bh::tuple<ref<plus_expr_type &>, term<int>>>;
78 
79             {
80                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
81                 ref<plus_expr_type &> plus_expr_ref =
82                     bh::front(plus_plus_expr.elements);
83                 BOOST_MPL_ASSERT(
84                     (std::is_same<
85                         decltype(yap::right(std::move(plus_expr_ref))),
86                         term<int> &>));
87             }
88 
89             {
90                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
91                 ref<plus_expr_type &> plus_expr_ref =
92                     bh::front(plus_plus_expr.elements);
93                 BOOST_MPL_ASSERT((std::is_same<
94                                   decltype(yap::right(plus_expr_ref)),
95                                   term<int> &>));
96             }
97 
98             {
99                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
100                 ref<plus_expr_type &> const plus_expr_ref =
101                     bh::front(plus_plus_expr.elements);
102                 BOOST_MPL_ASSERT((std::is_same<
103                                   decltype(yap::right(plus_expr_ref)),
104                                   term<int> &>));
105             }
106         }
107 
108         {
109             term<double> unity = {{1.0}};
110             using plus_expr_type = yap::expression<
111                 yap::expr_kind::plus,
112                 bh::tuple<ref<term<double> &>, term<int>>>;
113             plus_expr_type const plus_expr = unity + term<int>{{1}};
114 
115             using plus_plus_expr_type = yap::expression<
116                 yap::expr_kind::plus,
117                 bh::tuple<ref<plus_expr_type const &>, term<int>>>;
118 
119             {
120                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
121                 ref<plus_expr_type const &> plus_expr_ref =
122                     bh::front(plus_plus_expr.elements);
123                 BOOST_MPL_ASSERT(
124                     (std::is_same<
125                         decltype(yap::right(std::move(plus_expr_ref))),
126                         term<int> const &>));
127             }
128 
129             {
130                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
131                 ref<plus_expr_type const &> plus_expr_ref =
132                     bh::front(plus_plus_expr.elements);
133                 BOOST_MPL_ASSERT((std::is_same<
134                                   decltype(yap::right(plus_expr_ref)),
135                                   term<int> const &>));
136             }
137 
138             {
139                 plus_plus_expr_type plus_plus_expr = plus_expr + term<int>{{1}};
140                 ref<plus_expr_type const &> const plus_expr_ref =
141                     bh::front(plus_plus_expr.elements);
142                 BOOST_MPL_ASSERT((std::is_same<
143                                   decltype(yap::right(plus_expr_ref)),
144                                   term<int> const &>));
145             }
146         }
147     }
148 
149     {
150         user_term<double> unity = {{1.0}};
151         using plus_expr_type = user_expr<
152             yap::expr_kind::plus,
153             bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
154 
155         {
156             plus_expr_type plus_expr = unity + user_term<int>{{1}};
157             BOOST_MPL_ASSERT((std::is_same<
158                               decltype(yap::right(std::move(plus_expr))),
159                               user_term<int> &&>));
160         }
161 
162         {
163             plus_expr_type plus_expr = unity + user_term<int>{{1}};
164             BOOST_MPL_ASSERT((std::is_same<
165                               decltype(yap::right(plus_expr)),
166                               user_term<int> &>));
167         }
168 
169         {
170             plus_expr_type const plus_expr = unity + user_term<int>{{1}};
171             BOOST_MPL_ASSERT((std::is_same<
172                               decltype(yap::right(plus_expr)),
173                               user_term<int> const &>));
174         }
175 
176         {
177             user_term<double> unity = {{1.0}};
178             using plus_expr_type = user_expr<
179                 yap::expr_kind::plus,
180                 bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
181             plus_expr_type plus_expr = unity + user_term<int>{{1}};
182 
183             using plus_plus_expr_type = user_expr<
184                 yap::expr_kind::plus,
185                 bh::tuple<user_ref<plus_expr_type &>, user_term<int>>>;
186 
187             {
188                 plus_plus_expr_type plus_plus_expr =
189                     plus_expr + user_term<int>{{1}};
190                 user_ref<plus_expr_type &> plus_expr_ref =
191                     bh::front(plus_plus_expr.elements);
192                 BOOST_MPL_ASSERT(
193                     (std::is_same<
194                         decltype(yap::right(std::move(plus_expr_ref))),
195                         user_term<int> &>));
196             }
197 
198             {
199                 plus_plus_expr_type plus_plus_expr =
200                     plus_expr + user_term<int>{{1}};
201                 user_ref<plus_expr_type &> plus_expr_ref =
202                     bh::front(plus_plus_expr.elements);
203                 BOOST_MPL_ASSERT((std::is_same<
204                                   decltype(yap::right(plus_expr_ref)),
205                                   user_term<int> &>));
206             }
207 
208             {
209                 plus_plus_expr_type plus_plus_expr =
210                     plus_expr + user_term<int>{{1}};
211                 user_ref<plus_expr_type &> const plus_expr_ref =
212                     bh::front(plus_plus_expr.elements);
213                 BOOST_MPL_ASSERT((std::is_same<
214                                   decltype(yap::right(plus_expr_ref)),
215                                   user_term<int> &>));
216             }
217         }
218 
219         {
220             user_term<double> unity = {{1.0}};
221             using plus_expr_type = user_expr<
222                 yap::expr_kind::plus,
223                 bh::tuple<user_ref<user_term<double> &>, user_term<int>>>;
224             plus_expr_type const plus_expr = unity + user_term<int>{{1}};
225 
226             using plus_plus_expr_type = user_expr<
227                 yap::expr_kind::plus,
228                 bh::tuple<user_ref<plus_expr_type const &>, user_term<int>>>;
229 
230             {
231                 plus_plus_expr_type plus_plus_expr =
232                     plus_expr + user_term<int>{{1}};
233                 user_ref<plus_expr_type const &> plus_expr_ref =
234                     bh::front(plus_plus_expr.elements);
235                 BOOST_MPL_ASSERT(
236                     (std::is_same<
237                         decltype(yap::right(std::move(plus_expr_ref))),
238                         user_term<int> const &>));
239             }
240 
241             {
242                 plus_plus_expr_type plus_plus_expr =
243                     plus_expr + user_term<int>{{1}};
244                 user_ref<plus_expr_type const &> plus_expr_ref =
245                     bh::front(plus_plus_expr.elements);
246                 BOOST_MPL_ASSERT((std::is_same<
247                                   decltype(yap::right(plus_expr_ref)),
248                                   user_term<int> const &>));
249             }
250 
251             {
252                 plus_plus_expr_type plus_plus_expr =
253                     plus_expr + user_term<int>{{1}};
254                 user_ref<plus_expr_type const &> const plus_expr_ref =
255                     bh::front(plus_plus_expr.elements);
256                 BOOST_MPL_ASSERT((std::is_same<
257                                   decltype(yap::right(plus_expr_ref)),
258                                   user_term<int> const &>));
259             }
260         }
261     }
262 
263 #ifndef _MSC_VER // Tsk, tsk.
264     {
265         using term_t = term<int>;
266         constexpr auto expr = term_t{13} + term_t{42};
267         constexpr auto result1 = expr.right().value();
268         constexpr auto result2 = yap::value(right(expr));
269         (void)result1;
270         (void)result2;
271     }
272 #endif
273 
274     return 0;
275 }
276