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