]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/phoenix/operators.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / phoenix / operators.hpp
1 /*=============================================================================
2 Phoenix V1.2.1
3 Copyright (c) 2001-2002 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #ifndef PHOENIX_OPERATORS_HPP
9 #define PHOENIX_OPERATORS_HPP
10
11 ///////////////////////////////////////////////////////////////////////////////
12 #if !defined(BOOST_NO_CWCTYPE)
13 #include <cwctype>
14 #endif
15
16 #if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700)
17 #define CREF const&
18 #else
19 #define CREF
20 #endif
21
22 #include <climits>
23 #include <boost/spirit/home/classic/phoenix/actor.hpp>
24 #include <boost/spirit/home/classic/phoenix/composite.hpp>
25 #include <boost/config.hpp>
26 #include <boost/mpl/if.hpp>
27
28 ///////////////////////////////////////////////////////////////////////////////
29 namespace phoenix {
30
31 ///////////////////////////////////////////////////////////////////////////////
32 //
33 // Operators
34 //
35 // Lazy operators
36 //
37 // This class provides a mechanism for lazily evaluating operators.
38 // Syntactically, a lazy operator looks like an ordinary C/C++
39 // infix, prefix or postfix operator. The operator application
40 // looks the same. However, unlike ordinary operators, the actual
41 // operator execution is deferred. (see actor.hpp, primitives.hpp
42 // and composite.hpp for an overview). Samples:
43 //
44 // arg1 + arg2
45 // 1 + arg1 * arg2
46 // 1 / -arg1
47 // arg1 < 150
48 //
49 // T1 set of classes implement all the C++ free operators. Like
50 // lazy functions (see functions.hpp), lazy operators are not
51 // immediately executed when invoked. Instead, a composite (see
52 // composite.hpp) object is created and returned to the caller.
53 // Example:
54 //
55 // (arg1 + arg2) * arg3
56 //
57 // does nothing more than return a composite. T1 second function
58 // call will evaluate the actual operators. Example:
59 //
60 // int i = 4, j = 5, k = 6;
61 // cout << ((arg1 + arg2) * arg3)(i, j, k);
62 //
63 // will print out "54".
64 //
65 // Arbitrarily complex expressions can be lazily evaluated
66 // following three simple rules:
67 //
68 // 1) Lazy evaluated binary operators apply when at least one
69 // of the operands is an actor object (see actor.hpp and
70 // primitives.hpp). Consequently, if an operand is not an actor
71 // object, it is implicitly converted to an object of type
72 // actor<value<T> > (where T is the original type of the
73 // operand).
74 //
75 // 2) Lazy evaluated unary operators apply only to operands
76 // which are actor objects.
77 //
78 // 3) The result of a lazy operator is a composite actor object
79 // that can in turn apply to rule 1.
80 //
81 // Example:
82 //
83 // arg1 + 3
84 //
85 // is a lazy expression involving the operator+. Following rule 1,
86 // lazy evaluation is triggered since arg1 is an instance of an
87 // actor<argument<N> > class (see primitives.hpp). The right
88 // operand <3> is implicitly converted to an actor<value<int> >.
89 // The result of this binary + expression is a composite object,
90 // following rule 3.
91 //
92 // Take note that although at least one of the operands must be a
93 // valid actor class in order for lazy evaluation to take effect,
94 // if this is not the case and we still want to lazily evaluate an
95 // expression, we can use var(x), val(x) or cref(x) to transform
96 // the operand into a valid action object (see primitives.hpp).
97 // Example:
98 //
99 // val(1) << 3;
100 //
101 // Supported operators:
102 //
103 // Unary operators:
104 //
105 // prefix: ~, !, -, +, ++, --, & (reference), * (dereference)
106 // postfix: ++, --
107 //
108 // Binary operators:
109 //
110 // =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
111 // +, -, *, /, %, &, |, ^, <<, >>
112 // ==, !=, <, >, <=, >=
113 // &&, ||
114 //
115 // Each operator has a special tag type associated with it. For
116 // example the binary + operator has a plus_op tag type associated
117 // with it. This is used to specialize either the unary_operator or
118 // binary_operator template classes (see unary_operator and
119 // binary_operator below). Specializations of these unary_operator
120 // and binary_operator are the actual workhorses that implement the
121 // operations. The behavior of each lazy operator depends on these
122 // unary_operator and binary_operator specializations. 'preset'
123 // specializations conform to the canonical operator rules modeled
124 // by the behavior of integers and pointers:
125 //
126 // Prefix -, + and ~ accept constant arguments and return an
127 // object by value.
128 //
129 // The ! accept constant arguments and returns a boolean
130 // result.
131 //
132 // The & (address-of), * (dereference) both return a reference
133 // to an object.
134 //
135 // Prefix ++ returns a reference to its mutable argument after
136 // it is incremented.
137 //
138 // Postfix ++ returns the mutable argument by value before it
139 // is incremented.
140 //
141 // The += and its family accept mutable right hand side (rhs)
142 // operand and return a reference to the rhs operand.
143 //
144 // Infix + and its family accept constant arguments and return
145 // an object by value.
146 //
147 // The == and its family accept constant arguments and return a
148 // boolean result.
149 //
150 // Operators && and || accept constant arguments and return a
151 // boolean result and are short circuit evaluated as expected.
152 //
153 ///////////////////////////////////////////////////////////////////////////////
154
155 ///////////////////////////////////////////////////////////////////////////////
156 //
157 // Operator tags
158 //
159 // Each C++ operator has a corresponding tag type. This is
160 // used as a means for specializing the unary_operator and
161 // binary_operator (see below). The tag also serves as the
162 // lazy operator type compatible as a composite operation
163 // see (composite.hpp).
164 //
165 ///////////////////////////////////////////////////////////////////////////////
166
167 // Unary operator tags
168
169 struct negative_op; struct positive_op;
170 struct logical_not_op; struct invert_op;
171 struct reference_op; struct dereference_op;
172 struct pre_incr_op; struct pre_decr_op;
173 struct post_incr_op; struct post_decr_op;
174
175 // Binary operator tags
176
177 struct assign_op; struct index_op;
178 struct plus_assign_op; struct minus_assign_op;
179 struct times_assign_op; struct divide_assign_op; struct mod_assign_op;
180 struct and_assign_op; struct or_assign_op; struct xor_assign_op;
181 struct shift_l_assign_op; struct shift_r_assign_op;
182
183 struct plus_op; struct minus_op;
184 struct times_op; struct divide_op; struct mod_op;
185 struct and_op; struct or_op; struct xor_op;
186 struct shift_l_op; struct shift_r_op;
187
188 struct eq_op; struct not_eq_op;
189 struct lt_op; struct lt_eq_op;
190 struct gt_op; struct gt_eq_op;
191 struct logical_and_op; struct logical_or_op;
192
193 ///////////////////////////////////////////////////////////////////////////////
194 //
195 // unary_operator<TagT, T>
196 //
197 // The unary_operator class implements most of the C++ unary
198 // operators. Each specialization is basically a simple static eval
199 // function plus a result_type typedef that determines the return
200 // type of the eval function.
201 //
202 // TagT is one of the unary operator tags above and T is the data
203 // type (argument) involved in the operation.
204 //
205 // Only the behavior of C/C++ built-in types are taken into account
206 // in the specializations provided below. For user-defined types,
207 // these specializations may still be used provided that the
208 // operator overloads of such types adhere to the standard behavior
209 // of built-in types.
210 //
211 // T1 separate special_ops.hpp file implements more stl savvy
212 // specializations. Other more specialized unary_operator
213 // implementations may be defined by the client for specific
214 // unary operator tags/data types.
215 //
216 ///////////////////////////////////////////////////////////////////////////////
217 template <typename TagT, typename T>
218 struct unary_operator;
219
220 //////////////////////////////////
221 template <typename T>
222 struct unary_operator<negative_op, T> {
223
224 typedef T const result_type;
225 static result_type eval(T const& v)
226 { return -v; }
227 };
228
229 //////////////////////////////////
230 template <typename T>
231 struct unary_operator<positive_op, T> {
232
233 typedef T const result_type;
234 static result_type eval(T const& v)
235 { return +v; }
236 };
237
238 //////////////////////////////////
239 template <typename T>
240 struct unary_operator<logical_not_op, T> {
241
242 typedef T const result_type;
243 static result_type eval(T const& v)
244 { return !v; }
245 };
246
247 //////////////////////////////////
248 template <typename T>
249 struct unary_operator<invert_op, T> {
250
251 typedef T const result_type;
252 static result_type eval(T const& v)
253 { return ~v; }
254 };
255
256 //////////////////////////////////
257 template <typename T>
258 struct unary_operator<reference_op, T> {
259
260 typedef T* result_type;
261 static result_type eval(T& v)
262 { return &v; }
263 };
264
265 //////////////////////////////////
266 template <typename T>
267 struct unary_operator<dereference_op, T*> {
268
269 typedef T& result_type;
270 static result_type eval(T* v)
271 { return *v; }
272 };
273
274 //////////////////////////////////
275 template <typename T>
276 struct unary_operator<dereference_op, T* const> {
277
278 typedef T& result_type;
279 static result_type eval(T* const v)
280 { return *v; }
281 };
282
283 //////////////////////////////////
284 template <>
285 struct unary_operator<dereference_op, nil_t> {
286
287 // G++ eager template instantiation
288 // somehow requires this.
289 typedef nil_t result_type;
290 };
291
292 //////////////////////////////////
293 #ifndef __BORLANDC__
294 template <>
295 struct unary_operator<dereference_op, nil_t const> {
296
297 // G++ eager template instantiation
298 // somehow requires this.
299 typedef nil_t result_type;
300 };
301 #endif
302
303 //////////////////////////////////
304 template <typename T>
305 struct unary_operator<pre_incr_op, T> {
306
307 typedef T& result_type;
308 static result_type eval(T& v)
309 { return ++v; }
310 };
311
312 //////////////////////////////////
313 template <typename T>
314 struct unary_operator<pre_decr_op, T> {
315
316 typedef T& result_type;
317 static result_type eval(T& v)
318 { return --v; }
319 };
320
321 //////////////////////////////////
322 template <typename T>
323 struct unary_operator<post_incr_op, T> {
324
325 typedef T const result_type;
326 static result_type eval(T& v)
327 { T t(v); ++v; return t; }
328 };
329
330 //////////////////////////////////
331 template <typename T>
332 struct unary_operator<post_decr_op, T> {
333
334 typedef T const result_type;
335 static result_type eval(T& v)
336 { T t(v); --v; return t; }
337 };
338
339 ///////////////////////////////////////////////////////////////////////////////
340 //
341 // rank<T>
342 //
343 // rank<T> class has a static int constant 'value' that defines the
344 // absolute rank of a type. rank<T> is used to choose the result
345 // type of binary operators such as +. The type with the higher
346 // rank wins and is used as the operator's return type. T1 generic
347 // user defined type has a very high rank and always wins when
348 // compared against a user defined type. If this is not desireable,
349 // one can write a rank specialization for the type.
350 //
351 // Take note that ranks 0..9999 are reserved for the framework.
352 //
353 ///////////////////////////////////////////////////////////////////////////////
354 template <typename T>
355 struct rank { static int const value = INT_MAX; };
356
357 template <> struct rank<void> { static int const value = 0; };
358 template <> struct rank<bool> { static int const value = 10; };
359
360 template <> struct rank<char> { static int const value = 20; };
361 template <> struct rank<signed char> { static int const value = 20; };
362 template <> struct rank<unsigned char> { static int const value = 30; };
363 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
364 template <> struct rank<wchar_t> { static int const value = 40; };
365 #endif // !defined(BOOST_NO_INTRINSIC_WCHAR_T)
366
367 template <> struct rank<short> { static int const value = 50; };
368 template <> struct rank<unsigned short> { static int const value = 60; };
369
370 template <> struct rank<int> { static int const value = 70; };
371 template <> struct rank<unsigned int> { static int const value = 80; };
372
373 template <> struct rank<long> { static int const value = 90; };
374 template <> struct rank<unsigned long> { static int const value = 100; };
375
376 #ifdef BOOST_HAS_LONG_LONG
377 template <> struct rank< ::boost::long_long_type> { static int const value = 110; };
378 template <> struct rank< ::boost::ulong_long_type> { static int const value = 120; };
379 #endif
380
381 template <> struct rank<float> { static int const value = 130; };
382 template <> struct rank<double> { static int const value = 140; };
383 template <> struct rank<long double> { static int const value = 150; };
384
385 template <typename T> struct rank<T*>
386 { static int const value = 160; };
387
388 template <typename T> struct rank<T* const>
389 { static int const value = 160; };
390
391 template <typename T, int N> struct rank<T[N]>
392 { static int const value = 160; };
393
394 ///////////////////////////////////////////////////////////////////////////////
395 //
396 // higher_rank<T0, T1>
397 //
398 // Chooses the type (T0 or T1) with the higher rank.
399 //
400 ///////////////////////////////////////////////////////////////////////////////
401 template <typename T0, typename T1>
402 struct higher_rank {
403 typedef typename boost::mpl::if_c<
404 rank<T0>::value < rank<T1>::value,
405 T1, T0>::type type;
406 };
407
408 ///////////////////////////////////////////////////////////////////////////////
409 //
410 // binary_operator<TagT, T0, T1>
411 //
412 // The binary_operator class implements most of the C++ binary
413 // operators. Each specialization is basically a simple static eval
414 // function plus a result_type typedef that determines the return
415 // type of the eval function.
416 //
417 // TagT is one of the binary operator tags above T0 and T1 are the
418 // (arguments') data types involved in the operation.
419 //
420 // Only the behavior of C/C++ built-in types are taken into account
421 // in the specializations provided below. For user-defined types,
422 // these specializations may still be used provided that the
423 // operator overloads of such types adhere to the standard behavior
424 // of built-in types.
425 //
426 // T1 separate special_ops.hpp file implements more stl savvy
427 // specializations. Other more specialized unary_operator
428 // implementations may be defined by the client for specific
429 // unary operator tags/data types.
430 //
431 // All binary_operator except the logical_and_op and logical_or_op
432 // have an eval static function that carries out the actual operation.
433 // The logical_and_op and logical_or_op d are special because these
434 // two operators are short-circuit evaluated.
435 //
436 ///////////////////////////////////////////////////////////////////////////////
437 template <typename TagT, typename T0, typename T1>
438 struct binary_operator;
439
440 //////////////////////////////////
441 template <typename T0, typename T1>
442 struct binary_operator<assign_op, T0, T1> {
443
444 typedef T0& result_type;
445 static result_type eval(T0& lhs, T1 const& rhs)
446 { return lhs = rhs; }
447 };
448
449 //////////////////////////////////
450 template <typename T1>
451 struct binary_operator<index_op, nil_t, T1> {
452
453 // G++ eager template instantiation
454 // somehow requires this.
455 typedef nil_t result_type;
456 };
457
458 //////////////////////////////////
459 template <typename T0, typename T1>
460 struct binary_operator<index_op, T0*, T1> {
461
462 typedef T0& result_type;
463 static result_type eval(T0* ptr, T1 const& index)
464 { return ptr[index]; }
465 };
466
467 //////////////////////////////////
468 template <typename T0, typename T1>
469 struct binary_operator<index_op, T0* const, T1> {
470
471 typedef T0& result_type;
472 static result_type eval(T0* const ptr, T1 const& index)
473 { return ptr[index]; }
474 };
475
476 //////////////////////////////////
477 template <typename T0, int N, typename T1>
478 struct binary_operator<index_op, T0[N], T1> {
479
480 typedef T0& result_type;
481 static result_type eval(T0* ptr, T1 const& index)
482 { return ptr[index]; }
483 };
484
485 //////////////////////////////////
486 template <typename T0, typename T1>
487 struct binary_operator<plus_assign_op, T0, T1> {
488
489 typedef T0& result_type;
490 static result_type eval(T0& lhs, T1 const& rhs)
491 { return lhs += rhs; }
492 };
493
494 //////////////////////////////////
495 template <typename T0, typename T1>
496 struct binary_operator<minus_assign_op, T0, T1> {
497
498 typedef T0& result_type;
499 static result_type eval(T0& lhs, T1 const& rhs)
500 { return lhs -= rhs; }
501 };
502
503 //////////////////////////////////
504 template <typename T0, typename T1>
505 struct binary_operator<times_assign_op, T0, T1> {
506
507 typedef T0& result_type;
508 static result_type eval(T0& lhs, T1 const& rhs)
509 { return lhs *= rhs; }
510 };
511
512 //////////////////////////////////
513 template <typename T0, typename T1>
514 struct binary_operator<divide_assign_op, T0, T1> {
515
516 typedef T0& result_type;
517 static result_type eval(T0& lhs, T1 const& rhs)
518 { return lhs /= rhs; }
519 };
520
521 //////////////////////////////////
522 template <typename T0, typename T1>
523 struct binary_operator<mod_assign_op, T0, T1> {
524
525 typedef T0& result_type;
526 static result_type eval(T0& lhs, T1 const& rhs)
527 { return lhs %= rhs; }
528 };
529
530 //////////////////////////////////
531 template <typename T0, typename T1>
532 struct binary_operator<and_assign_op, T0, T1> {
533
534 typedef T0& result_type;
535 static result_type eval(T0& lhs, T1 const& rhs)
536 { return lhs &= rhs; }
537 };
538
539 //////////////////////////////////
540 template <typename T0, typename T1>
541 struct binary_operator<or_assign_op, T0, T1> {
542
543 typedef T0& result_type;
544 static result_type eval(T0& lhs, T1 const& rhs)
545 { return lhs |= rhs; }
546 };
547
548 //////////////////////////////////
549 template <typename T0, typename T1>
550 struct binary_operator<xor_assign_op, T0, T1> {
551
552 typedef T0& result_type;
553 static result_type eval(T0& lhs, T1 const& rhs)
554 { return lhs ^= rhs; }
555 };
556
557 //////////////////////////////////
558 template <typename T0, typename T1>
559 struct binary_operator<shift_l_assign_op, T0, T1> {
560
561 typedef T0& result_type;
562 static result_type eval(T0& lhs, T1 const& rhs)
563 { return lhs <<= rhs; }
564 };
565
566 //////////////////////////////////
567 template <typename T0, typename T1>
568 struct binary_operator<shift_r_assign_op, T0, T1> {
569
570 typedef T0& result_type;
571 static result_type eval(T0& lhs, T1 const& rhs)
572 { return lhs >>= rhs; }
573 };
574
575 //////////////////////////////////
576 template <typename T0, typename T1>
577 struct binary_operator<plus_op, T0, T1> {
578
579 typedef typename higher_rank<T0, T1>::type const result_type;
580 static result_type eval(T0 const& lhs, T1 const& rhs)
581 { return lhs + rhs; }
582 };
583
584 //////////////////////////////////
585 template <typename T0, typename T1>
586 struct binary_operator<minus_op, T0, T1> {
587
588 typedef typename higher_rank<T0, T1>::type const result_type;
589 static result_type eval(T0 const& lhs, T1 const& rhs)
590 { return lhs - rhs; }
591 };
592
593 //////////////////////////////////
594 template <typename T0, typename T1>
595 struct binary_operator<times_op, T0, T1> {
596
597 typedef typename higher_rank<T0, T1>::type const result_type;
598 static result_type eval(T0 const& lhs, T1 const& rhs)
599 { return lhs * rhs; }
600 };
601
602 //////////////////////////////////
603 template <typename T0, typename T1>
604 struct binary_operator<divide_op, T0, T1> {
605
606 typedef typename higher_rank<T0, T1>::type const result_type;
607 static result_type eval(T0 const& lhs, T1 const& rhs)
608 { return lhs / rhs; }
609 };
610
611 //////////////////////////////////
612 template <typename T0, typename T1>
613 struct binary_operator<mod_op, T0, T1> {
614
615 typedef typename higher_rank<T0, T1>::type const result_type;
616 static result_type eval(T0 const& lhs, T1 const& rhs)
617 { return lhs % rhs; }
618 };
619
620 //////////////////////////////////
621 template <typename T0, typename T1>
622 struct binary_operator<and_op, T0, T1> {
623
624 typedef typename higher_rank<T0, T1>::type const result_type;
625 static result_type eval(T0 const& lhs, T1 const& rhs)
626 { return lhs & rhs; }
627 };
628
629 //////////////////////////////////
630 template <typename T0, typename T1>
631 struct binary_operator<or_op, T0, T1> {
632
633 typedef typename higher_rank<T0, T1>::type const result_type;
634 static result_type eval(T0 const& lhs, T1 const& rhs)
635 { return lhs | rhs; }
636 };
637
638 //////////////////////////////////
639 template <typename T0, typename T1>
640 struct binary_operator<xor_op, T0, T1> {
641
642 typedef typename higher_rank<T0, T1>::type const result_type;
643 static result_type eval(T0 const& lhs, T1 const& rhs)
644 { return lhs ^ rhs; }
645 };
646
647 //////////////////////////////////
648 template <typename T0, typename T1>
649 struct binary_operator<shift_l_op, T0, T1> {
650
651 typedef T0 const result_type;
652 static result_type eval(T0 const& lhs, T1 const& rhs)
653 { return lhs << rhs; }
654 };
655
656 //////////////////////////////////
657 template <typename T0, typename T1>
658 struct binary_operator<shift_r_op, T0, T1> {
659
660 typedef T0 const result_type;
661 static result_type eval(T0 const& lhs, T1 const& rhs)
662 { return lhs >> rhs; }
663 };
664
665 //////////////////////////////////
666 template <typename T0, typename T1>
667 struct binary_operator<eq_op, T0, T1> {
668
669 typedef bool result_type;
670 static result_type eval(T0 const& lhs, T1 const& rhs)
671 { return lhs == rhs; }
672 };
673
674 //////////////////////////////////
675 template <typename T0, typename T1>
676 struct binary_operator<not_eq_op, T0, T1> {
677
678 typedef bool result_type;
679 static result_type eval(T0 const& lhs, T1 const& rhs)
680 { return lhs != rhs; }
681 };
682
683 //////////////////////////////////
684 template <typename T0, typename T1>
685 struct binary_operator<lt_op, T0, T1> {
686
687 typedef bool result_type;
688 static result_type eval(T0 const& lhs, T1 const& rhs)
689 { return lhs < rhs; }
690 };
691
692 //////////////////////////////////
693 template <typename T0, typename T1>
694 struct binary_operator<lt_eq_op, T0, T1> {
695
696 typedef bool result_type;
697 static result_type eval(T0 const& lhs, T1 const& rhs)
698 { return lhs <= rhs; }
699 };
700
701 //////////////////////////////////
702 template <typename T0, typename T1>
703 struct binary_operator<gt_op, T0, T1> {
704
705 typedef bool result_type;
706 static result_type eval(T0 const& lhs, T1 const& rhs)
707 { return lhs > rhs; }
708 };
709
710 //////////////////////////////////
711 template <typename T0, typename T1>
712 struct binary_operator<gt_eq_op, T0, T1> {
713
714 typedef bool result_type;
715 static result_type eval(T0 const& lhs, T1 const& rhs)
716 { return lhs >= rhs; }
717 };
718
719 //////////////////////////////////
720 template <typename T0, typename T1>
721 struct binary_operator<logical_and_op, T0, T1> {
722
723 typedef bool result_type;
724 // no eval function, see comment above.
725 };
726
727 //////////////////////////////////
728 template <typename T0, typename T1>
729 struct binary_operator<logical_or_op, T0, T1> {
730
731 typedef bool result_type;
732 // no eval function, see comment above.
733 };
734
735 ///////////////////////////////////////////////////////////////////////////////
736 //
737 // negative lazy operator (prefix -)
738 //
739 ///////////////////////////////////////////////////////////////////////////////
740 struct negative_op {
741
742 template <typename T0>
743 struct result {
744
745 typedef typename unary_operator<negative_op, T0>::result_type type;
746 };
747
748 template <typename T0>
749 typename unary_operator<negative_op, T0>::result_type
750 operator()(T0& _0) const
751 { return unary_operator<negative_op, T0>::eval(_0); }
752 };
753
754 //////////////////////////////////
755 template <typename BaseT>
756 inline typename impl::make_unary<negative_op, BaseT>::type
757 operator-(actor<BaseT> const& _0)
758 {
759 return impl::make_unary<negative_op, BaseT>::construct(_0);
760 }
761
762 ///////////////////////////////////////////////////////////////////////////////
763 //
764 // positive lazy operator (prefix +)
765 //
766 ///////////////////////////////////////////////////////////////////////////////
767 struct positive_op {
768
769 template <typename T0>
770 struct result {
771
772 typedef typename unary_operator<positive_op, T0>::result_type type;
773 };
774
775 template <typename T0>
776 typename unary_operator<positive_op, T0>::result_type
777 operator()(T0& _0) const
778 { return unary_operator<positive_op, T0>::eval(_0); }
779 };
780
781 //////////////////////////////////
782 template <typename BaseT>
783 inline typename impl::make_unary<positive_op, BaseT>::type
784 operator+(actor<BaseT> const& _0)
785 {
786 return impl::make_unary<positive_op, BaseT>::construct(_0);
787 }
788
789 ///////////////////////////////////////////////////////////////////////////////
790 //
791 // logical not lazy operator (prefix !)
792 //
793 ///////////////////////////////////////////////////////////////////////////////
794 struct logical_not_op {
795
796 template <typename T0>
797 struct result {
798
799 typedef typename unary_operator<logical_not_op, T0>::result_type type;
800 };
801
802 template <typename T0>
803 typename unary_operator<logical_not_op, T0>::result_type
804 operator()(T0& _0) const
805 { return unary_operator<logical_not_op, T0>::eval(_0); }
806 };
807
808 //////////////////////////////////
809 template <typename BaseT>
810 inline typename impl::make_unary<logical_not_op, BaseT>::type
811 operator!(actor<BaseT> const& _0)
812 {
813 return impl::make_unary<logical_not_op, BaseT>::construct(_0);
814 }
815
816 ///////////////////////////////////////////////////////////////////////////////
817 //
818 // invert lazy operator (prefix ~)
819 //
820 ///////////////////////////////////////////////////////////////////////////////
821 struct invert_op {
822
823 template <typename T0>
824 struct result {
825
826 typedef typename unary_operator<invert_op, T0>::result_type type;
827 };
828
829 template <typename T0>
830 typename unary_operator<invert_op, T0>::result_type
831 operator()(T0& _0) const
832 { return unary_operator<invert_op, T0>::eval(_0); }
833 };
834
835 //////////////////////////////////
836 template <typename BaseT>
837 inline typename impl::make_unary<invert_op, BaseT>::type
838 operator~(actor<BaseT> const& _0)
839 {
840 return impl::make_unary<invert_op, BaseT>::construct(_0);
841 }
842
843 ///////////////////////////////////////////////////////////////////////////////
844 //
845 // reference lazy operator (prefix &)
846 //
847 ///////////////////////////////////////////////////////////////////////////////
848 struct reference_op {
849
850 template <typename T0>
851 struct result {
852
853 typedef typename unary_operator<reference_op, T0>::result_type type;
854 };
855
856 template <typename T0>
857 typename unary_operator<reference_op, T0>::result_type
858 operator()(T0& _0) const
859 { return unary_operator<reference_op, T0>::eval(_0); }
860 };
861
862 //////////////////////////////////
863 template <typename BaseT>
864 inline typename impl::make_unary<reference_op, BaseT>::type
865 operator&(actor<BaseT> const& _0)
866 {
867 return impl::make_unary<reference_op, BaseT>::construct(_0);
868 }
869
870 ///////////////////////////////////////////////////////////////////////////////
871 //
872 // dereference lazy operator (prefix *)
873 //
874 ///////////////////////////////////////////////////////////////////////////////
875 struct dereference_op {
876
877 template <typename T0>
878 struct result {
879
880 typedef typename unary_operator<dereference_op, T0>::result_type type;
881 };
882
883 template <typename T0>
884 typename unary_operator<dereference_op, T0>::result_type
885 operator()(T0& _0) const
886 { return unary_operator<dereference_op, T0>::eval(_0); }
887 };
888
889 //////////////////////////////////
890 template <typename BaseT>
891 inline typename impl::make_unary<dereference_op, BaseT>::type
892 operator*(actor<BaseT> const& _0)
893 {
894 return impl::make_unary<dereference_op, BaseT>::construct(_0);
895 }
896
897 ///////////////////////////////////////////////////////////////////////////////
898 //
899 // pre increment lazy operator (prefix ++)
900 //
901 ///////////////////////////////////////////////////////////////////////////////
902 struct pre_incr_op {
903
904 template <typename T0>
905 struct result {
906
907 typedef typename unary_operator<pre_incr_op, T0>::result_type type;
908 };
909
910 template <typename T0>
911 typename unary_operator<pre_incr_op, T0>::result_type
912 operator()(T0& _0) const
913 { return unary_operator<pre_incr_op, T0>::eval(_0); }
914 };
915
916 //////////////////////////////////
917 template <typename BaseT>
918 inline typename impl::make_unary<pre_incr_op, BaseT>::type
919 operator++(actor<BaseT> const& _0)
920 {
921 return impl::make_unary<pre_incr_op, BaseT>::construct(_0);
922 }
923
924 ///////////////////////////////////////////////////////////////////////////////
925 //
926 // pre decrement lazy operator (prefix --)
927 //
928 ///////////////////////////////////////////////////////////////////////////////
929 struct pre_decr_op {
930
931 template <typename T0>
932 struct result {
933
934 typedef typename unary_operator<pre_decr_op, T0>::result_type type;
935 };
936
937 template <typename T0>
938 typename unary_operator<pre_decr_op, T0>::result_type
939 operator()(T0& _0) const
940 { return unary_operator<pre_decr_op, T0>::eval(_0); }
941 };
942
943 //////////////////////////////////
944 template <typename BaseT>
945 inline typename impl::make_unary<pre_decr_op, BaseT>::type
946 operator--(actor<BaseT> const& _0)
947 {
948 return impl::make_unary<pre_decr_op, BaseT>::construct(_0);
949 }
950
951 ///////////////////////////////////////////////////////////////////////////////
952 //
953 // post increment lazy operator (postfix ++)
954 //
955 ///////////////////////////////////////////////////////////////////////////////
956 struct post_incr_op {
957
958 template <typename T0>
959 struct result {
960
961 typedef typename unary_operator<post_incr_op, T0>::result_type type;
962 };
963
964 template <typename T0>
965 typename unary_operator<post_incr_op, T0>::result_type
966 operator()(T0& _0) const
967 { return unary_operator<post_incr_op, T0>::eval(_0); }
968 };
969
970 //////////////////////////////////
971 template <typename BaseT>
972 inline typename impl::make_unary<post_incr_op, BaseT>::type
973 operator++(actor<BaseT> const& _0, int)
974 {
975 return impl::make_unary<post_incr_op, BaseT>::construct(_0);
976 }
977
978 ///////////////////////////////////////////////////////////////////////////////
979 //
980 // post decrement lazy operator (postfix --)
981 //
982 ///////////////////////////////////////////////////////////////////////////////
983 struct post_decr_op {
984
985 template <typename T0>
986 struct result {
987
988 typedef typename unary_operator<post_decr_op, T0>::result_type type;
989 };
990
991 template <typename T0>
992 typename unary_operator<post_decr_op, T0>::result_type
993 operator()(T0& _0) const
994 { return unary_operator<post_decr_op, T0>::eval(_0); }
995 };
996
997 //////////////////////////////////
998 template <typename BaseT>
999 inline typename impl::make_unary<post_decr_op, BaseT>::type
1000 operator--(actor<BaseT> const& _0, int)
1001 {
1002 return impl::make_unary<post_decr_op, BaseT>::construct(_0);
1003 }
1004
1005 ///////////////////////////////////////////////////////////////////////////////
1006 //
1007 // assignment lazy operator (infix =)
1008 // The acual lazy operator is a member of the actor class.
1009 //
1010 ///////////////////////////////////////////////////////////////////////////////
1011 struct assign_op {
1012
1013 template <typename T0, typename T1>
1014 struct result {
1015
1016 typedef typename binary_operator<assign_op, T0, T1>
1017 ::result_type type;
1018 };
1019
1020 template <typename T0, typename T1>
1021 typename binary_operator<assign_op, T0, T1>::result_type
1022 operator()(T0& _0, T1& _1) const
1023 { return binary_operator<assign_op, T0, T1>::eval(_0, _1); }
1024 };
1025
1026 //////////////////////////////////
1027 template <typename BaseT>
1028 template <typename B>
1029 inline typename impl::make_binary1<assign_op, BaseT, B>::type
1030 actor<BaseT>::operator=(B const& _1) const
1031 {
1032 return impl::make_binary1<assign_op, BaseT, B>::construct(*this, _1);
1033 }
1034
1035 ///////////////////////////////////////////////////////////////////////////////
1036 //
1037 // index lazy operator (array index [])
1038 // The acual lazy operator is a member of the actor class.
1039 //
1040 ///////////////////////////////////////////////////////////////////////////////
1041 struct index_op {
1042
1043 template <typename T0, typename T1>
1044 struct result {
1045
1046 typedef typename binary_operator<index_op, T0, T1>
1047 ::result_type type;
1048 };
1049
1050 template <typename T0, typename T1>
1051 typename binary_operator<index_op, T0, T1>::result_type
1052 operator()(T0& _0, T1& _1) const
1053 { return binary_operator<index_op, T0, T1>::eval(_0, _1); }
1054 };
1055
1056 //////////////////////////////////
1057 template <typename BaseT>
1058 template <typename B>
1059 inline typename impl::make_binary1<index_op, BaseT, B>::type
1060 actor<BaseT>::operator[](B const& _1) const
1061 {
1062 return impl::make_binary1<index_op, BaseT, B>::construct(*this, _1);
1063 }
1064
1065 ///////////////////////////////////////////////////////////////////////////////
1066 //
1067 // plus assign lazy operator (infix +=)
1068 //
1069 ///////////////////////////////////////////////////////////////////////////////
1070 struct plus_assign_op {
1071
1072 template <typename T0, typename T1>
1073 struct result {
1074
1075 typedef typename binary_operator<plus_assign_op, T0, T1>
1076 ::result_type type;
1077 };
1078
1079 template <typename T0, typename T1>
1080 typename binary_operator<plus_assign_op, T0, T1>::result_type
1081 operator()(T0& _0, T1& _1) const
1082 { return binary_operator<plus_assign_op, T0, T1>::eval(_0, _1); }
1083 };
1084
1085 //////////////////////////////////
1086 template <typename BaseT, typename T1>
1087 inline typename impl::make_binary1<plus_assign_op, BaseT, T1>::type
1088 operator+=(actor<BaseT> const& _0, T1 CREF _1)
1089 {
1090 return impl::make_binary1<plus_assign_op, BaseT, T1>::construct(_0, _1);
1091 }
1092
1093 ///////////////////////////////////////////////////////////////////////////////
1094 //
1095 // minus assign lazy operator (infix -=)
1096 //
1097 ///////////////////////////////////////////////////////////////////////////////
1098 struct minus_assign_op {
1099
1100 template <typename T0, typename T1>
1101 struct result {
1102
1103 typedef typename binary_operator<minus_assign_op, T0, T1>
1104 ::result_type type;
1105 };
1106
1107 template <typename T0, typename T1>
1108 typename binary_operator<minus_assign_op, T0, T1>::result_type
1109 operator()(T0& _0, T1& _1) const
1110 { return binary_operator<minus_assign_op, T0, T1>::eval(_0, _1); }
1111 };
1112
1113 //////////////////////////////////
1114 template <typename BaseT, typename T1>
1115 inline typename impl::make_binary1<minus_assign_op, BaseT, T1>::type
1116 operator-=(actor<BaseT> const& _0, T1 CREF _1)
1117 {
1118 return impl::make_binary1<minus_assign_op, BaseT, T1>::construct(_0, _1);
1119 }
1120
1121 ///////////////////////////////////////////////////////////////////////////////
1122 //
1123 // times assign lazy operator (infix *=)
1124 //
1125 ///////////////////////////////////////////////////////////////////////////////
1126 struct times_assign_op {
1127
1128 template <typename T0, typename T1>
1129 struct result {
1130
1131 typedef typename binary_operator<times_assign_op, T0, T1>
1132 ::result_type type;
1133 };
1134
1135 template <typename T0, typename T1>
1136 typename binary_operator<times_assign_op, T0, T1>::result_type
1137 operator()(T0& _0, T1& _1) const
1138 { return binary_operator<times_assign_op, T0, T1>::eval(_0, _1); }
1139 };
1140
1141 //////////////////////////////////
1142 template <typename BaseT, typename T1>
1143 inline typename impl::make_binary1<times_assign_op, BaseT, T1>::type
1144 operator*=(actor<BaseT> const& _0, T1 CREF _1)
1145 {
1146 return impl::make_binary1<times_assign_op, BaseT, T1>::construct(_0, _1);
1147 }
1148
1149 ///////////////////////////////////////////////////////////////////////////////
1150 //
1151 // divide assign lazy operator (infix /=)
1152 //
1153 ///////////////////////////////////////////////////////////////////////////////
1154 struct divide_assign_op {
1155
1156 template <typename T0, typename T1>
1157 struct result {
1158
1159 typedef typename binary_operator<divide_assign_op, T0, T1>
1160 ::result_type type;
1161 };
1162
1163 template <typename T0, typename T1>
1164 typename binary_operator<divide_assign_op, T0, T1>::result_type
1165 operator()(T0& _0, T1& _1) const
1166 { return binary_operator<divide_assign_op, T0, T1>::eval(_0, _1); }
1167 };
1168
1169 //////////////////////////////////
1170 template <typename BaseT, typename T1>
1171 inline typename impl::make_binary1<divide_assign_op, BaseT, T1>::type
1172 operator/=(actor<BaseT> const& _0, T1 CREF _1)
1173 {
1174 return impl::make_binary1<divide_assign_op, BaseT, T1>::construct(_0, _1);
1175 }
1176
1177 ///////////////////////////////////////////////////////////////////////////////
1178 //
1179 // mod assign lazy operator (infix %=)
1180 //
1181 ///////////////////////////////////////////////////////////////////////////////
1182 struct mod_assign_op {
1183
1184 template <typename T0, typename T1>
1185 struct result {
1186
1187 typedef typename binary_operator<mod_assign_op, T0, T1>
1188 ::result_type type;
1189 };
1190
1191 template <typename T0, typename T1>
1192 typename binary_operator<mod_assign_op, T0, T1>::result_type
1193 operator()(T0& _0, T1& _1) const
1194 { return binary_operator<mod_assign_op, T0, T1>::eval(_0, _1); }
1195 };
1196
1197 //////////////////////////////////
1198 template <typename BaseT, typename T1>
1199 inline typename impl::make_binary1<mod_assign_op, BaseT, T1>::type
1200 operator%=(actor<BaseT> const& _0, T1 CREF _1)
1201 {
1202 return impl::make_binary1<mod_assign_op, BaseT, T1>::construct(_0, _1);
1203 }
1204
1205 ///////////////////////////////////////////////////////////////////////////////
1206 //
1207 // and assign lazy operator (infix &=)
1208 //
1209 ///////////////////////////////////////////////////////////////////////////////
1210 struct and_assign_op {
1211
1212 template <typename T0, typename T1>
1213 struct result {
1214
1215 typedef typename binary_operator<and_assign_op, T0, T1>
1216 ::result_type type;
1217 };
1218
1219 template <typename T0, typename T1>
1220 typename binary_operator<and_assign_op, T0, T1>::result_type
1221 operator()(T0& _0, T1& _1) const
1222 { return binary_operator<and_assign_op, T0, T1>::eval(_0, _1); }
1223 };
1224
1225 //////////////////////////////////
1226 template <typename BaseT, typename T1>
1227 inline typename impl::make_binary1<and_assign_op, BaseT, T1>::type
1228 operator&=(actor<BaseT> const& _0, T1 CREF _1)
1229 {
1230 return impl::make_binary1<and_assign_op, BaseT, T1>::construct(_0, _1);
1231 }
1232
1233 ///////////////////////////////////////////////////////////////////////////////
1234 //
1235 // or assign lazy operator (infix |=)
1236 //
1237 ///////////////////////////////////////////////////////////////////////////////
1238 struct or_assign_op {
1239
1240 template <typename T0, typename T1>
1241 struct result {
1242
1243 typedef typename binary_operator<or_assign_op, T0, T1>
1244 ::result_type type;
1245 };
1246
1247 template <typename T0, typename T1>
1248 typename binary_operator<or_assign_op, T0, T1>::result_type
1249 operator()(T0& _0, T1& _1) const
1250 { return binary_operator<or_assign_op, T0, T1>::eval(_0, _1); }
1251 };
1252
1253 //////////////////////////////////
1254 template <typename BaseT, typename T1>
1255 inline typename impl::make_binary1<or_assign_op, BaseT, T1>::type
1256 operator|=(actor<BaseT> const& _0, T1 CREF _1)
1257 {
1258 return impl::make_binary1<or_assign_op, BaseT, T1>::construct(_0, _1);
1259 }
1260
1261 ///////////////////////////////////////////////////////////////////////////////
1262 //
1263 // xor assign lazy operator (infix ^=)
1264 //
1265 ///////////////////////////////////////////////////////////////////////////////
1266 struct xor_assign_op {
1267
1268 template <typename T0, typename T1>
1269 struct result {
1270
1271 typedef typename binary_operator<xor_assign_op, T0, T1>
1272 ::result_type type;
1273 };
1274
1275 template <typename T0, typename T1>
1276 typename binary_operator<xor_assign_op, T0, T1>::result_type
1277 operator()(T0& _0, T1& _1) const
1278 { return binary_operator<xor_assign_op, T0, T1>::eval(_0, _1); }
1279 };
1280
1281 //////////////////////////////////
1282 template <typename BaseT, typename T1>
1283 inline typename impl::make_binary1<xor_assign_op, BaseT, T1>::type
1284 operator^=(actor<BaseT> const& _0, T1 CREF _1)
1285 {
1286 return impl::make_binary1<xor_assign_op, BaseT, T1>::construct(_0, _1);
1287 }
1288
1289 ///////////////////////////////////////////////////////////////////////////////
1290 //
1291 // shift left assign lazy operator (infix <<=)
1292 //
1293 ///////////////////////////////////////////////////////////////////////////////
1294 struct shift_l_assign_op {
1295
1296 template <typename T0, typename T1>
1297 struct result {
1298
1299 typedef typename binary_operator<shift_l_assign_op, T0, T1>
1300 ::result_type type;
1301 };
1302
1303 template <typename T0, typename T1>
1304 typename binary_operator<shift_l_assign_op, T0, T1>::result_type
1305 operator()(T0& _0, T1& _1) const
1306 { return binary_operator<shift_l_assign_op, T0, T1>::eval(_0, _1); }
1307 };
1308
1309 //////////////////////////////////
1310 template <typename BaseT, typename T1>
1311 inline typename impl::make_binary1<shift_l_assign_op, BaseT, T1>::type
1312 operator<<=(actor<BaseT> const& _0, T1 CREF _1)
1313 {
1314 return impl::make_binary1<shift_l_assign_op, BaseT, T1>::construct(_0, _1);
1315 }
1316
1317 ///////////////////////////////////////////////////////////////////////////////
1318 //
1319 // shift right assign lazy operator (infix >>=)
1320 //
1321 ///////////////////////////////////////////////////////////////////////////////
1322 struct shift_r_assign_op {
1323
1324 template <typename T0, typename T1>
1325 struct result {
1326
1327 typedef typename binary_operator<shift_r_assign_op, T0, T1>
1328 ::result_type type;
1329 };
1330
1331 template <typename T0, typename T1>
1332 typename binary_operator<shift_r_assign_op, T0, T1>::result_type
1333 operator()(T0& _0, T1& _1) const
1334 { return binary_operator<shift_r_assign_op, T0, T1>::eval(_0, _1); }
1335 };
1336
1337 //////////////////////////////////
1338 template <typename BaseT, typename T1>
1339 inline typename impl::make_binary1<shift_r_assign_op, BaseT, T1>::type
1340 operator>>=(actor<BaseT> const& _0, T1 CREF _1)
1341 {
1342 return impl::make_binary1<shift_r_assign_op, BaseT, T1>::construct(_0, _1);
1343 }
1344
1345 ///////////////////////////////////////////////////////////////////////////////
1346 //
1347 // plus lazy operator (infix +)
1348 //
1349 ///////////////////////////////////////////////////////////////////////////////
1350 struct plus_op {
1351
1352 template <typename T0, typename T1>
1353 struct result {
1354
1355 typedef typename binary_operator<plus_op, T0, T1>
1356 ::result_type type;
1357 };
1358
1359 template <typename T0, typename T1>
1360 typename binary_operator<plus_op, T0, T1>::result_type
1361 operator()(T0& _0, T1& _1) const
1362 { return binary_operator<plus_op, T0, T1>::eval(_0, _1); }
1363 };
1364
1365 //////////////////////////////////
1366 template <typename BaseT, typename T1>
1367 inline typename impl::make_binary1<plus_op, BaseT, T1>::type
1368 operator+(actor<BaseT> const& _0, T1 CREF _1)
1369 {
1370 return impl::make_binary1<plus_op, BaseT, T1>::construct(_0, _1);
1371 }
1372
1373 //////////////////////////////////
1374 template <typename T0, typename BaseT>
1375 inline typename impl::make_binary2<plus_op, T0, BaseT>::type
1376 operator+(T0 CREF _0, actor<BaseT> const& _1)
1377 {
1378 return impl::make_binary2<plus_op, T0, BaseT>::construct(_0, _1);
1379 }
1380
1381 //////////////////////////////////
1382 template <typename BaseT0, typename BaseT1>
1383 inline typename impl::make_binary3<plus_op, BaseT0, BaseT1>::type
1384 operator+(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1385 {
1386 return impl::make_binary3<plus_op, BaseT0, BaseT1>::construct(_0, _1);
1387 }
1388
1389 ///////////////////////////////////////////////////////////////////////////////
1390 //
1391 // minus lazy operator (infix -)
1392 //
1393 ///////////////////////////////////////////////////////////////////////////////
1394 struct minus_op {
1395
1396 template <typename T0, typename T1>
1397 struct result {
1398
1399 typedef typename binary_operator<minus_op, T0, T1>
1400 ::result_type type;
1401 };
1402
1403 template <typename T0, typename T1>
1404 typename binary_operator<minus_op, T0, T1>::result_type
1405 operator()(T0& _0, T1& _1) const
1406 { return binary_operator<minus_op, T0, T1>::eval(_0, _1); }
1407 };
1408
1409 //////////////////////////////////
1410 template <typename BaseT, typename T1>
1411 inline typename impl::make_binary1<minus_op, BaseT, T1>::type
1412 operator-(actor<BaseT> const& _0, T1 CREF _1)
1413 {
1414 return impl::make_binary1<minus_op, BaseT, T1>::construct(_0, _1);
1415 }
1416
1417 //////////////////////////////////
1418 template <typename T0, typename BaseT>
1419 inline typename impl::make_binary2<minus_op, T0, BaseT>::type
1420 operator-(T0 CREF _0, actor<BaseT> const& _1)
1421 {
1422 return impl::make_binary2<minus_op, T0, BaseT>::construct(_0, _1);
1423 }
1424
1425 //////////////////////////////////
1426 template <typename BaseT0, typename BaseT1>
1427 inline typename impl::make_binary3<minus_op, BaseT0, BaseT1>::type
1428 operator-(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1429 {
1430 return impl::make_binary3<minus_op, BaseT0, BaseT1>::construct(_0, _1);
1431 }
1432
1433 ///////////////////////////////////////////////////////////////////////////////
1434 //
1435 // times lazy operator (infix *)
1436 //
1437 ///////////////////////////////////////////////////////////////////////////////
1438 struct times_op {
1439
1440 template <typename T0, typename T1>
1441 struct result {
1442
1443 typedef typename binary_operator<times_op, T0, T1>
1444 ::result_type type;
1445 };
1446
1447 template <typename T0, typename T1>
1448 typename binary_operator<times_op, T0, T1>::result_type
1449 operator()(T0& _0, T1& _1) const
1450 { return binary_operator<times_op, T0, T1>::eval(_0, _1); }
1451 };
1452
1453 //////////////////////////////////
1454 template <typename BaseT, typename T1>
1455 inline typename impl::make_binary1<times_op, BaseT, T1>::type
1456 operator*(actor<BaseT> const& _0, T1 CREF _1)
1457 {
1458 return impl::make_binary1<times_op, BaseT, T1>::construct(_0, _1);
1459 }
1460
1461 //////////////////////////////////
1462 template <typename T0, typename BaseT>
1463 inline typename impl::make_binary2<times_op, T0, BaseT>::type
1464 operator*(T0 CREF _0, actor<BaseT> const& _1)
1465 {
1466 return impl::make_binary2<times_op, T0, BaseT>::construct(_0, _1);
1467 }
1468
1469 //////////////////////////////////
1470 template <typename BaseT0, typename BaseT1>
1471 inline typename impl::make_binary3<times_op, BaseT0, BaseT1>::type
1472 operator*(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1473 {
1474 return impl::make_binary3<times_op, BaseT0, BaseT1>::construct(_0, _1);
1475 }
1476
1477 ///////////////////////////////////////////////////////////////////////////////
1478 //
1479 // divide lazy operator (infix /)
1480 //
1481 ///////////////////////////////////////////////////////////////////////////////
1482 struct divide_op {
1483
1484 template <typename T0, typename T1>
1485 struct result {
1486
1487 typedef typename binary_operator<divide_op, T0, T1>
1488 ::result_type type;
1489 };
1490
1491 template <typename T0, typename T1>
1492 typename binary_operator<divide_op, T0, T1>::result_type
1493 operator()(T0& _0, T1& _1) const
1494 { return binary_operator<divide_op, T0, T1>::eval(_0, _1); }
1495 };
1496
1497 //////////////////////////////////
1498 template <typename BaseT, typename T1>
1499 inline typename impl::make_binary1<divide_op, BaseT, T1>::type
1500 operator/(actor<BaseT> const& _0, T1 CREF _1)
1501 {
1502 return impl::make_binary1<divide_op, BaseT, T1>::construct(_0, _1);
1503 }
1504
1505 //////////////////////////////////
1506 template <typename T0, typename BaseT>
1507 inline typename impl::make_binary2<divide_op, T0, BaseT>::type
1508 operator/(T0 CREF _0, actor<BaseT> const& _1)
1509 {
1510 return impl::make_binary2<divide_op, T0, BaseT>::construct(_0, _1);
1511 }
1512
1513 //////////////////////////////////
1514 template <typename BaseT0, typename BaseT1>
1515 inline typename impl::make_binary3<divide_op, BaseT0, BaseT1>::type
1516 operator/(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1517 {
1518 return impl::make_binary3<divide_op, BaseT0, BaseT1>::construct(_0, _1);
1519 }
1520
1521 ///////////////////////////////////////////////////////////////////////////////
1522 //
1523 // mod lazy operator (infix %)
1524 //
1525 ///////////////////////////////////////////////////////////////////////////////
1526 struct mod_op {
1527
1528 template <typename T0, typename T1>
1529 struct result {
1530
1531 typedef typename binary_operator<mod_op, T0, T1>
1532 ::result_type type;
1533 };
1534
1535 template <typename T0, typename T1>
1536 typename binary_operator<mod_op, T0, T1>::result_type
1537 operator()(T0& _0, T1& _1) const
1538 { return binary_operator<mod_op, T0, T1>::eval(_0, _1); }
1539 };
1540
1541 //////////////////////////////////
1542 template <typename BaseT, typename T1>
1543 inline typename impl::make_binary1<mod_op, BaseT, T1>::type
1544 operator%(actor<BaseT> const& _0, T1 CREF _1)
1545 {
1546 return impl::make_binary1<mod_op, BaseT, T1>::construct(_0, _1);
1547 }
1548
1549 //////////////////////////////////
1550 template <typename T0, typename BaseT>
1551 inline typename impl::make_binary2<mod_op, T0, BaseT>::type
1552 operator%(T0 CREF _0, actor<BaseT> const& _1)
1553 {
1554 return impl::make_binary2<mod_op, T0, BaseT>::construct(_0, _1);
1555 }
1556
1557 //////////////////////////////////
1558 template <typename BaseT0, typename BaseT1>
1559 inline typename impl::make_binary3<mod_op, BaseT0, BaseT1>::type
1560 operator%(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1561 {
1562 return impl::make_binary3<mod_op, BaseT0, BaseT1>::construct(_0, _1);
1563 }
1564
1565 ///////////////////////////////////////////////////////////////////////////////
1566 //
1567 // and lazy operator (infix &)
1568 //
1569 ///////////////////////////////////////////////////////////////////////////////
1570 struct and_op {
1571
1572 template <typename T0, typename T1>
1573 struct result {
1574
1575 typedef typename binary_operator<and_op, T0, T1>
1576 ::result_type type;
1577 };
1578
1579 template <typename T0, typename T1>
1580 typename binary_operator<and_op, T0, T1>::result_type
1581 operator()(T0& _0, T1& _1) const
1582 { return binary_operator<and_op, T0, T1>::eval(_0, _1); }
1583 };
1584
1585 //////////////////////////////////
1586 template <typename BaseT, typename T1>
1587 inline typename impl::make_binary1<and_op, BaseT, T1>::type
1588 operator&(actor<BaseT> const& _0, T1 CREF _1)
1589 {
1590 return impl::make_binary1<and_op, BaseT, T1>::construct(_0, _1);
1591 }
1592
1593 //////////////////////////////////
1594 template <typename T0, typename BaseT>
1595 inline typename impl::make_binary2<and_op, T0, BaseT>::type
1596 operator&(T0 CREF _0, actor<BaseT> const& _1)
1597 {
1598 return impl::make_binary2<and_op, T0, BaseT>::construct(_0, _1);
1599 }
1600
1601 //////////////////////////////////
1602 template <typename BaseT0, typename BaseT1>
1603 inline typename impl::make_binary3<and_op, BaseT0, BaseT1>::type
1604 operator&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1605 {
1606 return impl::make_binary3<and_op, BaseT0, BaseT1>::construct(_0, _1);
1607 }
1608
1609 ///////////////////////////////////////////////////////////////////////////////
1610 //
1611 // or lazy operator (infix |)
1612 //
1613 ///////////////////////////////////////////////////////////////////////////////
1614 struct or_op {
1615
1616 template <typename T0, typename T1>
1617 struct result {
1618
1619 typedef typename binary_operator<or_op, T0, T1>
1620 ::result_type type;
1621 };
1622
1623 template <typename T0, typename T1>
1624 typename binary_operator<or_op, T0, T1>::result_type
1625 operator()(T0& _0, T1& _1) const
1626 { return binary_operator<or_op, T0, T1>::eval(_0, _1); }
1627 };
1628
1629 //////////////////////////////////
1630 template <typename BaseT, typename T1>
1631 inline typename impl::make_binary1<or_op, BaseT, T1>::type
1632 operator|(actor<BaseT> const& _0, T1 CREF _1)
1633 {
1634 return impl::make_binary1<or_op, BaseT, T1>::construct(_0, _1);
1635 }
1636
1637 //////////////////////////////////
1638 template <typename T0, typename BaseT>
1639 inline typename impl::make_binary2<or_op, T0, BaseT>::type
1640 operator|(T0 CREF _0, actor<BaseT> const& _1)
1641 {
1642 return impl::make_binary2<or_op, T0, BaseT>::construct(_0, _1);
1643 }
1644
1645 //////////////////////////////////
1646 template <typename BaseT0, typename BaseT1>
1647 inline typename impl::make_binary3<or_op, BaseT0, BaseT1>::type
1648 operator|(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1649 {
1650 return impl::make_binary3<or_op, BaseT0, BaseT1>::construct(_0, _1);
1651 }
1652
1653 ///////////////////////////////////////////////////////////////////////////////
1654 //
1655 // xor lazy operator (infix ^)
1656 //
1657 ///////////////////////////////////////////////////////////////////////////////
1658 struct xor_op {
1659
1660 template <typename T0, typename T1>
1661 struct result {
1662
1663 typedef typename binary_operator<xor_op, T0, T1>
1664 ::result_type type;
1665 };
1666
1667 template <typename T0, typename T1>
1668 typename binary_operator<xor_op, T0, T1>::result_type
1669 operator()(T0& _0, T1& _1) const
1670 { return binary_operator<xor_op, T0, T1>::eval(_0, _1); }
1671 };
1672
1673 //////////////////////////////////
1674 template <typename BaseT, typename T1>
1675 inline typename impl::make_binary1<xor_op, BaseT, T1>::type
1676 operator^(actor<BaseT> const& _0, T1 CREF _1)
1677 {
1678 return impl::make_binary1<xor_op, BaseT, T1>::construct(_0, _1);
1679 }
1680
1681 //////////////////////////////////
1682 template <typename T0, typename BaseT>
1683 inline typename impl::make_binary2<xor_op, T0, BaseT>::type
1684 operator^(T0 CREF _0, actor<BaseT> const& _1)
1685 {
1686 return impl::make_binary2<xor_op, T0, BaseT>::construct(_0, _1);
1687 }
1688
1689 //////////////////////////////////
1690 template <typename BaseT0, typename BaseT1>
1691 inline typename impl::make_binary3<xor_op, BaseT0, BaseT1>::type
1692 operator^(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1693 {
1694 return impl::make_binary3<xor_op, BaseT0, BaseT1>::construct(_0, _1);
1695 }
1696
1697 ///////////////////////////////////////////////////////////////////////////////
1698 //
1699 // shift left lazy operator (infix <<)
1700 //
1701 ///////////////////////////////////////////////////////////////////////////////
1702 struct shift_l_op {
1703
1704 template <typename T0, typename T1>
1705 struct result {
1706
1707 typedef typename binary_operator<shift_l_op, T0, T1>
1708 ::result_type type;
1709 };
1710
1711 template <typename T0, typename T1>
1712 typename binary_operator<shift_l_op, T0, T1>::result_type
1713 operator()(T0& _0, T1& _1) const
1714 { return binary_operator<shift_l_op, T0, T1>::eval(_0, _1); }
1715 };
1716
1717 //////////////////////////////////
1718 template <typename BaseT, typename T1>
1719 inline typename impl::make_binary1<shift_l_op, BaseT, T1>::type
1720 operator<<(actor<BaseT> const& _0, T1 CREF _1)
1721 {
1722 return impl::make_binary1<shift_l_op, BaseT, T1>::construct(_0, _1);
1723 }
1724
1725 //////////////////////////////////
1726 template <typename T0, typename BaseT>
1727 inline typename impl::make_binary2<shift_l_op, T0, BaseT>::type
1728 operator<<(T0 CREF _0, actor<BaseT> const& _1)
1729 {
1730 return impl::make_binary2<shift_l_op, T0, BaseT>::construct(_0, _1);
1731 }
1732
1733 //////////////////////////////////
1734 template <typename BaseT0, typename BaseT1>
1735 inline typename impl::make_binary3<shift_l_op, BaseT0, BaseT1>::type
1736 operator<<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1737 {
1738 return impl::make_binary3<shift_l_op, BaseT0, BaseT1>::construct(_0, _1);
1739 }
1740
1741 ///////////////////////////////////////////////////////////////////////////////
1742 //
1743 // shift right lazy operator (infix >>)
1744 //
1745 ///////////////////////////////////////////////////////////////////////////////
1746 struct shift_r_op {
1747
1748 template <typename T0, typename T1>
1749 struct result {
1750
1751 typedef typename binary_operator<shift_r_op, T0, T1>
1752 ::result_type type;
1753 };
1754
1755 template <typename T0, typename T1>
1756 typename binary_operator<shift_r_op, T0, T1>::result_type
1757 operator()(T0& _0, T1& _1) const
1758 { return binary_operator<shift_r_op, T0, T1>::eval(_0, _1); }
1759 };
1760
1761 //////////////////////////////////
1762 template <typename BaseT, typename T1>
1763 inline typename impl::make_binary1<shift_r_op, BaseT, T1>::type
1764 operator>>(actor<BaseT> const& _0, T1 CREF _1)
1765 {
1766 return impl::make_binary1<shift_r_op, BaseT, T1>::construct(_0, _1);
1767 }
1768
1769 //////////////////////////////////
1770 template <typename T0, typename BaseT>
1771 inline typename impl::make_binary2<shift_r_op, T0, BaseT>::type
1772 operator>>(T0 CREF _0, actor<BaseT> const& _1)
1773 {
1774 return impl::make_binary2<shift_r_op, T0, BaseT>::construct(_0, _1);
1775 }
1776
1777 //////////////////////////////////
1778 template <typename BaseT0, typename BaseT1>
1779 inline typename impl::make_binary3<shift_r_op, BaseT0, BaseT1>::type
1780 operator>>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1781 {
1782 return impl::make_binary3<shift_r_op, BaseT0, BaseT1>::construct(_0, _1);
1783 }
1784
1785 ///////////////////////////////////////////////////////////////////////////////
1786 //
1787 // equal lazy operator (infix ==)
1788 //
1789 ///////////////////////////////////////////////////////////////////////////////
1790 struct eq_op {
1791
1792 template <typename T0, typename T1>
1793 struct result {
1794
1795 typedef typename binary_operator<eq_op, T0, T1>
1796 ::result_type type;
1797 };
1798
1799 template <typename T0, typename T1>
1800 typename binary_operator<eq_op, T0, T1>::result_type
1801 operator()(T0& _0, T1& _1) const
1802 { return binary_operator<eq_op, T0, T1>::eval(_0, _1); }
1803 };
1804
1805 //////////////////////////////////
1806 template <typename BaseT, typename T1>
1807 inline typename impl::make_binary1<eq_op, BaseT, T1>::type
1808 operator==(actor<BaseT> const& _0, T1 CREF _1)
1809 {
1810 return impl::make_binary1<eq_op, BaseT, T1>::construct(_0, _1);
1811 }
1812
1813 //////////////////////////////////
1814 template <typename T0, typename BaseT>
1815 inline typename impl::make_binary2<eq_op, T0, BaseT>::type
1816 operator==(T0 CREF _0, actor<BaseT> const& _1)
1817 {
1818 return impl::make_binary2<eq_op, T0, BaseT>::construct(_0, _1);
1819 }
1820
1821 //////////////////////////////////
1822 template <typename BaseT0, typename BaseT1>
1823 inline typename impl::make_binary3<eq_op, BaseT0, BaseT1>::type
1824 operator==(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1825 {
1826 return impl::make_binary3<eq_op, BaseT0, BaseT1>::construct(_0, _1);
1827 }
1828
1829 ///////////////////////////////////////////////////////////////////////////////
1830 //
1831 // not equal lazy operator (infix !=)
1832 //
1833 ///////////////////////////////////////////////////////////////////////////////
1834 struct not_eq_op {
1835
1836 template <typename T0, typename T1>
1837 struct result {
1838
1839 typedef typename binary_operator<not_eq_op, T0, T1>
1840 ::result_type type;
1841 };
1842
1843 template <typename T0, typename T1>
1844 typename binary_operator<not_eq_op, T0, T1>::result_type
1845 operator()(T0& _0, T1& _1) const
1846 { return binary_operator<not_eq_op, T0, T1>::eval(_0, _1); }
1847 };
1848
1849 //////////////////////////////////
1850 template <typename BaseT, typename T1>
1851 inline typename impl::make_binary1<not_eq_op, BaseT, T1>::type
1852 operator!=(actor<BaseT> const& _0, T1 CREF _1)
1853 {
1854 return impl::make_binary1<not_eq_op, BaseT, T1>::construct(_0, _1);
1855 }
1856
1857 //////////////////////////////////
1858 template <typename T0, typename BaseT>
1859 inline typename impl::make_binary2<not_eq_op, T0, BaseT>::type
1860 operator!=(T0 CREF _0, actor<BaseT> const& _1)
1861 {
1862 return impl::make_binary2<not_eq_op, T0, BaseT>::construct(_0, _1);
1863 }
1864
1865 //////////////////////////////////
1866 template <typename BaseT0, typename BaseT1>
1867 inline typename impl::make_binary3<not_eq_op, BaseT0, BaseT1>::type
1868 operator!=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1869 {
1870 return impl::make_binary3<not_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1871 }
1872
1873 ///////////////////////////////////////////////////////////////////////////////
1874 //
1875 // less than lazy operator (infix <)
1876 //
1877 ///////////////////////////////////////////////////////////////////////////////
1878 struct lt_op {
1879
1880 template <typename T0, typename T1>
1881 struct result {
1882
1883 typedef typename binary_operator<lt_op, T0, T1>
1884 ::result_type type;
1885 };
1886
1887 template <typename T0, typename T1>
1888 typename binary_operator<lt_op, T0, T1>::result_type
1889 operator()(T0& _0, T1& _1) const
1890 { return binary_operator<lt_op, T0, T1>::eval(_0, _1); }
1891 };
1892
1893 //////////////////////////////////
1894 template <typename BaseT, typename T1>
1895 inline typename impl::make_binary1<lt_op, BaseT, T1>::type
1896 operator<(actor<BaseT> const& _0, T1 CREF _1)
1897 {
1898 return impl::make_binary1<lt_op, BaseT, T1>::construct(_0, _1);
1899 }
1900
1901 //////////////////////////////////
1902 template <typename T0, typename BaseT>
1903 inline typename impl::make_binary2<lt_op, T0, BaseT>::type
1904 operator<(T0 CREF _0, actor<BaseT> const& _1)
1905 {
1906 return impl::make_binary2<lt_op, T0, BaseT>::construct(_0, _1);
1907 }
1908
1909 //////////////////////////////////
1910 template <typename BaseT0, typename BaseT1>
1911 inline typename impl::make_binary3<lt_op, BaseT0, BaseT1>::type
1912 operator<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1913 {
1914 return impl::make_binary3<lt_op, BaseT0, BaseT1>::construct(_0, _1);
1915 }
1916
1917 ///////////////////////////////////////////////////////////////////////////////
1918 //
1919 // less than equal lazy operator (infix <=)
1920 //
1921 ///////////////////////////////////////////////////////////////////////////////
1922 struct lt_eq_op {
1923
1924 template <typename T0, typename T1>
1925 struct result {
1926
1927 typedef typename binary_operator<lt_eq_op, T0, T1>
1928 ::result_type type;
1929 };
1930
1931 template <typename T0, typename T1>
1932 typename binary_operator<lt_eq_op, T0, T1>::result_type
1933 operator()(T0& _0, T1& _1) const
1934 { return binary_operator<lt_eq_op, T0, T1>::eval(_0, _1); }
1935 };
1936
1937 //////////////////////////////////
1938 template <typename BaseT, typename T1>
1939 inline typename impl::make_binary1<lt_eq_op, BaseT, T1>::type
1940 operator<=(actor<BaseT> const& _0, T1 CREF _1)
1941 {
1942 return impl::make_binary1<lt_eq_op, BaseT, T1>::construct(_0, _1);
1943 }
1944
1945 //////////////////////////////////
1946 template <typename T0, typename BaseT>
1947 inline typename impl::make_binary2<lt_eq_op, T0, BaseT>::type
1948 operator<=(T0 CREF _0, actor<BaseT> const& _1)
1949 {
1950 return impl::make_binary2<lt_eq_op, T0, BaseT>::construct(_0, _1);
1951 }
1952
1953 //////////////////////////////////
1954 template <typename BaseT0, typename BaseT1>
1955 inline typename impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::type
1956 operator<=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1957 {
1958 return impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1959 }
1960
1961 ///////////////////////////////////////////////////////////////////////////////
1962 //
1963 // greater than lazy operator (infix >)
1964 //
1965 ///////////////////////////////////////////////////////////////////////////////
1966 struct gt_op {
1967
1968 template <typename T0, typename T1>
1969 struct result {
1970
1971 typedef typename binary_operator<gt_op, T0, T1>
1972 ::result_type type;
1973 };
1974
1975 template <typename T0, typename T1>
1976 typename binary_operator<gt_op, T0, T1>::result_type
1977 operator()(T0& _0, T1& _1) const
1978 { return binary_operator<gt_op, T0, T1>::eval(_0, _1); }
1979 };
1980
1981 //////////////////////////////////
1982 template <typename BaseT, typename T1>
1983 inline typename impl::make_binary1<gt_op, BaseT, T1>::type
1984 operator>(actor<BaseT> const& _0, T1 CREF _1)
1985 {
1986 return impl::make_binary1<gt_op, BaseT, T1>::construct(_0, _1);
1987 }
1988
1989 //////////////////////////////////
1990 template <typename T0, typename BaseT>
1991 inline typename impl::make_binary2<gt_op, T0, BaseT>::type
1992 operator>(T0 CREF _0, actor<BaseT> const& _1)
1993 {
1994 return impl::make_binary2<gt_op, T0, BaseT>::construct(_0, _1);
1995 }
1996
1997 //////////////////////////////////
1998 template <typename BaseT0, typename BaseT1>
1999 inline typename impl::make_binary3<gt_op, BaseT0, BaseT1>::type
2000 operator>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2001 {
2002 return impl::make_binary3<gt_op, BaseT0, BaseT1>::construct(_0, _1);
2003 }
2004
2005 ///////////////////////////////////////////////////////////////////////////////
2006 //
2007 // greater than equal lazy operator (infix >=)
2008 //
2009 ///////////////////////////////////////////////////////////////////////////////
2010 struct gt_eq_op {
2011
2012 template <typename T0, typename T1>
2013 struct result {
2014
2015 typedef typename binary_operator<gt_eq_op, T0, T1>
2016 ::result_type type;
2017 };
2018
2019 template <typename T0, typename T1>
2020 typename binary_operator<gt_eq_op, T0, T1>::result_type
2021 operator()(T0& _0, T1& _1) const
2022 { return binary_operator<gt_eq_op, T0, T1>::eval(_0, _1); }
2023 };
2024
2025 //////////////////////////////////
2026 template <typename BaseT, typename T1>
2027 inline typename impl::make_binary1<gt_eq_op, BaseT, T1>::type
2028 operator>=(actor<BaseT> const& _0, T1 CREF _1)
2029 {
2030 return impl::make_binary1<gt_eq_op, BaseT, T1>::construct(_0, _1);
2031 }
2032
2033 //////////////////////////////////
2034 template <typename T0, typename BaseT>
2035 inline typename impl::make_binary2<gt_eq_op, T0, BaseT>::type
2036 operator>=(T0 CREF _0, actor<BaseT> const& _1)
2037 {
2038 return impl::make_binary2<gt_eq_op, T0, BaseT>::construct(_0, _1);
2039 }
2040
2041 //////////////////////////////////
2042 template <typename BaseT0, typename BaseT1>
2043 inline typename impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::type
2044 operator>=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2045 {
2046 return impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
2047 }
2048
2049 ///////////////////////////////////////////////////////////////////////////////
2050 //
2051 // logical and lazy operator (infix &&)
2052 //
2053 // The logical_and_composite class and its corresponding generators are
2054 // provided to allow short-circuit evaluation of the operator's
2055 // operands.
2056 //
2057 ///////////////////////////////////////////////////////////////////////////////
2058 template <typename A0, typename A1>
2059 struct logical_and_composite {
2060
2061 typedef logical_and_composite<A0, A1> self_t;
2062
2063 template <typename TupleT>
2064 struct result {
2065
2066 typedef typename binary_operator<logical_and_op,
2067 typename actor_result<A0, TupleT>::plain_type,
2068 typename actor_result<A1, TupleT>::plain_type
2069 >::result_type type;
2070 };
2071
2072 logical_and_composite(A0 const& _0, A1 const& _1)
2073 : a0(_0), a1(_1) {}
2074
2075 template <typename TupleT>
2076 typename actor_result<self_t, TupleT>::type
2077 eval(TupleT const& args) const
2078 {
2079 return a0.eval(args) && a1.eval(args);
2080 }
2081
2082 A0 a0; A1 a1; // actors
2083 };
2084
2085 #if !(defined(__ICL) && __ICL <= 500)
2086 //////////////////////////////////
2087 template <typename BaseT, typename T1>
2088 inline actor<logical_and_composite
2089 <actor<BaseT>, typename as_actor<T1>::type> >
2090 operator&&(actor<BaseT> const& _0, T1 CREF _1)
2091 {
2092 return logical_and_composite
2093 <actor<BaseT>, typename as_actor<T1>::type>
2094 (_0, as_actor<T1>::convert(_1));
2095 }
2096
2097 //////////////////////////////////
2098 template <typename T0, typename BaseT>
2099 inline actor<logical_and_composite
2100 <typename as_actor<T0>::type, actor<BaseT> > >
2101 operator&&(T0 CREF _0, actor<BaseT> const& _1)
2102 {
2103 return logical_and_composite
2104 <typename as_actor<T0>::type, actor<BaseT> >
2105 (as_actor<T0>::convert(_0), _1);
2106 }
2107
2108 //////////////////////////////////
2109 template <typename BaseT0, typename BaseT1>
2110 inline actor<logical_and_composite
2111 <actor<BaseT0>, actor<BaseT1> > >
2112 operator&&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2113 {
2114 return logical_and_composite
2115 <actor<BaseT0>, actor<BaseT1> >
2116 (_0, _1);
2117 }
2118 #else
2119 //////////////////////////////////
2120 template <typename T0, typename T1>
2121 inline actor<logical_and_composite
2122 <typename as_actor<T0>::type, typename as_actor<T1>::type> >
2123 operator&&(T0 CREF _0, T1 CREF _1)
2124 {
2125 return logical_and_composite
2126 <typename as_actor<T0>::type, typename as_actor<T1>::type>
2127 (as_actor<T0>::convert(_0), as_actor<T1>::convert(_1));
2128 }
2129 #endif // !(__ICL && __ICL <= 500)
2130
2131 ///////////////////////////////////////////////////////////////////////////////
2132 //
2133 // logical or lazy operator (infix ||)
2134 //
2135 // The logical_or_composite class and its corresponding generators are
2136 // provided to allow short-circuit evaluation of the operator's
2137 // operands.
2138 //
2139 ///////////////////////////////////////////////////////////////////////////////
2140 template <typename A0, typename A1>
2141 struct logical_or_composite {
2142
2143 typedef logical_or_composite<A0, A1> self_t;
2144
2145 template <typename TupleT>
2146 struct result {
2147
2148 typedef typename binary_operator<logical_or_op,
2149 typename actor_result<A0, TupleT>::plain_type,
2150 typename actor_result<A1, TupleT>::plain_type
2151 >::result_type type;
2152 };
2153
2154 logical_or_composite(A0 const& _0, A1 const& _1)
2155 : a0(_0), a1(_1) {}
2156
2157 template <typename TupleT>
2158 typename actor_result<self_t, TupleT>::type
2159 eval(TupleT const& args) const
2160 {
2161 return a0.eval(args) || a1.eval(args);
2162 }
2163
2164 A0 a0; A1 a1; // actors
2165 };
2166
2167 //////////////////////////////////
2168 template <typename BaseT, typename T1>
2169 inline actor<logical_or_composite
2170 <actor<BaseT>, typename as_actor<T1>::type> >
2171 operator||(actor<BaseT> const& _0, T1 CREF _1)
2172 {
2173 return logical_or_composite
2174 <actor<BaseT>, typename as_actor<T1>::type>
2175 (_0, as_actor<T1>::convert(_1));
2176 }
2177
2178 //////////////////////////////////
2179 template <typename T0, typename BaseT>
2180 inline actor<logical_or_composite
2181 <typename as_actor<T0>::type, actor<BaseT> > >
2182 operator||(T0 CREF _0, actor<BaseT> const& _1)
2183 {
2184 return logical_or_composite
2185 <typename as_actor<T0>::type, actor<BaseT> >
2186 (as_actor<T0>::convert(_0), _1);
2187 }
2188
2189 //////////////////////////////////
2190 template <typename BaseT0, typename BaseT1>
2191 inline actor<logical_or_composite
2192 <actor<BaseT0>, actor<BaseT1> > >
2193 operator||(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2194 {
2195 return logical_or_composite
2196 <actor<BaseT0>, actor<BaseT1> >
2197 (_0, _1);
2198 }
2199
2200 } // namespace phoenix
2201
2202 #undef CREF
2203 #endif