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 <string>
9 #include <vector>
10
11
12 #define user_expr user_expr_1
13
14 /// [USER_UNARY_OPERATOR]
15 template <boost::yap::expr_kind Kind, typename Tuple>
16 struct user_expr
17 {
18 static const boost::yap::expr_kind kind = Kind;
19
20 Tuple elements;
21 };
22
23 // Operator overloads for operator!().
24 BOOST_YAP_USER_UNARY_OPERATOR(logical_not, user_expr, user_expr)
25 /// [USER_UNARY_OPERATOR]
26
27 struct lazy_vector_1 :
28 user_expr<
29 boost::yap::expr_kind::terminal,
30 boost::hana::tuple<std::vector<double>>
31 >
32 {};
33
34 #undef user_expr
35
36 #define user_expr user_expr_2
37
38 /// [USER_BINARY_OPERATOR]
39 template <boost::yap::expr_kind Kind, typename Tuple>
40 struct user_expr
41 {
42 static const boost::yap::expr_kind kind = Kind;
43
44 Tuple elements;
45 };
46
47 // Operator overloads for operator&&()
48 BOOST_YAP_USER_BINARY_OPERATOR(logical_and, user_expr, user_expr)
49 /// [USER_BINARY_OPERATOR]
50
51 struct lazy_vector_2 :
52 user_expr<
53 boost::yap::expr_kind::terminal,
54 boost::hana::tuple<std::vector<double>>
55 >
56 {};
57
58 #undef user_expr
59
60 #define user_expr user_expr_3
61
62 /// [USER_CALL_OPERATOR]
63 template <boost::yap::expr_kind Kind, typename Tuple>
64 struct user_expr
65 {
66 static const boost::yap::expr_kind kind = Kind;
67
68 Tuple elements;
69
70 // Member operator overloads for operator()(). These will match any
71 // number of parameters. Each one can be any type, even another
72 // expression.
73 BOOST_YAP_USER_CALL_OPERATOR(::user_expr)
74 };
75 /// [USER_CALL_OPERATOR]
76
77 struct lazy_vector_3 :
78 user_expr<
79 boost::yap::expr_kind::terminal,
80 boost::hana::tuple<std::vector<double>>
81 >
82 {};
83
84 #undef user_expr
85
86 #define user_expr user_expr_4
87
88 /// [USER_SUBSCRIPT_OPERATOR]
89 template <boost::yap::expr_kind Kind, typename Tuple>
90 struct user_expr
91 {
92 static const boost::yap::expr_kind kind = Kind;
93
94 Tuple elements;
95
96 // Member operator overloads for operator[](). These will match any value
97 // on the right-hand side, even another expression.
98 BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::user_expr)
99 };
100
101 /// [USER_SUBSCRIPT_OPERATOR]
102
103 struct lazy_vector_4 :
104 user_expr<
105 boost::yap::expr_kind::terminal,
106 boost::hana::tuple<std::vector<double>>
107 >
108 {};
109
110 #undef user_expr
111
112 #define user_expr user_expr_5
113
114 /// [USER_EXPR_IF_ELSE]
115 template <boost::yap::expr_kind Kind, typename Tuple>
116 struct user_expr
117 {
118 static const boost::yap::expr_kind kind = Kind;
119
120 Tuple elements;
121 };
122
123 // Defines an overload of if_else() that returns expressions instantiated from
124 // user_expr.
125 BOOST_YAP_USER_EXPR_IF_ELSE(::user_expr)
126 /// [USER_EXPR_IF_ELSE]
127
128 struct lazy_vector_5 :
129 user_expr<
130 boost::yap::expr_kind::terminal,
131 boost::hana::tuple<std::vector<double>>
132 >
133 {};
134
135 #undef user_expr
136
137 #define user_expr user_expr_6
138 #define is_vector is_vector_1
139
140 /// [USER_UDT_ANY_IF_ELSE]
141 template <boost::yap::expr_kind Kind, typename Tuple>
142 struct user_expr
143 {
144 static const boost::yap::expr_kind kind = Kind;
145
146 Tuple elements;
147 };
148
149 template <typename T>
150 struct is_vector : std::false_type {};
151
152 template <typename T, typename A>
153 struct is_vector<std::vector<T, A>> : std::true_type {};
154
155 // Defines an overload of if_else() that returns expressions instantiated from
156 // user_expr.
157 BOOST_YAP_USER_UDT_ANY_IF_ELSE(::user_expr, is_vector)
158 /// [USER_UDT_ANY_IF_ELSE]
159
160 struct lazy_vector_6 :
161 user_expr<
162 boost::yap::expr_kind::terminal,
163 boost::hana::tuple<std::vector<double>>
164 >
165 {};
166
167 #undef is_vector
168 #undef user_expr
169
170 #define user_expr user_expr_7
171 #define is_vector is_vector_2
172
173 /// [USER_UDT_UNARY_OPERATOR]
174 template <boost::yap::expr_kind Kind, typename Tuple>
175 struct user_expr
176 {
177 static const boost::yap::expr_kind kind = Kind;
178
179 Tuple elements;
180 };
181
182 template <typename T>
183 struct is_vector : std::false_type {};
184
185 template <typename T, typename A>
186 struct is_vector<std::vector<T, A>> : std::true_type {};
187
188 // Defines an overload of operator!() that applies to vectors and returns
189 // expressions instantiated from user_expr.
190 BOOST_YAP_USER_UDT_UNARY_OPERATOR(logical_not, ::user_expr, is_vector)
191 /// [USER_UDT_UNARY_OPERATOR]
192
193 struct lazy_vector_7 :
194 user_expr<
195 boost::yap::expr_kind::terminal,
196 boost::hana::tuple<std::vector<double>>
197 >
198 {};
199
200 #undef is_vector
201 #undef user_expr
202
203 #define user_expr user_expr_8
204 #define is_vector is_vector_3
205
206 /// [USER_UDT_UDT_BINARY_OPERATOR]
207 template <boost::yap::expr_kind Kind, typename Tuple>
208 struct user_expr
209 {
210 static const boost::yap::expr_kind kind = Kind;
211
212 Tuple elements;
213 };
214
215 template <typename T>
216 struct is_vector : std::false_type {};
217
218 template <typename T, typename A>
219 struct is_vector<std::vector<T, A>> : std::true_type {};
220
221 template <typename T>
222 struct is_string : std::false_type {};
223
224 template <>
225 struct is_string<std::string> : std::true_type {};
226
227 // Defines an overload of operator||() that applies to vectors on the left and
228 // strings on the right, and returns expressions instantiated from user_expr.
229 BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR(logical_or, ::user_expr, is_vector, is_string)
230
231 // Defines an overload of operator&&() that applies to strings and returns
232 // expressions instantiated from user_expr.
233 BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR(logical_and, ::user_expr, is_string, is_string)
234 /// [USER_UDT_UDT_BINARY_OPERATOR]
235
236 struct lazy_vector_8 :
237 user_expr<
238 boost::yap::expr_kind::terminal,
239 boost::hana::tuple<std::vector<double>>
240 >
241 {};
242
243 #undef is_vector
244 #undef user_expr
245
246 #define user_expr user_expr_9
247 #define is_vector is_vector_4
248
249 /// [USER_UDT_ANY_BINARY_OPERATOR]
250 template <boost::yap::expr_kind Kind, typename Tuple>
251 struct user_expr
252 {
253 static const boost::yap::expr_kind kind = Kind;
254
255 Tuple elements;
256 };
257
258 template <typename T>
259 struct is_vector : std::false_type {};
260
261 template <typename T, typename A>
262 struct is_vector<std::vector<T, A>> : std::true_type {};
263
264 // Defines an overload of operator&&() that matches a vector on either side,
265 // and any type (possibly a vector) on the other.
266 BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(logical_and, ::user_expr, is_vector)
267 /// [USER_UDT_ANY_BINARY_OPERATOR]
268
269 struct lazy_vector_9 :
270 user_expr<
271 boost::yap::expr_kind::terminal,
272 boost::hana::tuple<std::vector<double>>
273 >
274 {};
275
276 #undef is_vector
277 #undef user_expr
278
279 #define user_expr user_expr_10
280
281 /// [USER_LITERAL_PLACEHOLDER_OPERATOR]
282 template <boost::yap::expr_kind Kind, typename Tuple>
283 struct user_expr
284 {
285 static const boost::yap::expr_kind kind = Kind;
286
287 Tuple elements;
288 };
289
290 namespace literals {
291
292 // Defines a user literal operator that makes placeholders; 2_p will be a
293 // 2-placeholder instantiated from the user_expr template.
294 BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR(user_expr)
295
296 }
297 /// [USER_LITERAL_PLACEHOLDER_OPERATOR]
298
299 struct lazy_vector_10 :
300 user_expr<
301 boost::yap::expr_kind::terminal,
302 boost::hana::tuple<std::vector<double>>
303 >
304 {};
305
306 #undef user_expr
307
308 #define user_expr user_expr_11
309
310 /// [USER_ASSIGN_OPERATOR]
311 template <boost::yap::expr_kind Kind, typename Tuple>
312 struct user_expr
313 {
314 static const boost::yap::expr_kind kind = Kind;
315
316 Tuple elements;
317
318 // Member operator overloads for operator=(). These will match any value
319 // on the right-hand side, even another expression, except that it will
320 // not conflict with the asignment or move assignment operators.
321 BOOST_YAP_USER_ASSIGN_OPERATOR(user_expr, ::user_expr)
322 };
323 /// [USER_ASSIGN_OPERATOR]
324
325 struct lazy_vector_11 :
326 user_expr<
327 boost::yap::expr_kind::terminal,
328 boost::hana::tuple<std::vector<double>>
329 >
330 {};
331
332 #undef user_expr
333
334 #undef user_expr
335
336 #define user_expr user_expr_12
337
338 /// [USER_CALL_OPERATOR]
339 template <boost::yap::expr_kind Kind, typename Tuple>
340 struct user_expr
341 {
342 static const boost::yap::expr_kind kind = Kind;
343
344 Tuple elements;
345
346 // Member operator overloads for operator()(). These will take exactly N
347 // parameters. Each one can be any type, even another expression.
348 BOOST_YAP_USER_CALL_OPERATOR(::user_expr)
349 };
350 /// [USER_CALL_OPERATOR]
351
352 struct lazy_vector_12 :
353 user_expr<
354 boost::yap::expr_kind::terminal,
355 boost::hana::tuple<std::vector<double>>
356 >
357 {};
358
359
main()360 int main ()
361 {
362 lazy_vector_1 v1;
363 lazy_vector_2 v2;
364 lazy_vector_3 v3;
365 lazy_vector_4 v4;
366 lazy_vector_5 v5;
367 lazy_vector_6 v6;
368 lazy_vector_7 v7;
369 lazy_vector_8 v8;
370 lazy_vector_9 v9;
371 lazy_vector_10 v10;
372 lazy_vector_11 v11;
373 lazy_vector_12 v12;
374
375 return 0;
376 }
377