Chris@102
|
1 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 // lazy operator.hpp
|
Chris@102
|
3 //
|
Chris@102
|
4 // Build lazy operations for Phoenix equivalents for FC++
|
Chris@102
|
5 //
|
Chris@102
|
6 // These are equivalents of the Boost FC++ functoids in operator.hpp
|
Chris@102
|
7 //
|
Chris@102
|
8 // Implemented so far:
|
Chris@102
|
9 //
|
Chris@102
|
10 // make_pair
|
Chris@102
|
11 // plus minus multiplies divides modulus
|
Chris@102
|
12 // negate equal not_equal greater less
|
Chris@102
|
13 // greater_equal less_equal logical_and logical_or
|
Chris@102
|
14 // logical_not min max inc dec
|
Chris@102
|
15 //
|
Chris@102
|
16 // These are not from the FC++ operator.hpp but were made for testing purposes.
|
Chris@102
|
17 //
|
Chris@102
|
18 // identity (renamed id)
|
Chris@102
|
19 // sin
|
Chris@102
|
20 //
|
Chris@102
|
21 // These are now being modified to use boost::phoenix::function
|
Chris@102
|
22 // so that they are available for use as arguments.
|
Chris@102
|
23 // Types are being defined in capitals e.g. Id id;
|
Chris@102
|
24 ////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
25 /*=============================================================================
|
Chris@102
|
26 Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
|
Chris@102
|
27 Copyright (c) 2001-2007 Joel de Guzman
|
Chris@102
|
28 Copyright (c) 2015 John Fletcher
|
Chris@102
|
29
|
Chris@102
|
30 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
31 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
32 ==============================================================================*/
|
Chris@102
|
33
|
Chris@102
|
34
|
Chris@102
|
35 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
|
Chris@102
|
36 #define BOOST_PHOENIX_FUNCTION_LAZY_OPERATOR
|
Chris@102
|
37
|
Chris@102
|
38 #include <cmath>
|
Chris@102
|
39 #include <cstdlib>
|
Chris@102
|
40 #include <boost/phoenix/core.hpp>
|
Chris@102
|
41 #include <boost/phoenix/function.hpp>
|
Chris@102
|
42 #include <boost/function.hpp>
|
Chris@102
|
43
|
Chris@102
|
44 namespace boost {
|
Chris@102
|
45
|
Chris@102
|
46 namespace phoenix {
|
Chris@102
|
47
|
Chris@102
|
48 //////////////////////////////////////////////////////////////////////
|
Chris@102
|
49 // a_unique_type_for_nil
|
Chris@102
|
50 //////////////////////////////////////////////////////////////////////
|
Chris@102
|
51
|
Chris@102
|
52 // This may need to be moved elsewhere to define reuser.
|
Chris@102
|
53 struct a_unique_type_for_nil {
|
Chris@102
|
54 bool operator==( a_unique_type_for_nil ) const { return true; }
|
Chris@102
|
55 bool operator< ( a_unique_type_for_nil ) const { return false; }
|
Chris@102
|
56 typedef a_unique_type_for_nil value_type;
|
Chris@102
|
57 };
|
Chris@102
|
58 // This maybe put into a namespace.
|
Chris@102
|
59 a_unique_type_for_nil NIL;
|
Chris@102
|
60
|
Chris@102
|
61 //////////////////////////////////////////////////////////////////////
|
Chris@102
|
62 // lazy_exception - renamed from fcpp_exception.
|
Chris@102
|
63 //////////////////////////////////////////////////////////////////////
|
Chris@102
|
64
|
Chris@102
|
65 #ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
|
Chris@102
|
66 struct lazy_exception : public std::exception {
|
Chris@102
|
67 const char* s;
|
Chris@102
|
68 lazy_exception( const char* ss ) : s(ss) {}
|
Chris@102
|
69 const char* what() const throw() { return s; }
|
Chris@102
|
70 };
|
Chris@102
|
71 #endif
|
Chris@102
|
72
|
Chris@102
|
73 //////////////////////////////////////////////////////////////////////
|
Chris@102
|
74
|
Chris@102
|
75 // in ref_count.hpp in BoostFC++
|
Chris@102
|
76 typedef unsigned int RefCountType;
|
Chris@102
|
77
|
Chris@102
|
78 namespace impl {
|
Chris@102
|
79
|
Chris@102
|
80 struct Id
|
Chris@102
|
81 {
|
Chris@102
|
82 template <typename Sig>
|
Chris@102
|
83 struct result;
|
Chris@102
|
84
|
Chris@102
|
85 template <typename This, typename A0>
|
Chris@102
|
86 struct result<This(A0)>
|
Chris@102
|
87 : boost::remove_reference<A0>
|
Chris@102
|
88 {};
|
Chris@102
|
89
|
Chris@102
|
90 template <typename A0>
|
Chris@102
|
91 A0 operator()(A0 const & a0) const
|
Chris@102
|
92 {
|
Chris@102
|
93 return a0;
|
Chris@102
|
94 }
|
Chris@102
|
95
|
Chris@102
|
96 };
|
Chris@102
|
97
|
Chris@102
|
98
|
Chris@102
|
99 }
|
Chris@102
|
100
|
Chris@102
|
101 //BOOST_PHOENIX_ADAPT_CALLABLE(id, impl::id, 1)
|
Chris@102
|
102 typedef boost::phoenix::function<impl::Id> Id;
|
Chris@102
|
103 Id id;
|
Chris@102
|
104
|
Chris@102
|
105 #ifdef BOOST_RESULT_OF_USE_TR1
|
Chris@102
|
106 // Experiment following examples in
|
Chris@102
|
107 // phoenix/stl/container/container.hpp
|
Chris@102
|
108
|
Chris@102
|
109 namespace result_of {
|
Chris@102
|
110
|
Chris@102
|
111 template <
|
Chris@102
|
112 typename Arg1
|
Chris@102
|
113 , typename Arg2
|
Chris@102
|
114 >
|
Chris@102
|
115 class make_pair
|
Chris@102
|
116 {
|
Chris@102
|
117 public:
|
Chris@102
|
118 typedef typename boost::remove_reference<Arg1>::type Arg1Type;
|
Chris@102
|
119 typedef typename boost::remove_reference<Arg2>::type Arg2Type;
|
Chris@102
|
120 typedef std::pair<Arg1Type,Arg2Type> type;
|
Chris@102
|
121 typedef std::pair<Arg1Type,Arg2Type> result_type;
|
Chris@102
|
122 };
|
Chris@102
|
123 }
|
Chris@102
|
124 #endif
|
Chris@102
|
125
|
Chris@102
|
126 namespace impl
|
Chris@102
|
127 {
|
Chris@102
|
128
|
Chris@102
|
129 struct make_pair {
|
Chris@102
|
130
|
Chris@102
|
131
|
Chris@102
|
132 #ifdef BOOST_RESULT_OF_USE_TR1
|
Chris@102
|
133 template <typename Sig>
|
Chris@102
|
134 struct result;
|
Chris@102
|
135 // This fails with -O2 unless refs are removed from A1 and A2.
|
Chris@102
|
136 template <typename This, typename A0, typename A1>
|
Chris@102
|
137 struct result<This(A0, A1)>
|
Chris@102
|
138 {
|
Chris@102
|
139 typedef typename result_of::make_pair<A0,A1>::type type;
|
Chris@102
|
140 };
|
Chris@102
|
141 #else
|
Chris@102
|
142 template <typename Sig>
|
Chris@102
|
143 struct result;
|
Chris@102
|
144
|
Chris@102
|
145 template <typename This, typename A0, typename A1>
|
Chris@102
|
146 struct result<This(A0, A1)>
|
Chris@102
|
147 : boost::remove_reference<std::pair<A0, A1> >
|
Chris@102
|
148 {};
|
Chris@102
|
149
|
Chris@102
|
150 #endif
|
Chris@102
|
151
|
Chris@102
|
152
|
Chris@102
|
153 template <typename A0, typename A1>
|
Chris@102
|
154 #ifdef BOOST_RESULT_OF_USE_TR1
|
Chris@102
|
155 typename result<make_pair(A0,A1)>::type
|
Chris@102
|
156 #else
|
Chris@102
|
157 std::pair<A0, A1>
|
Chris@102
|
158 #endif
|
Chris@102
|
159 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
160 {
|
Chris@102
|
161 return std::make_pair(a0,a1);
|
Chris@102
|
162 }
|
Chris@102
|
163
|
Chris@102
|
164 };
|
Chris@102
|
165 }
|
Chris@102
|
166
|
Chris@102
|
167 BOOST_PHOENIX_ADAPT_CALLABLE(make_pair, impl::make_pair, 2)
|
Chris@102
|
168
|
Chris@102
|
169 namespace impl
|
Chris@102
|
170 {
|
Chris@102
|
171
|
Chris@102
|
172 // For now I will leave the return type deduction as it is.
|
Chris@102
|
173 // I want to look at bringing in the sort of type deduction for
|
Chris@102
|
174 // mixed types which I have in FC++.
|
Chris@102
|
175 // Also I could look at the case where one of the arguments is
|
Chris@102
|
176 // another functor or a Phoenix placeholder.
|
Chris@102
|
177 struct Plus
|
Chris@102
|
178 {
|
Chris@102
|
179 template <typename Sig>
|
Chris@102
|
180 struct result;
|
Chris@102
|
181
|
Chris@102
|
182 template <typename This, typename A0, typename A1>
|
Chris@102
|
183 struct result<This(A0, A1)>
|
Chris@102
|
184 : boost::remove_reference<A0>
|
Chris@102
|
185 {};
|
Chris@102
|
186
|
Chris@102
|
187 template <typename This, typename A0, typename A1, typename A2>
|
Chris@102
|
188 struct result<This(A0, A1, A2)>
|
Chris@102
|
189 : boost::remove_reference<A0>
|
Chris@102
|
190 {};
|
Chris@102
|
191
|
Chris@102
|
192 template <typename A0, typename A1>
|
Chris@102
|
193 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
194 {
|
Chris@102
|
195 //A0 res = a0 + a1;
|
Chris@102
|
196 //return res;
|
Chris@102
|
197 return a0 + a1;
|
Chris@102
|
198 }
|
Chris@102
|
199
|
Chris@102
|
200 template <typename A0, typename A1, typename A2>
|
Chris@102
|
201 A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const
|
Chris@102
|
202 {
|
Chris@102
|
203 return a0 + a1 + a2;
|
Chris@102
|
204 }
|
Chris@102
|
205 };
|
Chris@102
|
206
|
Chris@102
|
207 struct Minus
|
Chris@102
|
208 {
|
Chris@102
|
209 template <typename Sig>
|
Chris@102
|
210 struct result;
|
Chris@102
|
211
|
Chris@102
|
212 template <typename This, typename A0, typename A1>
|
Chris@102
|
213 struct result<This(A0, A1)>
|
Chris@102
|
214 : boost::remove_reference<A0>
|
Chris@102
|
215 {};
|
Chris@102
|
216
|
Chris@102
|
217 template <typename A0, typename A1>
|
Chris@102
|
218 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
219 {
|
Chris@102
|
220 return a0 - a1;
|
Chris@102
|
221 }
|
Chris@102
|
222
|
Chris@102
|
223 };
|
Chris@102
|
224
|
Chris@102
|
225 struct multiplies
|
Chris@102
|
226 {
|
Chris@102
|
227 template <typename Sig>
|
Chris@102
|
228 struct result;
|
Chris@102
|
229
|
Chris@102
|
230 template <typename This, typename A0, typename A1>
|
Chris@102
|
231 struct result<This(A0, A1)>
|
Chris@102
|
232 : boost::remove_reference<A0>
|
Chris@102
|
233 {};
|
Chris@102
|
234
|
Chris@102
|
235 template <typename A0, typename A1>
|
Chris@102
|
236 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
237 {
|
Chris@102
|
238 return a0 * a1;
|
Chris@102
|
239 }
|
Chris@102
|
240
|
Chris@102
|
241 };
|
Chris@102
|
242
|
Chris@102
|
243 struct divides
|
Chris@102
|
244 {
|
Chris@102
|
245 template <typename Sig>
|
Chris@102
|
246 struct result;
|
Chris@102
|
247
|
Chris@102
|
248 template <typename This, typename A0, typename A1>
|
Chris@102
|
249 struct result<This(A0, A1)>
|
Chris@102
|
250 : boost::remove_reference<A0>
|
Chris@102
|
251 {};
|
Chris@102
|
252
|
Chris@102
|
253 template <typename A0, typename A1>
|
Chris@102
|
254 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
255 {
|
Chris@102
|
256 return a0 / a1;
|
Chris@102
|
257 }
|
Chris@102
|
258
|
Chris@102
|
259 };
|
Chris@102
|
260
|
Chris@102
|
261 struct modulus
|
Chris@102
|
262 {
|
Chris@102
|
263 template <typename Sig>
|
Chris@102
|
264 struct result;
|
Chris@102
|
265
|
Chris@102
|
266 template <typename This, typename A0, typename A1>
|
Chris@102
|
267 struct result<This(A0, A1)>
|
Chris@102
|
268 : boost::remove_reference<A0>
|
Chris@102
|
269 {};
|
Chris@102
|
270
|
Chris@102
|
271 template <typename A0, typename A1>
|
Chris@102
|
272 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
273 {
|
Chris@102
|
274 return a0 % a1;
|
Chris@102
|
275 }
|
Chris@102
|
276
|
Chris@102
|
277 };
|
Chris@102
|
278
|
Chris@102
|
279 struct negate
|
Chris@102
|
280 {
|
Chris@102
|
281 template <typename Sig>
|
Chris@102
|
282 struct result;
|
Chris@102
|
283
|
Chris@102
|
284 template <typename This, typename A0>
|
Chris@102
|
285 struct result<This(A0)>
|
Chris@102
|
286 : boost::remove_reference<A0>
|
Chris@102
|
287 {};
|
Chris@102
|
288
|
Chris@102
|
289 template <typename A0>
|
Chris@102
|
290 A0 operator()(A0 const & a0) const
|
Chris@102
|
291 {
|
Chris@102
|
292 return -a0;
|
Chris@102
|
293 }
|
Chris@102
|
294 };
|
Chris@102
|
295
|
Chris@102
|
296 struct equal
|
Chris@102
|
297 {
|
Chris@102
|
298 template <typename Sig>
|
Chris@102
|
299 struct result;
|
Chris@102
|
300
|
Chris@102
|
301 template <typename This, typename A0, typename A1>
|
Chris@102
|
302 struct result<This(A0,A1)>
|
Chris@102
|
303 {
|
Chris@102
|
304 typedef bool type;
|
Chris@102
|
305 };
|
Chris@102
|
306
|
Chris@102
|
307 template <typename A0, typename A1>
|
Chris@102
|
308 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
309 {
|
Chris@102
|
310 return a0 == a1;
|
Chris@102
|
311 }
|
Chris@102
|
312 };
|
Chris@102
|
313
|
Chris@102
|
314 struct not_equal
|
Chris@102
|
315 {
|
Chris@102
|
316 template <typename Sig>
|
Chris@102
|
317 struct result;
|
Chris@102
|
318
|
Chris@102
|
319 template <typename This, typename A0, typename A1>
|
Chris@102
|
320 struct result<This(A0,A1)>
|
Chris@102
|
321 {
|
Chris@102
|
322 typedef bool type;
|
Chris@102
|
323 };
|
Chris@102
|
324
|
Chris@102
|
325 template <typename A0, typename A1>
|
Chris@102
|
326 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
327 {
|
Chris@102
|
328 return a0 != a1;
|
Chris@102
|
329 }
|
Chris@102
|
330 };
|
Chris@102
|
331
|
Chris@102
|
332 struct greater
|
Chris@102
|
333 {
|
Chris@102
|
334 template <typename Sig>
|
Chris@102
|
335 struct result;
|
Chris@102
|
336
|
Chris@102
|
337 template <typename This, typename A0, typename A1>
|
Chris@102
|
338 struct result<This(A0,A1)>
|
Chris@102
|
339 {
|
Chris@102
|
340 typedef bool type;
|
Chris@102
|
341 };
|
Chris@102
|
342
|
Chris@102
|
343 template <typename A0, typename A1>
|
Chris@102
|
344 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
345 {
|
Chris@102
|
346 return a0 > a1;
|
Chris@102
|
347 }
|
Chris@102
|
348 };
|
Chris@102
|
349
|
Chris@102
|
350 struct less
|
Chris@102
|
351 {
|
Chris@102
|
352 template <typename Sig>
|
Chris@102
|
353 struct result;
|
Chris@102
|
354
|
Chris@102
|
355 template <typename This, typename A0, typename A1>
|
Chris@102
|
356 struct result<This(A0,A1)>
|
Chris@102
|
357 {
|
Chris@102
|
358 typedef bool type;
|
Chris@102
|
359 };
|
Chris@102
|
360
|
Chris@102
|
361 template <typename A0, typename A1>
|
Chris@102
|
362 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
363 {
|
Chris@102
|
364 return a0 < a1;
|
Chris@102
|
365 }
|
Chris@102
|
366 };
|
Chris@102
|
367
|
Chris@102
|
368 struct greater_equal
|
Chris@102
|
369 {
|
Chris@102
|
370 template <typename Sig>
|
Chris@102
|
371 struct result;
|
Chris@102
|
372
|
Chris@102
|
373 template <typename This, typename A0, typename A1>
|
Chris@102
|
374 struct result<This(A0,A1)>
|
Chris@102
|
375 {
|
Chris@102
|
376 typedef bool type;
|
Chris@102
|
377 };
|
Chris@102
|
378
|
Chris@102
|
379 template <typename A0, typename A1>
|
Chris@102
|
380 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
381 {
|
Chris@102
|
382 return a0 >= a1;
|
Chris@102
|
383 }
|
Chris@102
|
384 };
|
Chris@102
|
385
|
Chris@102
|
386 struct less_equal
|
Chris@102
|
387 {
|
Chris@102
|
388 template <typename Sig>
|
Chris@102
|
389 struct result;
|
Chris@102
|
390
|
Chris@102
|
391 template <typename This, typename A0, typename A1>
|
Chris@102
|
392 struct result<This(A0,A1)>
|
Chris@102
|
393 {
|
Chris@102
|
394 typedef bool type;
|
Chris@102
|
395 };
|
Chris@102
|
396
|
Chris@102
|
397 template <typename A0, typename A1>
|
Chris@102
|
398 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
399 {
|
Chris@102
|
400 return a0 <= a1;
|
Chris@102
|
401 }
|
Chris@102
|
402 };
|
Chris@102
|
403
|
Chris@102
|
404 struct logical_and
|
Chris@102
|
405 {
|
Chris@102
|
406 template <typename Sig>
|
Chris@102
|
407 struct result;
|
Chris@102
|
408
|
Chris@102
|
409 template <typename This, typename A0, typename A1>
|
Chris@102
|
410 struct result<This(A0,A1)>
|
Chris@102
|
411 {
|
Chris@102
|
412 typedef bool type;
|
Chris@102
|
413 };
|
Chris@102
|
414
|
Chris@102
|
415 template <typename A0, typename A1>
|
Chris@102
|
416 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
417 {
|
Chris@102
|
418 return a0 && a1;
|
Chris@102
|
419 }
|
Chris@102
|
420 };
|
Chris@102
|
421
|
Chris@102
|
422 struct logical_or
|
Chris@102
|
423 {
|
Chris@102
|
424 template <typename Sig>
|
Chris@102
|
425 struct result;
|
Chris@102
|
426
|
Chris@102
|
427 template <typename This, typename A0, typename A1>
|
Chris@102
|
428 struct result<This(A0,A1)>
|
Chris@102
|
429 {
|
Chris@102
|
430 typedef bool type;
|
Chris@102
|
431 };
|
Chris@102
|
432
|
Chris@102
|
433 template <typename A0, typename A1>
|
Chris@102
|
434 bool operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
435 {
|
Chris@102
|
436 return a0 || a1;
|
Chris@102
|
437 }
|
Chris@102
|
438 };
|
Chris@102
|
439
|
Chris@102
|
440 struct logical_not
|
Chris@102
|
441 {
|
Chris@102
|
442 template <typename Sig>
|
Chris@102
|
443 struct result;
|
Chris@102
|
444
|
Chris@102
|
445 template <typename This, typename A0>
|
Chris@102
|
446 struct result<This(A0)>
|
Chris@102
|
447 {
|
Chris@102
|
448 typedef bool type;
|
Chris@102
|
449 };
|
Chris@102
|
450
|
Chris@102
|
451 template <typename A0>
|
Chris@102
|
452 bool operator()(A0 const & a0) const
|
Chris@102
|
453 {
|
Chris@102
|
454 return !a0;
|
Chris@102
|
455 }
|
Chris@102
|
456 };
|
Chris@102
|
457
|
Chris@102
|
458 struct min
|
Chris@102
|
459 {
|
Chris@102
|
460 template <typename Sig>
|
Chris@102
|
461 struct result;
|
Chris@102
|
462
|
Chris@102
|
463 template <typename This, typename A0, typename A1>
|
Chris@102
|
464 struct result<This(A0, A1)>
|
Chris@102
|
465 : boost::remove_reference<A0>
|
Chris@102
|
466 {};
|
Chris@102
|
467
|
Chris@102
|
468 template <typename A0, typename A1>
|
Chris@102
|
469 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
470 {
|
Chris@102
|
471 if ( a0 < a1 ) return a0; else return a1;
|
Chris@102
|
472 }
|
Chris@102
|
473
|
Chris@102
|
474 };
|
Chris@102
|
475
|
Chris@102
|
476 struct max
|
Chris@102
|
477 {
|
Chris@102
|
478 template <typename Sig>
|
Chris@102
|
479 struct result;
|
Chris@102
|
480
|
Chris@102
|
481 template <typename This, typename A0, typename A1>
|
Chris@102
|
482 struct result<This(A0, A1)>
|
Chris@102
|
483 : boost::remove_reference<A0>
|
Chris@102
|
484 {};
|
Chris@102
|
485
|
Chris@102
|
486 template <typename A0, typename A1>
|
Chris@102
|
487 A0 operator()(A0 const & a0, A1 const & a1) const
|
Chris@102
|
488 {
|
Chris@102
|
489 if ( a0 < a1 ) return a1; else return a0;
|
Chris@102
|
490 }
|
Chris@102
|
491
|
Chris@102
|
492 };
|
Chris@102
|
493
|
Chris@102
|
494 struct Inc
|
Chris@102
|
495 {
|
Chris@102
|
496 template <typename Sig>
|
Chris@102
|
497 struct result;
|
Chris@102
|
498
|
Chris@102
|
499 template <typename This, typename A0>
|
Chris@102
|
500 struct result<This(A0)>
|
Chris@102
|
501 : boost::remove_reference<A0>
|
Chris@102
|
502 {};
|
Chris@102
|
503
|
Chris@102
|
504 template <typename A0>
|
Chris@102
|
505 A0 operator()(A0 const & a0) const
|
Chris@102
|
506 {
|
Chris@102
|
507 return a0 + 1;
|
Chris@102
|
508 }
|
Chris@102
|
509
|
Chris@102
|
510 };
|
Chris@102
|
511
|
Chris@102
|
512 struct Dec
|
Chris@102
|
513 {
|
Chris@102
|
514 template <typename Sig>
|
Chris@102
|
515 struct result;
|
Chris@102
|
516
|
Chris@102
|
517 template <typename This, typename A0>
|
Chris@102
|
518 struct result<This(A0)>
|
Chris@102
|
519 : boost::remove_reference<A0>
|
Chris@102
|
520 {};
|
Chris@102
|
521
|
Chris@102
|
522 template <typename A0>
|
Chris@102
|
523 A0 operator()(A0 const & a0) const
|
Chris@102
|
524 {
|
Chris@102
|
525 return a0 - 1;
|
Chris@102
|
526 }
|
Chris@102
|
527
|
Chris@102
|
528 };
|
Chris@102
|
529
|
Chris@102
|
530 struct Sin
|
Chris@102
|
531 {
|
Chris@102
|
532 template <typename Sig>
|
Chris@102
|
533 struct result;
|
Chris@102
|
534
|
Chris@102
|
535 template <typename This, typename A0>
|
Chris@102
|
536 struct result<This(A0)>
|
Chris@102
|
537 : boost::remove_reference<A0>
|
Chris@102
|
538 {};
|
Chris@102
|
539
|
Chris@102
|
540 template <typename A0>
|
Chris@102
|
541 A0 operator()(A0 const & a0) const
|
Chris@102
|
542 {
|
Chris@102
|
543 return std::sin(a0);
|
Chris@102
|
544 }
|
Chris@102
|
545
|
Chris@102
|
546 };
|
Chris@102
|
547
|
Chris@102
|
548 // Example of templated struct.
|
Chris@102
|
549 // How do I make it callable?
|
Chris@102
|
550 template <typename Result>
|
Chris@102
|
551 struct what {
|
Chris@102
|
552
|
Chris@102
|
553 typedef Result result_type;
|
Chris@102
|
554
|
Chris@102
|
555 Result operator()(Result const & r) const
|
Chris@102
|
556 {
|
Chris@102
|
557 return r;
|
Chris@102
|
558 }
|
Chris@102
|
559 // what is not complete - error.
|
Chris@102
|
560 //static boost::function1<Result,Result> res = what<Result>();
|
Chris@102
|
561 };
|
Chris@102
|
562
|
Chris@102
|
563 template <typename Result>
|
Chris@102
|
564 struct what0 {
|
Chris@102
|
565
|
Chris@102
|
566 typedef Result result_type;
|
Chris@102
|
567
|
Chris@102
|
568 Result operator()() const
|
Chris@102
|
569 {
|
Chris@102
|
570 return Result(100);
|
Chris@102
|
571 }
|
Chris@102
|
572
|
Chris@102
|
573 };
|
Chris@102
|
574
|
Chris@102
|
575 template <class Result, class F>
|
Chris@102
|
576 class MonomorphicWrapper0 /* : public c_fun_type<Res> */
|
Chris@102
|
577 {
|
Chris@102
|
578 F f;
|
Chris@102
|
579 public:
|
Chris@102
|
580 typedef Result result_type;
|
Chris@102
|
581 MonomorphicWrapper0( const F& g ) : f(g) {}
|
Chris@102
|
582 Result operator()() const {
|
Chris@102
|
583 return f();
|
Chris@102
|
584 }
|
Chris@102
|
585 };
|
Chris@102
|
586
|
Chris@102
|
587 /* I need the equivalent of this
|
Chris@102
|
588 template <class Res, class F>
|
Chris@102
|
589 full0<impl::XMonomorphicWrapper0<Res,F> > monomorphize0( const F& f )
|
Chris@102
|
590 {
|
Chris@102
|
591 return make_full0( impl::XMonomorphicWrapper0<Res,F>( f ) );
|
Chris@102
|
592 }*/
|
Chris@102
|
593
|
Chris@102
|
594
|
Chris@102
|
595 // boost::function0<int> res = MonomorphicWrapper0<int,F>(f);
|
Chris@102
|
596
|
Chris@102
|
597
|
Chris@102
|
598 template <class Res, class F>
|
Chris@102
|
599 boost::function<Res()> monomorphize0( const F& f )
|
Chris@102
|
600 {
|
Chris@102
|
601 boost::function0<Res> ff = MonomorphicWrapper0<Res,F>( f );
|
Chris@102
|
602 //BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(Res,fres,ff)
|
Chris@102
|
603 return ff;
|
Chris@102
|
604 }
|
Chris@102
|
605
|
Chris@102
|
606 // This is C++1y
|
Chris@102
|
607 //template <typename Result>
|
Chris@102
|
608 //static boost::function1<Result,Result> res = what<Result>();
|
Chris@102
|
609
|
Chris@102
|
610
|
Chris@102
|
611 }
|
Chris@102
|
612 /////////////////////////////////////////////////////////
|
Chris@102
|
613 // Look at this. How to use Phoenix with a templated
|
Chris@102
|
614 // struct. First adapt with boost::function and then
|
Chris@102
|
615 // convert that to Phoenix!!
|
Chris@102
|
616 // I have not found out how to do it directly.
|
Chris@102
|
617 /////////////////////////////////////////////////////////
|
Chris@102
|
618 boost::function1<int, int > what_int = impl::what<int>();
|
Chris@102
|
619 typedef boost::function1<int,int> fun1_int_int;
|
Chris@102
|
620 typedef boost::function0<int> fun0_int;
|
Chris@102
|
621 boost::function0<int> what0_int = impl::what0<int>();
|
Chris@102
|
622 BOOST_PHOENIX_ADAPT_FUNCTION(int,what,what_int,1)
|
Chris@102
|
623 BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int,what0,what0_int)
|
Chris@102
|
624 // And this shows how to make them into argument callable functions.
|
Chris@102
|
625 typedef boost::phoenix::function<fun1_int_int> What_arg;
|
Chris@102
|
626 typedef boost::phoenix::function<fun0_int> What0_arg;
|
Chris@102
|
627 What_arg what_arg(what_int);
|
Chris@102
|
628 What0_arg what0_arg(what0_int);
|
Chris@102
|
629
|
Chris@102
|
630 //BOOST_PHOENIX_ADAPT_CALLABLE(plus, impl::plus, 2)
|
Chris@102
|
631 //BOOST_PHOENIX_ADAPT_CALLABLE(plus, impl::plus, 3)
|
Chris@102
|
632 //BOOST_PHOENIX_ADAPT_CALLABLE(minus, impl::minus, 2)
|
Chris@102
|
633 BOOST_PHOENIX_ADAPT_CALLABLE(multiplies, impl::multiplies, 2)
|
Chris@102
|
634 BOOST_PHOENIX_ADAPT_CALLABLE(divides, impl::divides, 2)
|
Chris@102
|
635 BOOST_PHOENIX_ADAPT_CALLABLE(modulus, impl::modulus, 2)
|
Chris@102
|
636 BOOST_PHOENIX_ADAPT_CALLABLE(negate, impl::negate, 1)
|
Chris@102
|
637 BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 2)
|
Chris@102
|
638 BOOST_PHOENIX_ADAPT_CALLABLE(not_equal, impl::not_equal, 2)
|
Chris@102
|
639 BOOST_PHOENIX_ADAPT_CALLABLE(greater, impl::greater, 2)
|
Chris@102
|
640 BOOST_PHOENIX_ADAPT_CALLABLE(less, impl::less, 2)
|
Chris@102
|
641 BOOST_PHOENIX_ADAPT_CALLABLE(greater_equal, impl::greater_equal, 2)
|
Chris@102
|
642 BOOST_PHOENIX_ADAPT_CALLABLE(less_equal, impl::less_equal, 2)
|
Chris@102
|
643 BOOST_PHOENIX_ADAPT_CALLABLE(logical_and, impl::logical_and, 2)
|
Chris@102
|
644 BOOST_PHOENIX_ADAPT_CALLABLE(logical_or, impl::logical_or, 2)
|
Chris@102
|
645 BOOST_PHOENIX_ADAPT_CALLABLE(logical_not, impl::logical_not, 1)
|
Chris@102
|
646 BOOST_PHOENIX_ADAPT_CALLABLE(min, impl::min, 2)
|
Chris@102
|
647 BOOST_PHOENIX_ADAPT_CALLABLE(max, impl::max, 2)
|
Chris@102
|
648 //BOOST_PHOENIX_ADAPT_CALLABLE(inc, impl::inc, 1)
|
Chris@102
|
649 //BOOST_PHOENIX_ADAPT_CALLABLE(dec, impl::dec, 1)
|
Chris@102
|
650 //BOOST_PHOENIX_ADAPT_CALLABLE(sin, impl::sin, 1)
|
Chris@102
|
651
|
Chris@102
|
652 // To use these as arguments they have to be defined like this.
|
Chris@102
|
653 typedef boost::phoenix::function<impl::Plus> Plus;
|
Chris@102
|
654 typedef boost::phoenix::function<impl::Minus> Minus;
|
Chris@102
|
655 typedef boost::phoenix::function<impl::Inc> Inc;
|
Chris@102
|
656 typedef boost::phoenix::function<impl::Dec> Dec;
|
Chris@102
|
657 typedef boost::phoenix::function<impl::Sin> Sin;
|
Chris@102
|
658 Plus plus;
|
Chris@102
|
659 Minus minus;
|
Chris@102
|
660 Inc inc;
|
Chris@102
|
661 Dec dec;
|
Chris@102
|
662 Sin sin;
|
Chris@102
|
663 }
|
Chris@102
|
664
|
Chris@102
|
665 }
|
Chris@102
|
666
|
Chris@102
|
667
|
Chris@102
|
668
|
Chris@102
|
669
|
Chris@102
|
670 #endif
|