1
/*=============================================================================
3
Copyright (c) 2001-2002 Joel de Guzman
5
Permission to copy, use, modify, sell and distribute this software
6
is granted provided this copyright notice appears in all copies.
7
This software is provided "as is" without express or implied
8
warranty, and with no claim as to its suitability for any purpose.
9
==============================================================================*/
10
#ifndef PHOENIX_OPERATORS_HPP
11
#define PHOENIX_OPERATORS_HPP
13
///////////////////////////////////////////////////////////////////////////////
14
#if !defined(BOOST_NO_CWCTYPE)
18
#if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700)
24
#include "boost/spirit/phoenix/actor.hpp"
25
#include "boost/spirit/phoenix/composite.hpp"
26
#include "boost/config.hpp"
28
///////////////////////////////////////////////////////////////////////////////
31
///////////////////////////////////////////////////////////////////////////////
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:
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.
55
// (arg1 + arg2) * arg3
57
// does nothing more than return a composite. T1 second function
58
// call will evaluate the actual operators. Example:
60
// int i = 4, j = 5, k = 6;
61
// cout << ((arg1 + arg2) * arg3)(i, j, k);
63
// will print out "54".
65
// Arbitrarily complex expressions can be lazily evaluated
66
// following three simple rules:
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
75
// 2) Lazy evaluated unary operators apply only to operands
76
// which are actor objects.
78
// 3) The result of a lazy operator is a composite actor object
79
// that can in turn apply to rule 1.
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,
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).
101
// Supported operators:
105
// prefix: ~, !, -, +, ++, --, & (reference), * (dereference)
110
// =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
111
// +, -, *, /, %, &, |, ^, <<, >>
112
// ==, !=, <, >, <=, >=
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:
126
// Prefix -, + and ~ accept constant arguments and return an
129
// The ! accept constant arguments and returns a boolean
132
// The & (address-of), * (dereference) both return a reference
135
// Prefix ++ returns a reference to its mutable argument after
136
// it is incremented.
138
// Postfix ++ returns the mutable argument by value before it
141
// The += and its family accept mutable right hand side (rhs)
142
// operand and return a reference to the rhs operand.
144
// Infix + and its family accept constant arguments and return
145
// an object by value.
147
// The == and its family accept constant arguments and return a
150
// Operators && and || accept constant arguments and return a
151
// boolean result and are short circuit evaluated as expected.
153
///////////////////////////////////////////////////////////////////////////////
155
///////////////////////////////////////////////////////////////////////////////
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).
165
///////////////////////////////////////////////////////////////////////////////
167
// Unary operator tags
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;
175
// Binary operator tags
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;
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;
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;
193
///////////////////////////////////////////////////////////////////////////////
195
// unary_operator<TagT, T>
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.
202
// TagT is one of the unary operator tags above and T is the data
203
// type (argument) involved in the operation.
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.
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.
216
///////////////////////////////////////////////////////////////////////////////
217
template <typename TagT, typename T>
218
struct unary_operator;
220
//////////////////////////////////
221
template <typename T>
222
struct unary_operator<negative_op, T> {
224
typedef T const result_type;
225
static result_type eval(T const& v)
229
//////////////////////////////////
230
template <typename T>
231
struct unary_operator<positive_op, T> {
233
typedef T const result_type;
234
static result_type eval(T const& v)
238
//////////////////////////////////
239
template <typename T>
240
struct unary_operator<logical_not_op, T> {
242
typedef bool result_type;
243
static result_type eval(T const& v)
247
//////////////////////////////////
248
template <typename T>
249
struct unary_operator<invert_op, T> {
251
typedef T const result_type;
252
static result_type eval(T const& v)
256
//////////////////////////////////
257
template <typename T>
258
struct unary_operator<reference_op, T> {
260
typedef T* result_type;
261
static result_type eval(T& v)
265
//////////////////////////////////
266
template <typename T>
267
struct unary_operator<dereference_op, T*> {
269
typedef T& result_type;
270
static result_type eval(T* v)
274
//////////////////////////////////
275
template <typename T>
276
struct unary_operator<dereference_op, T* const> {
278
typedef T& result_type;
279
static result_type eval(T* const v)
283
//////////////////////////////////
285
struct unary_operator<dereference_op, nil_t> {
287
// G++ eager template instantiation
288
// somehow requires this.
289
typedef nil_t result_type;
292
//////////////////////////////////
295
struct unary_operator<dereference_op, nil_t const> {
297
// G++ eager template instantiation
298
// somehow requires this.
299
typedef nil_t result_type;
303
//////////////////////////////////
304
template <typename T>
305
struct unary_operator<pre_incr_op, T> {
307
typedef T& result_type;
308
static result_type eval(T& v)
312
//////////////////////////////////
313
template <typename T>
314
struct unary_operator<pre_decr_op, T> {
316
typedef T& result_type;
317
static result_type eval(T& v)
321
//////////////////////////////////
322
template <typename T>
323
struct unary_operator<post_incr_op, T> {
325
typedef T const result_type;
326
static result_type eval(T& v)
327
{ T t(v); ++v; return t; }
330
//////////////////////////////////
331
template <typename T>
332
struct unary_operator<post_decr_op, T> {
334
typedef T const result_type;
335
static result_type eval(T& v)
336
{ T t(v); --v; return t; }
339
///////////////////////////////////////////////////////////////////////////////
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.
351
// Take note that ranks 0..9999 are reserved for the framework.
353
///////////////////////////////////////////////////////////////////////////////
354
template <typename T>
355
struct rank { static int const value = INT_MAX; };
357
template <> struct rank<void> { static int const value = 0; };
358
template <> struct rank<bool> { static int const value = 10; };
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)
367
template <> struct rank<short> { static int const value = 50; };
368
template <> struct rank<unsigned short> { static int const value = 60; };
370
template <> struct rank<int> { static int const value = 70; };
371
template <> struct rank<unsigned int> { static int const value = 80; };
373
template <> struct rank<long> { static int const value = 90; };
374
template <> struct rank<unsigned long> { static int const value = 100; };
376
#ifdef BOOST_HAS_LONG_LONG
377
template <> struct rank<long long> { static int const value = 110; };
378
template <> struct rank<unsigned long long> { static int const value = 120; };
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; };
385
template <typename T> struct rank<T*>
386
{ static int const value = 160; };
388
template <typename T> struct rank<T* const>
389
{ static int const value = 160; };
391
template <typename T, int N> struct rank<T[N]>
392
{ static int const value = 160; };
394
///////////////////////////////////////////////////////////////////////////////
396
// higher_rank<T0, T1>
398
// Chooses the type (T0 or T1) with the higher rank.
400
///////////////////////////////////////////////////////////////////////////////
401
template <typename T0, typename T1>
406
rank1 = rank<T0>::value,
407
rank2 = rank<T1>::value,
409
#if defined __BORLANDC__ && __BORLANDC__ >= 0x561
410
siz = (rank<T0>::value < rank<T1>::value) ? 1 : 2
412
siz = (rank1 < rank2) ? 1 : 2
416
typedef char compare_rank[siz];
417
typedef typename impl::if_t<compare_rank, T1, T0>::type type;
420
///////////////////////////////////////////////////////////////////////////////
422
// binary_operator<TagT, T0, T1>
424
// The binary_operator class implements most of the C++ binary
425
// operators. Each specialization is basically a simple static eval
426
// function plus a result_type typedef that determines the return
427
// type of the eval function.
429
// TagT is one of the binary operator tags above T0 and T1 are the
430
// (arguments') data types involved in the operation.
432
// Only the behavior of C/C++ built-in types are taken into account
433
// in the specializations provided below. For user-defined types,
434
// these specializations may still be used provided that the
435
// operator overloads of such types adhere to the standard behavior
436
// of built-in types.
438
// T1 separate special_ops.hpp file implements more stl savvy
439
// specializations. Other more specialized unary_operator
440
// implementations may be defined by the client for specific
441
// unary operator tags/data types.
443
// All binary_operator except the logical_and_op and logical_or_op
444
// have an eval static function that carries out the actual operation.
445
// The logical_and_op and logical_or_op d are special because these
446
// two operators are short-circuit evaluated.
448
///////////////////////////////////////////////////////////////////////////////
449
template <typename TagT, typename T0, typename T1>
450
struct binary_operator;
452
//////////////////////////////////
453
template <typename T0, typename T1>
454
struct binary_operator<assign_op, T0, T1> {
456
typedef T0& result_type;
457
static result_type eval(T0& lhs, T1 const& rhs)
458
{ return lhs = rhs; }
461
//////////////////////////////////
462
template <typename T1>
463
struct binary_operator<index_op, nil_t, T1> {
465
// G++ eager template instantiation
466
// somehow requires this.
467
typedef nil_t result_type;
470
//////////////////////////////////
471
template <typename T0, typename T1>
472
struct binary_operator<index_op, T0*, T1> {
474
typedef T0& result_type;
475
static result_type eval(T0* ptr, T1 const& index)
476
{ return ptr[index]; }
479
//////////////////////////////////
480
template <typename T0, typename T1>
481
struct binary_operator<index_op, T0* const, T1> {
483
typedef T0& result_type;
484
static result_type eval(T0* const ptr, T1 const& index)
485
{ return ptr[index]; }
488
//////////////////////////////////
489
template <typename T0, int N, typename T1>
490
struct binary_operator<index_op, T0[N], T1> {
492
typedef T0& result_type;
493
static result_type eval(T0* ptr, T1 const& index)
494
{ return ptr[index]; }
497
//////////////////////////////////
498
template <typename T0, typename T1>
499
struct binary_operator<plus_assign_op, T0, T1> {
501
typedef T0& result_type;
502
static result_type eval(T0& lhs, T1 const& rhs)
503
{ return lhs += rhs; }
506
//////////////////////////////////
507
template <typename T0, typename T1>
508
struct binary_operator<minus_assign_op, T0, T1> {
510
typedef T0& result_type;
511
static result_type eval(T0& lhs, T1 const& rhs)
512
{ return lhs -= rhs; }
515
//////////////////////////////////
516
template <typename T0, typename T1>
517
struct binary_operator<times_assign_op, T0, T1> {
519
typedef T0& result_type;
520
static result_type eval(T0& lhs, T1 const& rhs)
521
{ return lhs *= rhs; }
524
//////////////////////////////////
525
template <typename T0, typename T1>
526
struct binary_operator<divide_assign_op, T0, T1> {
528
typedef T0& result_type;
529
static result_type eval(T0& lhs, T1 const& rhs)
530
{ return lhs /= rhs; }
533
//////////////////////////////////
534
template <typename T0, typename T1>
535
struct binary_operator<mod_assign_op, T0, T1> {
537
typedef T0& result_type;
538
static result_type eval(T0& lhs, T1 const& rhs)
539
{ return lhs %= rhs; }
542
//////////////////////////////////
543
template <typename T0, typename T1>
544
struct binary_operator<and_assign_op, T0, T1> {
546
typedef T0& result_type;
547
static result_type eval(T0& lhs, T1 const& rhs)
548
{ return lhs &= rhs; }
551
//////////////////////////////////
552
template <typename T0, typename T1>
553
struct binary_operator<or_assign_op, T0, T1> {
555
typedef T0& result_type;
556
static result_type eval(T0& lhs, T1 const& rhs)
557
{ return lhs |= rhs; }
560
//////////////////////////////////
561
template <typename T0, typename T1>
562
struct binary_operator<xor_assign_op, T0, T1> {
564
typedef T0& result_type;
565
static result_type eval(T0& lhs, T1 const& rhs)
566
{ return lhs ^= rhs; }
569
//////////////////////////////////
570
template <typename T0, typename T1>
571
struct binary_operator<shift_l_assign_op, T0, T1> {
573
typedef T0& result_type;
574
static result_type eval(T0& lhs, T1 const& rhs)
575
{ return lhs <<= rhs; }
578
//////////////////////////////////
579
template <typename T0, typename T1>
580
struct binary_operator<shift_r_assign_op, T0, T1> {
582
typedef T0& result_type;
583
static result_type eval(T0& lhs, T1 const& rhs)
584
{ return lhs >>= rhs; }
587
//////////////////////////////////
588
template <typename T0, typename T1>
589
struct binary_operator<plus_op, T0, T1> {
591
typedef typename higher_rank<T0, T1>::type const result_type;
592
static result_type eval(T0 const& lhs, T1 const& rhs)
593
{ return lhs + rhs; }
596
//////////////////////////////////
597
template <typename T0, typename T1>
598
struct binary_operator<minus_op, T0, T1> {
600
typedef typename higher_rank<T0, T1>::type const result_type;
601
static result_type eval(T0 const& lhs, T1 const& rhs)
602
{ return lhs - rhs; }
605
//////////////////////////////////
606
template <typename T0, typename T1>
607
struct binary_operator<times_op, T0, T1> {
609
typedef typename higher_rank<T0, T1>::type const result_type;
610
static result_type eval(T0 const& lhs, T1 const& rhs)
611
{ return lhs * rhs; }
614
//////////////////////////////////
615
template <typename T0, typename T1>
616
struct binary_operator<divide_op, T0, T1> {
618
typedef typename higher_rank<T0, T1>::type const result_type;
619
static result_type eval(T0 const& lhs, T1 const& rhs)
620
{ return lhs / rhs; }
623
//////////////////////////////////
624
template <typename T0, typename T1>
625
struct binary_operator<mod_op, T0, T1> {
627
typedef typename higher_rank<T0, T1>::type const result_type;
628
static result_type eval(T0 const& lhs, T1 const& rhs)
629
{ return lhs % rhs; }
632
//////////////////////////////////
633
template <typename T0, typename T1>
634
struct binary_operator<and_op, T0, T1> {
636
typedef typename higher_rank<T0, T1>::type const result_type;
637
static result_type eval(T0 const& lhs, T1 const& rhs)
638
{ return lhs & rhs; }
641
//////////////////////////////////
642
template <typename T0, typename T1>
643
struct binary_operator<or_op, T0, T1> {
645
typedef typename higher_rank<T0, T1>::type const result_type;
646
static result_type eval(T0 const& lhs, T1 const& rhs)
647
{ return lhs | rhs; }
650
//////////////////////////////////
651
template <typename T0, typename T1>
652
struct binary_operator<xor_op, T0, T1> {
654
typedef typename higher_rank<T0, T1>::type const result_type;
655
static result_type eval(T0 const& lhs, T1 const& rhs)
656
{ return lhs ^ rhs; }
659
//////////////////////////////////
660
template <typename T0, typename T1>
661
struct binary_operator<shift_l_op, T0, T1> {
663
typedef T0 const result_type;
664
static result_type eval(T0 const& lhs, T1 const& rhs)
665
{ return lhs << rhs; }
668
//////////////////////////////////
669
template <typename T0, typename T1>
670
struct binary_operator<shift_r_op, T0, T1> {
672
typedef T0 const result_type;
673
static result_type eval(T0 const& lhs, T1 const& rhs)
674
{ return lhs >> rhs; }
677
//////////////////////////////////
678
template <typename T0, typename T1>
679
struct binary_operator<eq_op, T0, T1> {
681
typedef bool result_type;
682
static result_type eval(T0 const& lhs, T1 const& rhs)
683
{ return lhs == rhs; }
686
//////////////////////////////////
687
template <typename T0, typename T1>
688
struct binary_operator<not_eq_op, T0, T1> {
690
typedef bool result_type;
691
static result_type eval(T0 const& lhs, T1 const& rhs)
692
{ return lhs != rhs; }
695
//////////////////////////////////
696
template <typename T0, typename T1>
697
struct binary_operator<lt_op, T0, T1> {
699
typedef bool result_type;
700
static result_type eval(T0 const& lhs, T1 const& rhs)
701
{ return lhs < rhs; }
704
//////////////////////////////////
705
template <typename T0, typename T1>
706
struct binary_operator<lt_eq_op, T0, T1> {
708
typedef bool result_type;
709
static result_type eval(T0 const& lhs, T1 const& rhs)
710
{ return lhs <= rhs; }
713
//////////////////////////////////
714
template <typename T0, typename T1>
715
struct binary_operator<gt_op, T0, T1> {
717
typedef bool result_type;
718
static result_type eval(T0 const& lhs, T1 const& rhs)
719
{ return lhs > rhs; }
722
//////////////////////////////////
723
template <typename T0, typename T1>
724
struct binary_operator<gt_eq_op, T0, T1> {
726
typedef bool result_type;
727
static result_type eval(T0 const& lhs, T1 const& rhs)
728
{ return lhs >= rhs; }
731
//////////////////////////////////
732
template <typename T0, typename T1>
733
struct binary_operator<logical_and_op, T0, T1> {
735
typedef bool result_type;
736
// no eval function, see comment above.
739
//////////////////////////////////
740
template <typename T0, typename T1>
741
struct binary_operator<logical_or_op, T0, T1> {
743
typedef bool result_type;
744
// no eval function, see comment above.
747
///////////////////////////////////////////////////////////////////////////////
749
// negative lazy operator (prefix -)
751
///////////////////////////////////////////////////////////////////////////////
754
template <typename T0>
757
typedef typename unary_operator<negative_op, T0>::result_type type;
760
template <typename T0>
761
typename unary_operator<negative_op, T0>::result_type
762
operator()(T0& _0) const
763
{ return unary_operator<negative_op, T0>::eval(_0); }
766
//////////////////////////////////
767
template <typename BaseT>
768
inline typename impl::make_unary<negative_op, BaseT>::type
769
operator-(actor<BaseT> const& _0)
771
return impl::make_unary<negative_op, BaseT>::construct(_0);
774
///////////////////////////////////////////////////////////////////////////////
776
// positive lazy operator (prefix +)
778
///////////////////////////////////////////////////////////////////////////////
781
template <typename T0>
784
typedef typename unary_operator<positive_op, T0>::result_type type;
787
template <typename T0>
788
typename unary_operator<positive_op, T0>::result_type
789
operator()(T0& _0) const
790
{ return unary_operator<positive_op, T0>::eval(_0); }
793
//////////////////////////////////
794
template <typename BaseT>
795
inline typename impl::make_unary<positive_op, BaseT>::type
796
operator+(actor<BaseT> const& _0)
798
return impl::make_unary<positive_op, BaseT>::construct(_0);
801
///////////////////////////////////////////////////////////////////////////////
803
// logical not lazy operator (prefix !)
805
///////////////////////////////////////////////////////////////////////////////
806
struct logical_not_op {
808
template <typename T0>
811
typedef typename unary_operator<logical_not_op, T0>::result_type type;
814
template <typename T0>
815
typename unary_operator<logical_not_op, T0>::result_type
816
operator()(T0& _0) const
817
{ return unary_operator<logical_not_op, T0>::eval(_0); }
820
//////////////////////////////////
821
template <typename BaseT>
822
inline typename impl::make_unary<logical_not_op, BaseT>::type
823
operator!(actor<BaseT> const& _0)
825
return impl::make_unary<logical_not_op, BaseT>::construct(_0);
828
///////////////////////////////////////////////////////////////////////////////
830
// invert lazy operator (prefix ~)
832
///////////////////////////////////////////////////////////////////////////////
835
template <typename T0>
838
typedef typename unary_operator<invert_op, T0>::result_type type;
841
template <typename T0>
842
typename unary_operator<invert_op, T0>::result_type
843
operator()(T0& _0) const
844
{ return unary_operator<invert_op, T0>::eval(_0); }
847
//////////////////////////////////
848
template <typename BaseT>
849
inline typename impl::make_unary<invert_op, BaseT>::type
850
operator~(actor<BaseT> const& _0)
852
return impl::make_unary<invert_op, BaseT>::construct(_0);
855
///////////////////////////////////////////////////////////////////////////////
857
// reference lazy operator (prefix &)
859
///////////////////////////////////////////////////////////////////////////////
860
struct reference_op {
862
template <typename T0>
865
typedef typename unary_operator<reference_op, T0>::result_type type;
868
template <typename T0>
869
typename unary_operator<reference_op, T0>::result_type
870
operator()(T0& _0) const
871
{ return unary_operator<reference_op, T0>::eval(_0); }
874
//////////////////////////////////
875
template <typename BaseT>
876
inline typename impl::make_unary<reference_op, BaseT>::type
877
operator&(actor<BaseT> const& _0)
879
return impl::make_unary<reference_op, BaseT>::construct(_0);
882
///////////////////////////////////////////////////////////////////////////////
884
// dereference lazy operator (prefix *)
886
///////////////////////////////////////////////////////////////////////////////
887
struct dereference_op {
889
template <typename T0>
892
typedef typename unary_operator<dereference_op, T0>::result_type type;
895
template <typename T0>
896
typename unary_operator<dereference_op, T0>::result_type
897
operator()(T0& _0) const
898
{ return unary_operator<dereference_op, T0>::eval(_0); }
901
//////////////////////////////////
902
template <typename BaseT>
903
inline typename impl::make_unary<dereference_op, BaseT>::type
904
operator*(actor<BaseT> const& _0)
906
return impl::make_unary<dereference_op, BaseT>::construct(_0);
909
///////////////////////////////////////////////////////////////////////////////
911
// pre increment lazy operator (prefix ++)
913
///////////////////////////////////////////////////////////////////////////////
916
template <typename T0>
919
typedef typename unary_operator<pre_incr_op, T0>::result_type type;
922
template <typename T0>
923
typename unary_operator<pre_incr_op, T0>::result_type
924
operator()(T0& _0) const
925
{ return unary_operator<pre_incr_op, T0>::eval(_0); }
928
//////////////////////////////////
929
template <typename BaseT>
930
inline typename impl::make_unary<pre_incr_op, BaseT>::type
931
operator++(actor<BaseT> const& _0)
933
return impl::make_unary<pre_incr_op, BaseT>::construct(_0);
936
///////////////////////////////////////////////////////////////////////////////
938
// pre decrement lazy operator (prefix --)
940
///////////////////////////////////////////////////////////////////////////////
943
template <typename T0>
946
typedef typename unary_operator<pre_decr_op, T0>::result_type type;
949
template <typename T0>
950
typename unary_operator<pre_decr_op, T0>::result_type
951
operator()(T0& _0) const
952
{ return unary_operator<pre_decr_op, T0>::eval(_0); }
955
//////////////////////////////////
956
template <typename BaseT>
957
inline typename impl::make_unary<pre_decr_op, BaseT>::type
958
operator--(actor<BaseT> const& _0)
960
return impl::make_unary<pre_decr_op, BaseT>::construct(_0);
963
///////////////////////////////////////////////////////////////////////////////
965
// post increment lazy operator (postfix ++)
967
///////////////////////////////////////////////////////////////////////////////
968
struct post_incr_op {
970
template <typename T0>
973
typedef typename unary_operator<post_incr_op, T0>::result_type type;
976
template <typename T0>
977
typename unary_operator<post_incr_op, T0>::result_type
978
operator()(T0& _0) const
979
{ return unary_operator<post_incr_op, T0>::eval(_0); }
982
//////////////////////////////////
983
template <typename BaseT>
984
inline typename impl::make_unary<post_incr_op, BaseT>::type
985
operator++(actor<BaseT> const& _0, int)
987
return impl::make_unary<post_incr_op, BaseT>::construct(_0);
990
///////////////////////////////////////////////////////////////////////////////
992
// post decrement lazy operator (postfix --)
994
///////////////////////////////////////////////////////////////////////////////
995
struct post_decr_op {
997
template <typename T0>
1000
typedef typename unary_operator<post_decr_op, T0>::result_type type;
1003
template <typename T0>
1004
typename unary_operator<post_decr_op, T0>::result_type
1005
operator()(T0& _0) const
1006
{ return unary_operator<post_decr_op, T0>::eval(_0); }
1009
//////////////////////////////////
1010
template <typename BaseT>
1011
inline typename impl::make_unary<post_decr_op, BaseT>::type
1012
operator--(actor<BaseT> const& _0, int)
1014
return impl::make_unary<post_decr_op, BaseT>::construct(_0);
1017
///////////////////////////////////////////////////////////////////////////////
1019
// assignment lazy operator (infix =)
1020
// The acual lazy operator is a member of the actor class.
1022
///////////////////////////////////////////////////////////////////////////////
1025
template <typename T0, typename T1>
1028
typedef typename binary_operator<assign_op, T0, T1>
1032
template <typename T0, typename T1>
1033
typename binary_operator<assign_op, T0, T1>::result_type
1034
operator()(T0& _0, T1& _1) const
1035
{ return binary_operator<assign_op, T0, T1>::eval(_0, _1); }
1038
//////////////////////////////////
1039
template <typename BaseT>
1040
template <typename B>
1041
inline typename impl::make_binary1<assign_op, BaseT, B>::type
1042
actor<BaseT>::operator=(B const& _1) const
1044
return impl::make_binary1<assign_op, BaseT, B>::construct(*this, _1);
1047
///////////////////////////////////////////////////////////////////////////////
1049
// index lazy operator (array index [])
1050
// The acual lazy operator is a member of the actor class.
1052
///////////////////////////////////////////////////////////////////////////////
1055
template <typename T0, typename T1>
1058
typedef typename binary_operator<index_op, T0, T1>
1062
template <typename T0, typename T1>
1063
typename binary_operator<index_op, T0, T1>::result_type
1064
operator()(T0& _0, T1& _1) const
1065
{ return binary_operator<index_op, T0, T1>::eval(_0, _1); }
1068
//////////////////////////////////
1069
template <typename BaseT>
1070
template <typename B>
1071
inline typename impl::make_binary1<index_op, BaseT, B>::type
1072
actor<BaseT>::operator[](B const& _1) const
1074
return impl::make_binary1<index_op, BaseT, B>::construct(*this, _1);
1077
///////////////////////////////////////////////////////////////////////////////
1079
// plus assign lazy operator (infix +=)
1081
///////////////////////////////////////////////////////////////////////////////
1082
struct plus_assign_op {
1084
template <typename T0, typename T1>
1087
typedef typename binary_operator<plus_assign_op, T0, T1>
1091
template <typename T0, typename T1>
1092
typename binary_operator<plus_assign_op, T0, T1>::result_type
1093
operator()(T0& _0, T1& _1) const
1094
{ return binary_operator<plus_assign_op, T0, T1>::eval(_0, _1); }
1097
//////////////////////////////////
1098
template <typename BaseT, typename T1>
1099
inline typename impl::make_binary1<plus_assign_op, BaseT, T1>::type
1100
operator+=(actor<BaseT> const& _0, T1 CREF _1)
1102
return impl::make_binary1<plus_assign_op, BaseT, T1>::construct(_0, _1);
1105
///////////////////////////////////////////////////////////////////////////////
1107
// minus assign lazy operator (infix -=)
1109
///////////////////////////////////////////////////////////////////////////////
1110
struct minus_assign_op {
1112
template <typename T0, typename T1>
1115
typedef typename binary_operator<minus_assign_op, T0, T1>
1119
template <typename T0, typename T1>
1120
typename binary_operator<minus_assign_op, T0, T1>::result_type
1121
operator()(T0& _0, T1& _1) const
1122
{ return binary_operator<minus_assign_op, T0, T1>::eval(_0, _1); }
1125
//////////////////////////////////
1126
template <typename BaseT, typename T1>
1127
inline typename impl::make_binary1<minus_assign_op, BaseT, T1>::type
1128
operator-=(actor<BaseT> const& _0, T1 CREF _1)
1130
return impl::make_binary1<minus_assign_op, BaseT, T1>::construct(_0, _1);
1133
///////////////////////////////////////////////////////////////////////////////
1135
// times assign lazy operator (infix *=)
1137
///////////////////////////////////////////////////////////////////////////////
1138
struct times_assign_op {
1140
template <typename T0, typename T1>
1143
typedef typename binary_operator<times_assign_op, T0, T1>
1147
template <typename T0, typename T1>
1148
typename binary_operator<times_assign_op, T0, T1>::result_type
1149
operator()(T0& _0, T1& _1) const
1150
{ return binary_operator<times_assign_op, T0, T1>::eval(_0, _1); }
1153
//////////////////////////////////
1154
template <typename BaseT, typename T1>
1155
inline typename impl::make_binary1<times_assign_op, BaseT, T1>::type
1156
operator*=(actor<BaseT> const& _0, T1 CREF _1)
1158
return impl::make_binary1<times_assign_op, BaseT, T1>::construct(_0, _1);
1161
///////////////////////////////////////////////////////////////////////////////
1163
// divide assign lazy operator (infix /=)
1165
///////////////////////////////////////////////////////////////////////////////
1166
struct divide_assign_op {
1168
template <typename T0, typename T1>
1171
typedef typename binary_operator<divide_assign_op, T0, T1>
1175
template <typename T0, typename T1>
1176
typename binary_operator<divide_assign_op, T0, T1>::result_type
1177
operator()(T0& _0, T1& _1) const
1178
{ return binary_operator<divide_assign_op, T0, T1>::eval(_0, _1); }
1181
//////////////////////////////////
1182
template <typename BaseT, typename T1>
1183
inline typename impl::make_binary1<divide_assign_op, BaseT, T1>::type
1184
operator/=(actor<BaseT> const& _0, T1 CREF _1)
1186
return impl::make_binary1<divide_assign_op, BaseT, T1>::construct(_0, _1);
1189
///////////////////////////////////////////////////////////////////////////////
1191
// mod assign lazy operator (infix %=)
1193
///////////////////////////////////////////////////////////////////////////////
1194
struct mod_assign_op {
1196
template <typename T0, typename T1>
1199
typedef typename binary_operator<mod_assign_op, T0, T1>
1203
template <typename T0, typename T1>
1204
typename binary_operator<mod_assign_op, T0, T1>::result_type
1205
operator()(T0& _0, T1& _1) const
1206
{ return binary_operator<mod_assign_op, T0, T1>::eval(_0, _1); }
1209
//////////////////////////////////
1210
template <typename BaseT, typename T1>
1211
inline typename impl::make_binary1<mod_assign_op, BaseT, T1>::type
1212
operator%=(actor<BaseT> const& _0, T1 CREF _1)
1214
return impl::make_binary1<mod_assign_op, BaseT, T1>::construct(_0, _1);
1217
///////////////////////////////////////////////////////////////////////////////
1219
// and assign lazy operator (infix &=)
1221
///////////////////////////////////////////////////////////////////////////////
1222
struct and_assign_op {
1224
template <typename T0, typename T1>
1227
typedef typename binary_operator<and_assign_op, T0, T1>
1231
template <typename T0, typename T1>
1232
typename binary_operator<and_assign_op, T0, T1>::result_type
1233
operator()(T0& _0, T1& _1) const
1234
{ return binary_operator<and_assign_op, T0, T1>::eval(_0, _1); }
1237
//////////////////////////////////
1238
template <typename BaseT, typename T1>
1239
inline typename impl::make_binary1<and_assign_op, BaseT, T1>::type
1240
operator&=(actor<BaseT> const& _0, T1 CREF _1)
1242
return impl::make_binary1<and_assign_op, BaseT, T1>::construct(_0, _1);
1245
///////////////////////////////////////////////////////////////////////////////
1247
// or assign lazy operator (infix |=)
1249
///////////////////////////////////////////////////////////////////////////////
1250
struct or_assign_op {
1252
template <typename T0, typename T1>
1255
typedef typename binary_operator<or_assign_op, T0, T1>
1259
template <typename T0, typename T1>
1260
typename binary_operator<or_assign_op, T0, T1>::result_type
1261
operator()(T0& _0, T1& _1) const
1262
{ return binary_operator<or_assign_op, T0, T1>::eval(_0, _1); }
1265
//////////////////////////////////
1266
template <typename BaseT, typename T1>
1267
inline typename impl::make_binary1<or_assign_op, BaseT, T1>::type
1268
operator|=(actor<BaseT> const& _0, T1 CREF _1)
1270
return impl::make_binary1<or_assign_op, BaseT, T1>::construct(_0, _1);
1273
///////////////////////////////////////////////////////////////////////////////
1275
// xor assign lazy operator (infix ^=)
1277
///////////////////////////////////////////////////////////////////////////////
1278
struct xor_assign_op {
1280
template <typename T0, typename T1>
1283
typedef typename binary_operator<xor_assign_op, T0, T1>
1287
template <typename T0, typename T1>
1288
typename binary_operator<xor_assign_op, T0, T1>::result_type
1289
operator()(T0& _0, T1& _1) const
1290
{ return binary_operator<xor_assign_op, T0, T1>::eval(_0, _1); }
1293
//////////////////////////////////
1294
template <typename BaseT, typename T1>
1295
inline typename impl::make_binary1<xor_assign_op, BaseT, T1>::type
1296
operator^=(actor<BaseT> const& _0, T1 CREF _1)
1298
return impl::make_binary1<xor_assign_op, BaseT, T1>::construct(_0, _1);
1301
///////////////////////////////////////////////////////////////////////////////
1303
// shift left assign lazy operator (infix <<=)
1305
///////////////////////////////////////////////////////////////////////////////
1306
struct shift_l_assign_op {
1308
template <typename T0, typename T1>
1311
typedef typename binary_operator<shift_l_assign_op, T0, T1>
1315
template <typename T0, typename T1>
1316
typename binary_operator<shift_l_assign_op, T0, T1>::result_type
1317
operator()(T0& _0, T1& _1) const
1318
{ return binary_operator<shift_l_assign_op, T0, T1>::eval(_0, _1); }
1321
//////////////////////////////////
1322
template <typename BaseT, typename T1>
1323
inline typename impl::make_binary1<shift_l_assign_op, BaseT, T1>::type
1324
operator<<=(actor<BaseT> const& _0, T1 CREF _1)
1326
return impl::make_binary1<shift_l_assign_op, BaseT, T1>::construct(_0, _1);
1329
///////////////////////////////////////////////////////////////////////////////
1331
// shift right assign lazy operator (infix >>=)
1333
///////////////////////////////////////////////////////////////////////////////
1334
struct shift_r_assign_op {
1336
template <typename T0, typename T1>
1339
typedef typename binary_operator<shift_r_assign_op, T0, T1>
1343
template <typename T0, typename T1>
1344
typename binary_operator<shift_r_assign_op, T0, T1>::result_type
1345
operator()(T0& _0, T1& _1) const
1346
{ return binary_operator<shift_r_assign_op, T0, T1>::eval(_0, _1); }
1349
//////////////////////////////////
1350
template <typename BaseT, typename T1>
1351
inline typename impl::make_binary1<shift_r_assign_op, BaseT, T1>::type
1352
operator>>=(actor<BaseT> const& _0, T1 CREF _1)
1354
return impl::make_binary1<shift_r_assign_op, BaseT, T1>::construct(_0, _1);
1357
///////////////////////////////////////////////////////////////////////////////
1359
// plus lazy operator (infix +)
1361
///////////////////////////////////////////////////////////////////////////////
1364
template <typename T0, typename T1>
1367
typedef typename binary_operator<plus_op, T0, T1>
1371
template <typename T0, typename T1>
1372
typename binary_operator<plus_op, T0, T1>::result_type
1373
operator()(T0& _0, T1& _1) const
1374
{ return binary_operator<plus_op, T0, T1>::eval(_0, _1); }
1377
//////////////////////////////////
1378
template <typename BaseT, typename T1>
1379
inline typename impl::make_binary1<plus_op, BaseT, T1>::type
1380
operator+(actor<BaseT> const& _0, T1 CREF _1)
1382
return impl::make_binary1<plus_op, BaseT, T1>::construct(_0, _1);
1385
//////////////////////////////////
1386
template <typename T0, typename BaseT>
1387
inline typename impl::make_binary2<plus_op, T0, BaseT>::type
1388
operator+(T0 CREF _0, actor<BaseT> const& _1)
1390
return impl::make_binary2<plus_op, T0, BaseT>::construct(_0, _1);
1393
//////////////////////////////////
1394
template <typename BaseT0, typename BaseT1>
1395
inline typename impl::make_binary3<plus_op, BaseT0, BaseT1>::type
1396
operator+(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1398
return impl::make_binary3<plus_op, BaseT0, BaseT1>::construct(_0, _1);
1401
///////////////////////////////////////////////////////////////////////////////
1403
// minus lazy operator (infix -)
1405
///////////////////////////////////////////////////////////////////////////////
1408
template <typename T0, typename T1>
1411
typedef typename binary_operator<minus_op, T0, T1>
1415
template <typename T0, typename T1>
1416
typename binary_operator<minus_op, T0, T1>::result_type
1417
operator()(T0& _0, T1& _1) const
1418
{ return binary_operator<minus_op, T0, T1>::eval(_0, _1); }
1421
//////////////////////////////////
1422
template <typename BaseT, typename T1>
1423
inline typename impl::make_binary1<minus_op, BaseT, T1>::type
1424
operator-(actor<BaseT> const& _0, T1 CREF _1)
1426
return impl::make_binary1<minus_op, BaseT, T1>::construct(_0, _1);
1429
//////////////////////////////////
1430
template <typename T0, typename BaseT>
1431
inline typename impl::make_binary2<minus_op, T0, BaseT>::type
1432
operator-(T0 CREF _0, actor<BaseT> const& _1)
1434
return impl::make_binary2<minus_op, T0, BaseT>::construct(_0, _1);
1437
//////////////////////////////////
1438
template <typename BaseT0, typename BaseT1>
1439
inline typename impl::make_binary3<minus_op, BaseT0, BaseT1>::type
1440
operator-(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1442
return impl::make_binary3<minus_op, BaseT0, BaseT1>::construct(_0, _1);
1445
///////////////////////////////////////////////////////////////////////////////
1447
// times lazy operator (infix *)
1449
///////////////////////////////////////////////////////////////////////////////
1452
template <typename T0, typename T1>
1455
typedef typename binary_operator<times_op, T0, T1>
1459
template <typename T0, typename T1>
1460
typename binary_operator<times_op, T0, T1>::result_type
1461
operator()(T0& _0, T1& _1) const
1462
{ return binary_operator<times_op, T0, T1>::eval(_0, _1); }
1465
//////////////////////////////////
1466
template <typename BaseT, typename T1>
1467
inline typename impl::make_binary1<times_op, BaseT, T1>::type
1468
operator*(actor<BaseT> const& _0, T1 CREF _1)
1470
return impl::make_binary1<times_op, BaseT, T1>::construct(_0, _1);
1473
//////////////////////////////////
1474
template <typename T0, typename BaseT>
1475
inline typename impl::make_binary2<times_op, T0, BaseT>::type
1476
operator*(T0 CREF _0, actor<BaseT> const& _1)
1478
return impl::make_binary2<times_op, T0, BaseT>::construct(_0, _1);
1481
//////////////////////////////////
1482
template <typename BaseT0, typename BaseT1>
1483
inline typename impl::make_binary3<times_op, BaseT0, BaseT1>::type
1484
operator*(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1486
return impl::make_binary3<times_op, BaseT0, BaseT1>::construct(_0, _1);
1489
///////////////////////////////////////////////////////////////////////////////
1491
// divide lazy operator (infix /)
1493
///////////////////////////////////////////////////////////////////////////////
1496
template <typename T0, typename T1>
1499
typedef typename binary_operator<divide_op, T0, T1>
1503
template <typename T0, typename T1>
1504
typename binary_operator<divide_op, T0, T1>::result_type
1505
operator()(T0& _0, T1& _1) const
1506
{ return binary_operator<divide_op, T0, T1>::eval(_0, _1); }
1509
//////////////////////////////////
1510
template <typename BaseT, typename T1>
1511
inline typename impl::make_binary1<divide_op, BaseT, T1>::type
1512
operator/(actor<BaseT> const& _0, T1 CREF _1)
1514
return impl::make_binary1<divide_op, BaseT, T1>::construct(_0, _1);
1517
//////////////////////////////////
1518
template <typename T0, typename BaseT>
1519
inline typename impl::make_binary2<divide_op, T0, BaseT>::type
1520
operator/(T0 CREF _0, actor<BaseT> const& _1)
1522
return impl::make_binary2<divide_op, T0, BaseT>::construct(_0, _1);
1525
//////////////////////////////////
1526
template <typename BaseT0, typename BaseT1>
1527
inline typename impl::make_binary3<divide_op, BaseT0, BaseT1>::type
1528
operator/(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1530
return impl::make_binary3<divide_op, BaseT0, BaseT1>::construct(_0, _1);
1533
///////////////////////////////////////////////////////////////////////////////
1535
// mod lazy operator (infix %)
1537
///////////////////////////////////////////////////////////////////////////////
1540
template <typename T0, typename T1>
1543
typedef typename binary_operator<mod_op, T0, T1>
1547
template <typename T0, typename T1>
1548
typename binary_operator<mod_op, T0, T1>::result_type
1549
operator()(T0& _0, T1& _1) const
1550
{ return binary_operator<mod_op, T0, T1>::eval(_0, _1); }
1553
//////////////////////////////////
1554
template <typename BaseT, typename T1>
1555
inline typename impl::make_binary1<mod_op, BaseT, T1>::type
1556
operator%(actor<BaseT> const& _0, T1 CREF _1)
1558
return impl::make_binary1<mod_op, BaseT, T1>::construct(_0, _1);
1561
//////////////////////////////////
1562
template <typename T0, typename BaseT>
1563
inline typename impl::make_binary2<mod_op, T0, BaseT>::type
1564
operator%(T0 CREF _0, actor<BaseT> const& _1)
1566
return impl::make_binary2<mod_op, T0, BaseT>::construct(_0, _1);
1569
//////////////////////////////////
1570
template <typename BaseT0, typename BaseT1>
1571
inline typename impl::make_binary3<mod_op, BaseT0, BaseT1>::type
1572
operator%(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1574
return impl::make_binary3<mod_op, BaseT0, BaseT1>::construct(_0, _1);
1577
///////////////////////////////////////////////////////////////////////////////
1579
// and lazy operator (infix &)
1581
///////////////////////////////////////////////////////////////////////////////
1584
template <typename T0, typename T1>
1587
typedef typename binary_operator<and_op, T0, T1>
1591
template <typename T0, typename T1>
1592
typename binary_operator<and_op, T0, T1>::result_type
1593
operator()(T0& _0, T1& _1) const
1594
{ return binary_operator<and_op, T0, T1>::eval(_0, _1); }
1597
//////////////////////////////////
1598
template <typename BaseT, typename T1>
1599
inline typename impl::make_binary1<and_op, BaseT, T1>::type
1600
operator&(actor<BaseT> const& _0, T1 CREF _1)
1602
return impl::make_binary1<and_op, BaseT, T1>::construct(_0, _1);
1605
//////////////////////////////////
1606
template <typename T0, typename BaseT>
1607
inline typename impl::make_binary2<and_op, T0, BaseT>::type
1608
operator&(T0 CREF _0, actor<BaseT> const& _1)
1610
return impl::make_binary2<and_op, T0, BaseT>::construct(_0, _1);
1613
//////////////////////////////////
1614
template <typename BaseT0, typename BaseT1>
1615
inline typename impl::make_binary3<and_op, BaseT0, BaseT1>::type
1616
operator&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1618
return impl::make_binary3<and_op, BaseT0, BaseT1>::construct(_0, _1);
1621
///////////////////////////////////////////////////////////////////////////////
1623
// or lazy operator (infix |)
1625
///////////////////////////////////////////////////////////////////////////////
1628
template <typename T0, typename T1>
1631
typedef typename binary_operator<or_op, T0, T1>
1635
template <typename T0, typename T1>
1636
typename binary_operator<or_op, T0, T1>::result_type
1637
operator()(T0& _0, T1& _1) const
1638
{ return binary_operator<or_op, T0, T1>::eval(_0, _1); }
1641
//////////////////////////////////
1642
template <typename BaseT, typename T1>
1643
inline typename impl::make_binary1<or_op, BaseT, T1>::type
1644
operator|(actor<BaseT> const& _0, T1 CREF _1)
1646
return impl::make_binary1<or_op, BaseT, T1>::construct(_0, _1);
1649
//////////////////////////////////
1650
template <typename T0, typename BaseT>
1651
inline typename impl::make_binary2<or_op, T0, BaseT>::type
1652
operator|(T0 CREF _0, actor<BaseT> const& _1)
1654
return impl::make_binary2<or_op, T0, BaseT>::construct(_0, _1);
1657
//////////////////////////////////
1658
template <typename BaseT0, typename BaseT1>
1659
inline typename impl::make_binary3<or_op, BaseT0, BaseT1>::type
1660
operator|(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1662
return impl::make_binary3<or_op, BaseT0, BaseT1>::construct(_0, _1);
1665
///////////////////////////////////////////////////////////////////////////////
1667
// xor lazy operator (infix ^)
1669
///////////////////////////////////////////////////////////////////////////////
1672
template <typename T0, typename T1>
1675
typedef typename binary_operator<xor_op, T0, T1>
1679
template <typename T0, typename T1>
1680
typename binary_operator<xor_op, T0, T1>::result_type
1681
operator()(T0& _0, T1& _1) const
1682
{ return binary_operator<xor_op, T0, T1>::eval(_0, _1); }
1685
//////////////////////////////////
1686
template <typename BaseT, typename T1>
1687
inline typename impl::make_binary1<xor_op, BaseT, T1>::type
1688
operator^(actor<BaseT> const& _0, T1 CREF _1)
1690
return impl::make_binary1<xor_op, BaseT, T1>::construct(_0, _1);
1693
//////////////////////////////////
1694
template <typename T0, typename BaseT>
1695
inline typename impl::make_binary2<xor_op, T0, BaseT>::type
1696
operator^(T0 CREF _0, actor<BaseT> const& _1)
1698
return impl::make_binary2<xor_op, T0, BaseT>::construct(_0, _1);
1701
//////////////////////////////////
1702
template <typename BaseT0, typename BaseT1>
1703
inline typename impl::make_binary3<xor_op, BaseT0, BaseT1>::type
1704
operator^(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1706
return impl::make_binary3<xor_op, BaseT0, BaseT1>::construct(_0, _1);
1709
///////////////////////////////////////////////////////////////////////////////
1711
// shift left lazy operator (infix <<)
1713
///////////////////////////////////////////////////////////////////////////////
1716
template <typename T0, typename T1>
1719
typedef typename binary_operator<shift_l_op, T0, T1>
1723
template <typename T0, typename T1>
1724
typename binary_operator<shift_l_op, T0, T1>::result_type
1725
operator()(T0& _0, T1& _1) const
1726
{ return binary_operator<shift_l_op, T0, T1>::eval(_0, _1); }
1729
//////////////////////////////////
1730
template <typename BaseT, typename T1>
1731
inline typename impl::make_binary1<shift_l_op, BaseT, T1>::type
1732
operator<<(actor<BaseT> const& _0, T1 CREF _1)
1734
return impl::make_binary1<shift_l_op, BaseT, T1>::construct(_0, _1);
1737
//////////////////////////////////
1738
template <typename T0, typename BaseT>
1739
inline typename impl::make_binary2<shift_l_op, T0, BaseT>::type
1740
operator<<(T0 CREF _0, actor<BaseT> const& _1)
1742
return impl::make_binary2<shift_l_op, T0, BaseT>::construct(_0, _1);
1745
//////////////////////////////////
1746
template <typename BaseT0, typename BaseT1>
1747
inline typename impl::make_binary3<shift_l_op, BaseT0, BaseT1>::type
1748
operator<<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1750
return impl::make_binary3<shift_l_op, BaseT0, BaseT1>::construct(_0, _1);
1753
///////////////////////////////////////////////////////////////////////////////
1755
// shift right lazy operator (infix >>)
1757
///////////////////////////////////////////////////////////////////////////////
1760
template <typename T0, typename T1>
1763
typedef typename binary_operator<shift_r_op, T0, T1>
1767
template <typename T0, typename T1>
1768
typename binary_operator<shift_r_op, T0, T1>::result_type
1769
operator()(T0& _0, T1& _1) const
1770
{ return binary_operator<shift_r_op, T0, T1>::eval(_0, _1); }
1773
//////////////////////////////////
1774
template <typename BaseT, typename T1>
1775
inline typename impl::make_binary1<shift_r_op, BaseT, T1>::type
1776
operator>>(actor<BaseT> const& _0, T1 CREF _1)
1778
return impl::make_binary1<shift_r_op, BaseT, T1>::construct(_0, _1);
1781
//////////////////////////////////
1782
template <typename T0, typename BaseT>
1783
inline typename impl::make_binary2<shift_r_op, T0, BaseT>::type
1784
operator>>(T0 CREF _0, actor<BaseT> const& _1)
1786
return impl::make_binary2<shift_r_op, T0, BaseT>::construct(_0, _1);
1789
//////////////////////////////////
1790
template <typename BaseT0, typename BaseT1>
1791
inline typename impl::make_binary3<shift_r_op, BaseT0, BaseT1>::type
1792
operator>>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1794
return impl::make_binary3<shift_r_op, BaseT0, BaseT1>::construct(_0, _1);
1797
///////////////////////////////////////////////////////////////////////////////
1799
// equal lazy operator (infix ==)
1801
///////////////////////////////////////////////////////////////////////////////
1804
template <typename T0, typename T1>
1807
typedef typename binary_operator<eq_op, T0, T1>
1811
template <typename T0, typename T1>
1812
typename binary_operator<eq_op, T0, T1>::result_type
1813
operator()(T0& _0, T1& _1) const
1814
{ return binary_operator<eq_op, T0, T1>::eval(_0, _1); }
1817
//////////////////////////////////
1818
template <typename BaseT, typename T1>
1819
inline typename impl::make_binary1<eq_op, BaseT, T1>::type
1820
operator==(actor<BaseT> const& _0, T1 CREF _1)
1822
return impl::make_binary1<eq_op, BaseT, T1>::construct(_0, _1);
1825
//////////////////////////////////
1826
template <typename T0, typename BaseT>
1827
inline typename impl::make_binary2<eq_op, T0, BaseT>::type
1828
operator==(T0 CREF _0, actor<BaseT> const& _1)
1830
return impl::make_binary2<eq_op, T0, BaseT>::construct(_0, _1);
1833
//////////////////////////////////
1834
template <typename BaseT0, typename BaseT1>
1835
inline typename impl::make_binary3<eq_op, BaseT0, BaseT1>::type
1836
operator==(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1838
return impl::make_binary3<eq_op, BaseT0, BaseT1>::construct(_0, _1);
1841
///////////////////////////////////////////////////////////////////////////////
1843
// not equal lazy operator (infix !=)
1845
///////////////////////////////////////////////////////////////////////////////
1848
template <typename T0, typename T1>
1851
typedef typename binary_operator<not_eq_op, T0, T1>
1855
template <typename T0, typename T1>
1856
typename binary_operator<not_eq_op, T0, T1>::result_type
1857
operator()(T0& _0, T1& _1) const
1858
{ return binary_operator<not_eq_op, T0, T1>::eval(_0, _1); }
1861
//////////////////////////////////
1862
template <typename BaseT, typename T1>
1863
inline typename impl::make_binary1<not_eq_op, BaseT, T1>::type
1864
operator!=(actor<BaseT> const& _0, T1 CREF _1)
1866
return impl::make_binary1<not_eq_op, BaseT, T1>::construct(_0, _1);
1869
//////////////////////////////////
1870
template <typename T0, typename BaseT>
1871
inline typename impl::make_binary2<not_eq_op, T0, BaseT>::type
1872
operator!=(T0 CREF _0, actor<BaseT> const& _1)
1874
return impl::make_binary2<not_eq_op, T0, BaseT>::construct(_0, _1);
1877
//////////////////////////////////
1878
template <typename BaseT0, typename BaseT1>
1879
inline typename impl::make_binary3<not_eq_op, BaseT0, BaseT1>::type
1880
operator!=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1882
return impl::make_binary3<not_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1885
///////////////////////////////////////////////////////////////////////////////
1887
// less than lazy operator (infix <)
1889
///////////////////////////////////////////////////////////////////////////////
1892
template <typename T0, typename T1>
1895
typedef typename binary_operator<lt_op, T0, T1>
1899
template <typename T0, typename T1>
1900
typename binary_operator<lt_op, T0, T1>::result_type
1901
operator()(T0& _0, T1& _1) const
1902
{ return binary_operator<lt_op, T0, T1>::eval(_0, _1); }
1905
//////////////////////////////////
1906
template <typename BaseT, typename T1>
1907
inline typename impl::make_binary1<lt_op, BaseT, T1>::type
1908
operator<(actor<BaseT> const& _0, T1 CREF _1)
1910
return impl::make_binary1<lt_op, BaseT, T1>::construct(_0, _1);
1913
//////////////////////////////////
1914
template <typename T0, typename BaseT>
1915
inline typename impl::make_binary2<lt_op, T0, BaseT>::type
1916
operator<(T0 CREF _0, actor<BaseT> const& _1)
1918
return impl::make_binary2<lt_op, T0, BaseT>::construct(_0, _1);
1921
//////////////////////////////////
1922
template <typename BaseT0, typename BaseT1>
1923
inline typename impl::make_binary3<lt_op, BaseT0, BaseT1>::type
1924
operator<(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1926
return impl::make_binary3<lt_op, BaseT0, BaseT1>::construct(_0, _1);
1929
///////////////////////////////////////////////////////////////////////////////
1931
// less than equal lazy operator (infix <=)
1933
///////////////////////////////////////////////////////////////////////////////
1936
template <typename T0, typename T1>
1939
typedef typename binary_operator<lt_eq_op, T0, T1>
1943
template <typename T0, typename T1>
1944
typename binary_operator<lt_eq_op, T0, T1>::result_type
1945
operator()(T0& _0, T1& _1) const
1946
{ return binary_operator<lt_eq_op, T0, T1>::eval(_0, _1); }
1949
//////////////////////////////////
1950
template <typename BaseT, typename T1>
1951
inline typename impl::make_binary1<lt_eq_op, BaseT, T1>::type
1952
operator<=(actor<BaseT> const& _0, T1 CREF _1)
1954
return impl::make_binary1<lt_eq_op, BaseT, T1>::construct(_0, _1);
1957
//////////////////////////////////
1958
template <typename T0, typename BaseT>
1959
inline typename impl::make_binary2<lt_eq_op, T0, BaseT>::type
1960
operator<=(T0 CREF _0, actor<BaseT> const& _1)
1962
return impl::make_binary2<lt_eq_op, T0, BaseT>::construct(_0, _1);
1965
//////////////////////////////////
1966
template <typename BaseT0, typename BaseT1>
1967
inline typename impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::type
1968
operator<=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
1970
return impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
1973
///////////////////////////////////////////////////////////////////////////////
1975
// greater than lazy operator (infix >)
1977
///////////////////////////////////////////////////////////////////////////////
1980
template <typename T0, typename T1>
1983
typedef typename binary_operator<gt_op, T0, T1>
1987
template <typename T0, typename T1>
1988
typename binary_operator<gt_op, T0, T1>::result_type
1989
operator()(T0& _0, T1& _1) const
1990
{ return binary_operator<gt_op, T0, T1>::eval(_0, _1); }
1993
//////////////////////////////////
1994
template <typename BaseT, typename T1>
1995
inline typename impl::make_binary1<gt_op, BaseT, T1>::type
1996
operator>(actor<BaseT> const& _0, T1 CREF _1)
1998
return impl::make_binary1<gt_op, BaseT, T1>::construct(_0, _1);
2001
//////////////////////////////////
2002
template <typename T0, typename BaseT>
2003
inline typename impl::make_binary2<gt_op, T0, BaseT>::type
2004
operator>(T0 CREF _0, actor<BaseT> const& _1)
2006
return impl::make_binary2<gt_op, T0, BaseT>::construct(_0, _1);
2009
//////////////////////////////////
2010
template <typename BaseT0, typename BaseT1>
2011
inline typename impl::make_binary3<gt_op, BaseT0, BaseT1>::type
2012
operator>(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2014
return impl::make_binary3<gt_op, BaseT0, BaseT1>::construct(_0, _1);
2017
///////////////////////////////////////////////////////////////////////////////
2019
// greater than equal lazy operator (infix >=)
2021
///////////////////////////////////////////////////////////////////////////////
2024
template <typename T0, typename T1>
2027
typedef typename binary_operator<gt_eq_op, T0, T1>
2031
template <typename T0, typename T1>
2032
typename binary_operator<gt_eq_op, T0, T1>::result_type
2033
operator()(T0& _0, T1& _1) const
2034
{ return binary_operator<gt_eq_op, T0, T1>::eval(_0, _1); }
2037
//////////////////////////////////
2038
template <typename BaseT, typename T1>
2039
inline typename impl::make_binary1<gt_eq_op, BaseT, T1>::type
2040
operator>=(actor<BaseT> const& _0, T1 CREF _1)
2042
return impl::make_binary1<gt_eq_op, BaseT, T1>::construct(_0, _1);
2045
//////////////////////////////////
2046
template <typename T0, typename BaseT>
2047
inline typename impl::make_binary2<gt_eq_op, T0, BaseT>::type
2048
operator>=(T0 CREF _0, actor<BaseT> const& _1)
2050
return impl::make_binary2<gt_eq_op, T0, BaseT>::construct(_0, _1);
2053
//////////////////////////////////
2054
template <typename BaseT0, typename BaseT1>
2055
inline typename impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::type
2056
operator>=(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2058
return impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
2061
///////////////////////////////////////////////////////////////////////////////
2063
// logical and lazy operator (infix &&)
2065
// The logical_and_composite class and its corresponding generators are
2066
// provided to allow short-circuit evaluation of the operator's
2069
///////////////////////////////////////////////////////////////////////////////
2070
template <typename A0, typename A1>
2071
struct logical_and_composite {
2073
typedef logical_and_composite<A0, A1> self_t;
2075
template <typename TupleT>
2078
typedef typename binary_operator<logical_and_op,
2079
typename actor_result<A0, TupleT>::plain_type,
2080
typename actor_result<A1, TupleT>::plain_type
2081
>::result_type type;
2084
logical_and_composite(A0 const& _0, A1 const& _1)
2087
template <typename TupleT>
2088
typename actor_result<self_t, TupleT>::type
2089
eval(TupleT const& args) const
2091
return a0.eval(args) && a1.eval(args);
2094
A0 a0; A1 a1; // actors
2097
#if !(defined(__ICL) && __ICL <= 500)
2098
//////////////////////////////////
2099
template <typename BaseT, typename T1>
2100
inline actor<logical_and_composite
2101
<actor<BaseT>, typename as_actor<T1>::type> >
2102
operator&&(actor<BaseT> const& _0, T1 CREF _1)
2104
return logical_and_composite
2105
<actor<BaseT>, typename as_actor<T1>::type>
2106
(_0, as_actor<T1>::convert(_1));
2109
//////////////////////////////////
2110
template <typename T0, typename BaseT>
2111
inline actor<logical_and_composite
2112
<typename as_actor<T0>::type, actor<BaseT> > >
2113
operator&&(T0 CREF _0, actor<BaseT> const& _1)
2115
return logical_and_composite
2116
<typename as_actor<T0>::type, actor<BaseT> >
2117
(as_actor<T0>::convert(_0), _1);
2120
//////////////////////////////////
2121
template <typename BaseT0, typename BaseT1>
2122
inline actor<logical_and_composite
2123
<actor<BaseT0>, actor<BaseT1> > >
2124
operator&&(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2126
return logical_and_composite
2127
<actor<BaseT0>, actor<BaseT1> >
2131
//////////////////////////////////
2132
template <typename T0, typename T1>
2133
inline actor<logical_and_composite
2134
<typename as_actor<T0>::type, typename as_actor<T1>::type> >
2135
operator&&(T0 CREF _0, T1 CREF _1)
2137
return logical_and_composite
2138
<typename as_actor<T0>::type, typename as_actor<T1>::type>
2139
(as_actor<T0>::convert(_0), as_actor<T1>::convert(_1));
2141
#endif // !(__ICL && __ICL <= 500)
2143
///////////////////////////////////////////////////////////////////////////////
2145
// logical or lazy operator (infix ||)
2147
// The logical_or_composite class and its corresponding generators are
2148
// provided to allow short-circuit evaluation of the operator's
2151
///////////////////////////////////////////////////////////////////////////////
2152
template <typename A0, typename A1>
2153
struct logical_or_composite {
2155
typedef logical_or_composite<A0, A1> self_t;
2157
template <typename TupleT>
2160
typedef typename binary_operator<logical_or_op,
2161
typename actor_result<A0, TupleT>::plain_type,
2162
typename actor_result<A1, TupleT>::plain_type
2163
>::result_type type;
2166
logical_or_composite(A0 const& _0, A1 const& _1)
2169
template <typename TupleT>
2170
typename actor_result<self_t, TupleT>::type
2171
eval(TupleT const& args) const
2173
return a0.eval(args) || a1.eval(args);
2176
A0 a0; A1 a1; // actors
2179
//////////////////////////////////
2180
template <typename BaseT, typename T1>
2181
inline actor<logical_or_composite
2182
<actor<BaseT>, typename as_actor<T1>::type> >
2183
operator||(actor<BaseT> const& _0, T1 CREF _1)
2185
return logical_or_composite
2186
<actor<BaseT>, typename as_actor<T1>::type>
2187
(_0, as_actor<T1>::convert(_1));
2190
//////////////////////////////////
2191
template <typename T0, typename BaseT>
2192
inline actor<logical_or_composite
2193
<typename as_actor<T0>::type, actor<BaseT> > >
2194
operator||(T0 CREF _0, actor<BaseT> const& _1)
2196
return logical_or_composite
2197
<typename as_actor<T0>::type, actor<BaseT> >
2198
(as_actor<T0>::convert(_0), _1);
2201
//////////////////////////////////
2202
template <typename BaseT0, typename BaseT1>
2203
inline actor<logical_or_composite
2204
<actor<BaseT0>, actor<BaseT1> > >
2205
operator||(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
2207
return logical_or_composite
2208
<actor<BaseT0>, actor<BaseT1> >
2212
} // namespace phoenix