~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/spirit/phoenix/operators.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Phoenix V1.0
 
3
    Copyright (c) 2001-2002 Joel de Guzman
 
4
 
 
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
 
12
 
 
13
///////////////////////////////////////////////////////////////////////////////
 
14
#if !defined(BOOST_NO_CWCTYPE)
 
15
    #include <cwctype>
 
16
#endif
 
17
 
 
18
#if defined(__BORLANDC__) || (defined(__ICL) && __ICL >= 700)
 
19
#define CREF const&
 
20
#else
 
21
#define CREF
 
22
#endif
 
23
 
 
24
#include "boost/spirit/phoenix/actor.hpp"
 
25
#include "boost/spirit/phoenix/composite.hpp"
 
26
#include "boost/config.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 bool 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<long long>          { static int const value = 110; };
 
378
template <> struct rank<unsigned long long> { 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
 
 
404
    enum {
 
405
 
 
406
        rank1 = rank<T0>::value,
 
407
        rank2 = rank<T1>::value,
 
408
 
 
409
#if defined __BORLANDC__ && __BORLANDC__ >= 0x561
 
410
        siz = (rank<T0>::value < rank<T1>::value) ? 1 : 2
 
411
#else
 
412
        siz = (rank1 < rank2) ? 1 : 2
 
413
#endif
 
414
    };
 
415
 
 
416
    typedef char compare_rank[siz];
 
417
    typedef typename impl::if_t<compare_rank, T1, T0>::type type;
 
418
};
 
419
 
 
420
///////////////////////////////////////////////////////////////////////////////
 
421
//
 
422
//  binary_operator<TagT, T0, T1>
 
423
//
 
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.
 
428
//
 
429
//      TagT is one of the binary operator tags above T0 and T1 are the
 
430
//      (arguments') data types involved in the operation.
 
431
//
 
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.
 
437
//
 
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.
 
442
//
 
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.
 
447
//
 
448
///////////////////////////////////////////////////////////////////////////////
 
449
template <typename TagT, typename T0, typename T1>
 
450
struct binary_operator;
 
451
 
 
452
//////////////////////////////////
 
453
template <typename T0, typename T1>
 
454
struct binary_operator<assign_op, T0, T1> {
 
455
 
 
456
    typedef T0& result_type;
 
457
    static result_type eval(T0& lhs, T1 const& rhs)
 
458
    { return lhs = rhs; }
 
459
};
 
460
 
 
461
//////////////////////////////////
 
462
template <typename T1>
 
463
struct binary_operator<index_op, nil_t, T1> {
 
464
 
 
465
    //  G++ eager template instantiation
 
466
    //  somehow requires this.
 
467
    typedef nil_t result_type;
 
468
};
 
469
 
 
470
//////////////////////////////////
 
471
template <typename T0, typename T1>
 
472
struct binary_operator<index_op, T0*, T1> {
 
473
 
 
474
    typedef T0& result_type;
 
475
    static result_type eval(T0* ptr, T1 const& index)
 
476
    { return ptr[index]; }
 
477
};
 
478
 
 
479
//////////////////////////////////
 
480
template <typename T0, typename T1>
 
481
struct binary_operator<index_op, T0* const, T1> {
 
482
 
 
483
    typedef T0& result_type;
 
484
    static result_type eval(T0* const ptr, T1 const& index)
 
485
    { return ptr[index]; }
 
486
};
 
487
 
 
488
//////////////////////////////////
 
489
template <typename T0, int N, typename T1>
 
490
struct binary_operator<index_op, T0[N], T1> {
 
491
 
 
492
    typedef T0& result_type;
 
493
    static result_type eval(T0* ptr, T1 const& index)
 
494
    { return ptr[index]; }
 
495
};
 
496
 
 
497
//////////////////////////////////
 
498
template <typename T0, typename T1>
 
499
struct binary_operator<plus_assign_op, T0, T1> {
 
500
 
 
501
    typedef T0& result_type;
 
502
    static result_type eval(T0& lhs, T1 const& rhs)
 
503
    { return lhs += rhs; }
 
504
};
 
505
 
 
506
//////////////////////////////////
 
507
template <typename T0, typename T1>
 
508
struct binary_operator<minus_assign_op, T0, T1> {
 
509
 
 
510
    typedef T0& result_type;
 
511
    static result_type eval(T0& lhs, T1 const& rhs)
 
512
    { return lhs -= rhs; }
 
513
};
 
514
 
 
515
//////////////////////////////////
 
516
template <typename T0, typename T1>
 
517
struct binary_operator<times_assign_op, T0, T1> {
 
518
 
 
519
    typedef T0& result_type;
 
520
    static result_type eval(T0& lhs, T1 const& rhs)
 
521
    { return lhs *= rhs; }
 
522
};
 
523
 
 
524
//////////////////////////////////
 
525
template <typename T0, typename T1>
 
526
struct binary_operator<divide_assign_op, T0, T1> {
 
527
 
 
528
    typedef T0& result_type;
 
529
    static result_type eval(T0& lhs, T1 const& rhs)
 
530
    { return lhs /= rhs; }
 
531
};
 
532
 
 
533
//////////////////////////////////
 
534
template <typename T0, typename T1>
 
535
struct binary_operator<mod_assign_op, T0, T1> {
 
536
 
 
537
    typedef T0& result_type;
 
538
    static result_type eval(T0& lhs, T1 const& rhs)
 
539
    { return lhs %= rhs; }
 
540
};
 
541
 
 
542
//////////////////////////////////
 
543
template <typename T0, typename T1>
 
544
struct binary_operator<and_assign_op, T0, T1> {
 
545
 
 
546
    typedef T0& result_type;
 
547
    static result_type eval(T0& lhs, T1 const& rhs)
 
548
    { return lhs &= rhs; }
 
549
};
 
550
 
 
551
//////////////////////////////////
 
552
template <typename T0, typename T1>
 
553
struct binary_operator<or_assign_op, T0, T1> {
 
554
 
 
555
    typedef T0& result_type;
 
556
    static result_type eval(T0& lhs, T1 const& rhs)
 
557
    { return lhs |= rhs; }
 
558
};
 
559
 
 
560
//////////////////////////////////
 
561
template <typename T0, typename T1>
 
562
struct binary_operator<xor_assign_op, T0, T1> {
 
563
 
 
564
    typedef T0& result_type;
 
565
    static result_type eval(T0& lhs, T1 const& rhs)
 
566
    { return lhs ^= rhs; }
 
567
};
 
568
 
 
569
//////////////////////////////////
 
570
template <typename T0, typename T1>
 
571
struct binary_operator<shift_l_assign_op, T0, T1> {
 
572
 
 
573
    typedef T0& result_type;
 
574
    static result_type eval(T0& lhs, T1 const& rhs)
 
575
    { return lhs <<= rhs; }
 
576
};
 
577
 
 
578
//////////////////////////////////
 
579
template <typename T0, typename T1>
 
580
struct binary_operator<shift_r_assign_op, T0, T1> {
 
581
 
 
582
    typedef T0& result_type;
 
583
    static result_type eval(T0& lhs, T1 const& rhs)
 
584
    { return lhs >>= rhs; }
 
585
};
 
586
 
 
587
//////////////////////////////////
 
588
template <typename T0, typename T1>
 
589
struct binary_operator<plus_op, T0, T1> {
 
590
 
 
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; }
 
594
};
 
595
 
 
596
//////////////////////////////////
 
597
template <typename T0, typename T1>
 
598
struct binary_operator<minus_op, T0, T1> {
 
599
 
 
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; }
 
603
};
 
604
 
 
605
//////////////////////////////////
 
606
template <typename T0, typename T1>
 
607
struct binary_operator<times_op, T0, T1> {
 
608
 
 
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; }
 
612
};
 
613
 
 
614
//////////////////////////////////
 
615
template <typename T0, typename T1>
 
616
struct binary_operator<divide_op, T0, T1> {
 
617
 
 
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; }
 
621
};
 
622
 
 
623
//////////////////////////////////
 
624
template <typename T0, typename T1>
 
625
struct binary_operator<mod_op, T0, T1> {
 
626
 
 
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; }
 
630
};
 
631
 
 
632
//////////////////////////////////
 
633
template <typename T0, typename T1>
 
634
struct binary_operator<and_op, T0, T1> {
 
635
 
 
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; }
 
639
};
 
640
 
 
641
//////////////////////////////////
 
642
template <typename T0, typename T1>
 
643
struct binary_operator<or_op, T0, T1> {
 
644
 
 
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; }
 
648
};
 
649
 
 
650
//////////////////////////////////
 
651
template <typename T0, typename T1>
 
652
struct binary_operator<xor_op, T0, T1> {
 
653
 
 
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; }
 
657
};
 
658
 
 
659
//////////////////////////////////
 
660
template <typename T0, typename T1>
 
661
struct binary_operator<shift_l_op, T0, T1> {
 
662
 
 
663
    typedef T0 const result_type;
 
664
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
665
    { return lhs << rhs; }
 
666
};
 
667
 
 
668
//////////////////////////////////
 
669
template <typename T0, typename T1>
 
670
struct binary_operator<shift_r_op, T0, T1> {
 
671
 
 
672
    typedef T0 const result_type;
 
673
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
674
    { return lhs >> rhs; }
 
675
};
 
676
 
 
677
//////////////////////////////////
 
678
template <typename T0, typename T1>
 
679
struct binary_operator<eq_op, T0, T1> {
 
680
 
 
681
    typedef bool result_type;
 
682
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
683
    { return lhs == rhs; }
 
684
};
 
685
 
 
686
//////////////////////////////////
 
687
template <typename T0, typename T1>
 
688
struct binary_operator<not_eq_op, T0, T1> {
 
689
 
 
690
    typedef bool result_type;
 
691
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
692
    { return lhs != rhs; }
 
693
};
 
694
 
 
695
//////////////////////////////////
 
696
template <typename T0, typename T1>
 
697
struct binary_operator<lt_op, T0, T1> {
 
698
 
 
699
    typedef bool result_type;
 
700
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
701
    { return lhs < rhs; }
 
702
};
 
703
 
 
704
//////////////////////////////////
 
705
template <typename T0, typename T1>
 
706
struct binary_operator<lt_eq_op, T0, T1> {
 
707
 
 
708
    typedef bool result_type;
 
709
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
710
    { return lhs <= rhs; }
 
711
};
 
712
 
 
713
//////////////////////////////////
 
714
template <typename T0, typename T1>
 
715
struct binary_operator<gt_op, T0, T1> {
 
716
 
 
717
    typedef bool result_type;
 
718
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
719
    { return lhs > rhs; }
 
720
};
 
721
 
 
722
//////////////////////////////////
 
723
template <typename T0, typename T1>
 
724
struct binary_operator<gt_eq_op, T0, T1> {
 
725
 
 
726
    typedef bool result_type;
 
727
    static result_type eval(T0 const& lhs, T1 const& rhs)
 
728
    { return lhs >= rhs; }
 
729
};
 
730
 
 
731
//////////////////////////////////
 
732
template <typename T0, typename T1>
 
733
struct binary_operator<logical_and_op, T0, T1> {
 
734
 
 
735
    typedef bool result_type;
 
736
    //  no eval function, see comment above.
 
737
};
 
738
 
 
739
//////////////////////////////////
 
740
template <typename T0, typename T1>
 
741
struct binary_operator<logical_or_op, T0, T1> {
 
742
 
 
743
    typedef bool result_type;
 
744
    //  no eval function, see comment above.
 
745
};
 
746
 
 
747
///////////////////////////////////////////////////////////////////////////////
 
748
//
 
749
//  negative lazy operator (prefix -)
 
750
//
 
751
///////////////////////////////////////////////////////////////////////////////
 
752
struct negative_op {
 
753
 
 
754
    template <typename T0>
 
755
    struct result {
 
756
 
 
757
        typedef typename unary_operator<negative_op, T0>::result_type type;
 
758
    };
 
759
 
 
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); }
 
764
};
 
765
 
 
766
//////////////////////////////////
 
767
template <typename BaseT>
 
768
inline typename impl::make_unary<negative_op, BaseT>::type
 
769
operator-(actor<BaseT> const& _0)
 
770
{
 
771
    return impl::make_unary<negative_op, BaseT>::construct(_0);
 
772
}
 
773
 
 
774
///////////////////////////////////////////////////////////////////////////////
 
775
//
 
776
//  positive lazy operator (prefix +)
 
777
//
 
778
///////////////////////////////////////////////////////////////////////////////
 
779
struct positive_op {
 
780
 
 
781
    template <typename T0>
 
782
    struct result {
 
783
 
 
784
        typedef typename unary_operator<positive_op, T0>::result_type type;
 
785
    };
 
786
 
 
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); }
 
791
};
 
792
 
 
793
//////////////////////////////////
 
794
template <typename BaseT>
 
795
inline typename impl::make_unary<positive_op, BaseT>::type
 
796
operator+(actor<BaseT> const& _0)
 
797
{
 
798
    return impl::make_unary<positive_op, BaseT>::construct(_0);
 
799
}
 
800
 
 
801
///////////////////////////////////////////////////////////////////////////////
 
802
//
 
803
//  logical not lazy operator (prefix !)
 
804
//
 
805
///////////////////////////////////////////////////////////////////////////////
 
806
struct logical_not_op {
 
807
 
 
808
    template <typename T0>
 
809
    struct result {
 
810
 
 
811
        typedef typename unary_operator<logical_not_op, T0>::result_type type;
 
812
    };
 
813
 
 
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); }
 
818
};
 
819
 
 
820
//////////////////////////////////
 
821
template <typename BaseT>
 
822
inline typename impl::make_unary<logical_not_op, BaseT>::type
 
823
operator!(actor<BaseT> const& _0)
 
824
{
 
825
    return impl::make_unary<logical_not_op, BaseT>::construct(_0);
 
826
}
 
827
 
 
828
///////////////////////////////////////////////////////////////////////////////
 
829
//
 
830
//  invert lazy operator (prefix ~)
 
831
//
 
832
///////////////////////////////////////////////////////////////////////////////
 
833
struct invert_op {
 
834
 
 
835
    template <typename T0>
 
836
    struct result {
 
837
 
 
838
        typedef typename unary_operator<invert_op, T0>::result_type type;
 
839
    };
 
840
 
 
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); }
 
845
};
 
846
 
 
847
//////////////////////////////////
 
848
template <typename BaseT>
 
849
inline typename impl::make_unary<invert_op, BaseT>::type
 
850
operator~(actor<BaseT> const& _0)
 
851
{
 
852
    return impl::make_unary<invert_op, BaseT>::construct(_0);
 
853
}
 
854
 
 
855
///////////////////////////////////////////////////////////////////////////////
 
856
//
 
857
//  reference lazy operator (prefix &)
 
858
//
 
859
///////////////////////////////////////////////////////////////////////////////
 
860
struct reference_op {
 
861
 
 
862
    template <typename T0>
 
863
    struct result {
 
864
 
 
865
        typedef typename unary_operator<reference_op, T0>::result_type type;
 
866
    };
 
867
 
 
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); }
 
872
};
 
873
 
 
874
//////////////////////////////////
 
875
template <typename BaseT>
 
876
inline typename impl::make_unary<reference_op, BaseT>::type
 
877
operator&(actor<BaseT> const& _0)
 
878
{
 
879
    return impl::make_unary<reference_op, BaseT>::construct(_0);
 
880
}
 
881
 
 
882
///////////////////////////////////////////////////////////////////////////////
 
883
//
 
884
//  dereference lazy operator (prefix *)
 
885
//
 
886
///////////////////////////////////////////////////////////////////////////////
 
887
struct dereference_op {
 
888
 
 
889
    template <typename T0>
 
890
    struct result {
 
891
 
 
892
        typedef typename unary_operator<dereference_op, T0>::result_type type;
 
893
    };
 
894
 
 
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); }
 
899
};
 
900
 
 
901
//////////////////////////////////
 
902
template <typename BaseT>
 
903
inline typename impl::make_unary<dereference_op, BaseT>::type
 
904
operator*(actor<BaseT> const& _0)
 
905
{
 
906
    return impl::make_unary<dereference_op, BaseT>::construct(_0);
 
907
}
 
908
 
 
909
///////////////////////////////////////////////////////////////////////////////
 
910
//
 
911
//  pre increment lazy operator (prefix ++)
 
912
//
 
913
///////////////////////////////////////////////////////////////////////////////
 
914
struct pre_incr_op {
 
915
 
 
916
    template <typename T0>
 
917
    struct result {
 
918
 
 
919
        typedef typename unary_operator<pre_incr_op, T0>::result_type type;
 
920
    };
 
921
 
 
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); }
 
926
};
 
927
 
 
928
//////////////////////////////////
 
929
template <typename BaseT>
 
930
inline typename impl::make_unary<pre_incr_op, BaseT>::type
 
931
operator++(actor<BaseT> const& _0)
 
932
{
 
933
    return impl::make_unary<pre_incr_op, BaseT>::construct(_0);
 
934
}
 
935
 
 
936
///////////////////////////////////////////////////////////////////////////////
 
937
//
 
938
//  pre decrement lazy operator (prefix --)
 
939
//
 
940
///////////////////////////////////////////////////////////////////////////////
 
941
struct pre_decr_op {
 
942
 
 
943
    template <typename T0>
 
944
    struct result {
 
945
 
 
946
        typedef typename unary_operator<pre_decr_op, T0>::result_type type;
 
947
    };
 
948
 
 
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); }
 
953
};
 
954
 
 
955
//////////////////////////////////
 
956
template <typename BaseT>
 
957
inline typename impl::make_unary<pre_decr_op, BaseT>::type
 
958
operator--(actor<BaseT> const& _0)
 
959
{
 
960
    return impl::make_unary<pre_decr_op, BaseT>::construct(_0);
 
961
}
 
962
 
 
963
///////////////////////////////////////////////////////////////////////////////
 
964
//
 
965
//  post increment lazy operator (postfix ++)
 
966
//
 
967
///////////////////////////////////////////////////////////////////////////////
 
968
struct post_incr_op {
 
969
 
 
970
    template <typename T0>
 
971
    struct result {
 
972
 
 
973
        typedef typename unary_operator<post_incr_op, T0>::result_type type;
 
974
    };
 
975
 
 
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); }
 
980
};
 
981
 
 
982
//////////////////////////////////
 
983
template <typename BaseT>
 
984
inline typename impl::make_unary<post_incr_op, BaseT>::type
 
985
operator++(actor<BaseT> const& _0, int)
 
986
{
 
987
    return impl::make_unary<post_incr_op, BaseT>::construct(_0);
 
988
}
 
989
 
 
990
///////////////////////////////////////////////////////////////////////////////
 
991
//
 
992
//  post decrement lazy operator (postfix --)
 
993
//
 
994
///////////////////////////////////////////////////////////////////////////////
 
995
struct post_decr_op {
 
996
 
 
997
    template <typename T0>
 
998
    struct result {
 
999
 
 
1000
        typedef typename unary_operator<post_decr_op, T0>::result_type type;
 
1001
    };
 
1002
 
 
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); }
 
1007
};
 
1008
 
 
1009
//////////////////////////////////
 
1010
template <typename BaseT>
 
1011
inline typename impl::make_unary<post_decr_op, BaseT>::type
 
1012
operator--(actor<BaseT> const& _0, int)
 
1013
{
 
1014
    return impl::make_unary<post_decr_op, BaseT>::construct(_0);
 
1015
}
 
1016
 
 
1017
///////////////////////////////////////////////////////////////////////////////
 
1018
//
 
1019
//  assignment lazy operator (infix =)
 
1020
//  The acual lazy operator is a member of the actor class.
 
1021
//
 
1022
///////////////////////////////////////////////////////////////////////////////
 
1023
struct assign_op {
 
1024
 
 
1025
    template <typename T0, typename T1>
 
1026
    struct result {
 
1027
 
 
1028
        typedef typename binary_operator<assign_op, T0, T1>
 
1029
            ::result_type type;
 
1030
    };
 
1031
 
 
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); }
 
1036
};
 
1037
 
 
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
 
1043
{
 
1044
    return impl::make_binary1<assign_op, BaseT, B>::construct(*this, _1);
 
1045
}
 
1046
 
 
1047
///////////////////////////////////////////////////////////////////////////////
 
1048
//
 
1049
//  index lazy operator (array index [])
 
1050
//  The acual lazy operator is a member of the actor class.
 
1051
//
 
1052
///////////////////////////////////////////////////////////////////////////////
 
1053
struct index_op {
 
1054
 
 
1055
    template <typename T0, typename T1>
 
1056
    struct result {
 
1057
 
 
1058
        typedef typename binary_operator<index_op, T0, T1>
 
1059
            ::result_type type;
 
1060
    };
 
1061
 
 
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); }
 
1066
};
 
1067
 
 
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
 
1073
{
 
1074
    return impl::make_binary1<index_op, BaseT, B>::construct(*this, _1);
 
1075
}
 
1076
 
 
1077
///////////////////////////////////////////////////////////////////////////////
 
1078
//
 
1079
//  plus assign lazy operator (infix +=)
 
1080
//
 
1081
///////////////////////////////////////////////////////////////////////////////
 
1082
struct plus_assign_op {
 
1083
 
 
1084
    template <typename T0, typename T1>
 
1085
    struct result {
 
1086
 
 
1087
        typedef typename binary_operator<plus_assign_op, T0, T1>
 
1088
            ::result_type type;
 
1089
    };
 
1090
 
 
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); }
 
1095
};
 
1096
 
 
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)
 
1101
{
 
1102
    return impl::make_binary1<plus_assign_op, BaseT, T1>::construct(_0, _1);
 
1103
}
 
1104
 
 
1105
///////////////////////////////////////////////////////////////////////////////
 
1106
//
 
1107
//  minus assign lazy operator (infix -=)
 
1108
//
 
1109
///////////////////////////////////////////////////////////////////////////////
 
1110
struct minus_assign_op {
 
1111
 
 
1112
    template <typename T0, typename T1>
 
1113
    struct result {
 
1114
 
 
1115
        typedef typename binary_operator<minus_assign_op, T0, T1>
 
1116
            ::result_type type;
 
1117
    };
 
1118
 
 
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); }
 
1123
};
 
1124
 
 
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)
 
1129
{
 
1130
    return impl::make_binary1<minus_assign_op, BaseT, T1>::construct(_0, _1);
 
1131
}
 
1132
 
 
1133
///////////////////////////////////////////////////////////////////////////////
 
1134
//
 
1135
//  times assign lazy operator (infix *=)
 
1136
//
 
1137
///////////////////////////////////////////////////////////////////////////////
 
1138
struct times_assign_op {
 
1139
 
 
1140
    template <typename T0, typename T1>
 
1141
    struct result {
 
1142
 
 
1143
        typedef typename binary_operator<times_assign_op, T0, T1>
 
1144
            ::result_type type;
 
1145
    };
 
1146
 
 
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); }
 
1151
};
 
1152
 
 
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)
 
1157
{
 
1158
    return impl::make_binary1<times_assign_op, BaseT, T1>::construct(_0, _1);
 
1159
}
 
1160
 
 
1161
///////////////////////////////////////////////////////////////////////////////
 
1162
//
 
1163
//  divide assign lazy operator (infix /=)
 
1164
//
 
1165
///////////////////////////////////////////////////////////////////////////////
 
1166
struct divide_assign_op {
 
1167
 
 
1168
    template <typename T0, typename T1>
 
1169
    struct result {
 
1170
 
 
1171
        typedef typename binary_operator<divide_assign_op, T0, T1>
 
1172
            ::result_type type;
 
1173
    };
 
1174
 
 
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); }
 
1179
};
 
1180
 
 
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)
 
1185
{
 
1186
    return impl::make_binary1<divide_assign_op, BaseT, T1>::construct(_0, _1);
 
1187
}
 
1188
 
 
1189
///////////////////////////////////////////////////////////////////////////////
 
1190
//
 
1191
//  mod assign lazy operator (infix %=)
 
1192
//
 
1193
///////////////////////////////////////////////////////////////////////////////
 
1194
struct mod_assign_op {
 
1195
 
 
1196
    template <typename T0, typename T1>
 
1197
    struct result {
 
1198
 
 
1199
        typedef typename binary_operator<mod_assign_op, T0, T1>
 
1200
            ::result_type type;
 
1201
    };
 
1202
 
 
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); }
 
1207
};
 
1208
 
 
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)
 
1213
{
 
1214
    return impl::make_binary1<mod_assign_op, BaseT, T1>::construct(_0, _1);
 
1215
}
 
1216
 
 
1217
///////////////////////////////////////////////////////////////////////////////
 
1218
//
 
1219
//  and assign lazy operator (infix &=)
 
1220
//
 
1221
///////////////////////////////////////////////////////////////////////////////
 
1222
struct and_assign_op {
 
1223
 
 
1224
    template <typename T0, typename T1>
 
1225
    struct result {
 
1226
 
 
1227
        typedef typename binary_operator<and_assign_op, T0, T1>
 
1228
            ::result_type type;
 
1229
    };
 
1230
 
 
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); }
 
1235
};
 
1236
 
 
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)
 
1241
{
 
1242
    return impl::make_binary1<and_assign_op, BaseT, T1>::construct(_0, _1);
 
1243
}
 
1244
 
 
1245
///////////////////////////////////////////////////////////////////////////////
 
1246
//
 
1247
//  or assign lazy operator (infix |=)
 
1248
//
 
1249
///////////////////////////////////////////////////////////////////////////////
 
1250
struct or_assign_op {
 
1251
 
 
1252
    template <typename T0, typename T1>
 
1253
    struct result {
 
1254
 
 
1255
        typedef typename binary_operator<or_assign_op, T0, T1>
 
1256
            ::result_type type;
 
1257
    };
 
1258
 
 
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); }
 
1263
};
 
1264
 
 
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)
 
1269
{
 
1270
    return impl::make_binary1<or_assign_op, BaseT, T1>::construct(_0, _1);
 
1271
}
 
1272
 
 
1273
///////////////////////////////////////////////////////////////////////////////
 
1274
//
 
1275
//  xor assign lazy operator (infix ^=)
 
1276
//
 
1277
///////////////////////////////////////////////////////////////////////////////
 
1278
struct xor_assign_op {
 
1279
 
 
1280
    template <typename T0, typename T1>
 
1281
    struct result {
 
1282
 
 
1283
        typedef typename binary_operator<xor_assign_op, T0, T1>
 
1284
            ::result_type type;
 
1285
    };
 
1286
 
 
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); }
 
1291
};
 
1292
 
 
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)
 
1297
{
 
1298
    return impl::make_binary1<xor_assign_op, BaseT, T1>::construct(_0, _1);
 
1299
}
 
1300
 
 
1301
///////////////////////////////////////////////////////////////////////////////
 
1302
//
 
1303
//  shift left assign lazy operator (infix <<=)
 
1304
//
 
1305
///////////////////////////////////////////////////////////////////////////////
 
1306
struct shift_l_assign_op {
 
1307
 
 
1308
    template <typename T0, typename T1>
 
1309
    struct result {
 
1310
 
 
1311
        typedef typename binary_operator<shift_l_assign_op, T0, T1>
 
1312
            ::result_type type;
 
1313
    };
 
1314
 
 
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); }
 
1319
};
 
1320
 
 
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)
 
1325
{
 
1326
    return impl::make_binary1<shift_l_assign_op, BaseT, T1>::construct(_0, _1);
 
1327
}
 
1328
 
 
1329
///////////////////////////////////////////////////////////////////////////////
 
1330
//
 
1331
//  shift right assign lazy operator (infix >>=)
 
1332
//
 
1333
///////////////////////////////////////////////////////////////////////////////
 
1334
struct shift_r_assign_op {
 
1335
 
 
1336
    template <typename T0, typename T1>
 
1337
    struct result {
 
1338
 
 
1339
        typedef typename binary_operator<shift_r_assign_op, T0, T1>
 
1340
            ::result_type type;
 
1341
    };
 
1342
 
 
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); }
 
1347
};
 
1348
 
 
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)
 
1353
{
 
1354
    return impl::make_binary1<shift_r_assign_op, BaseT, T1>::construct(_0, _1);
 
1355
}
 
1356
 
 
1357
///////////////////////////////////////////////////////////////////////////////
 
1358
//
 
1359
//  plus lazy operator (infix +)
 
1360
//
 
1361
///////////////////////////////////////////////////////////////////////////////
 
1362
struct plus_op {
 
1363
 
 
1364
    template <typename T0, typename T1>
 
1365
    struct result {
 
1366
 
 
1367
        typedef typename binary_operator<plus_op, T0, T1>
 
1368
            ::result_type type;
 
1369
    };
 
1370
 
 
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); }
 
1375
};
 
1376
 
 
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)
 
1381
{
 
1382
    return impl::make_binary1<plus_op, BaseT, T1>::construct(_0, _1);
 
1383
}
 
1384
 
 
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)
 
1389
{
 
1390
    return impl::make_binary2<plus_op, T0, BaseT>::construct(_0, _1);
 
1391
}
 
1392
 
 
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)
 
1397
{
 
1398
    return impl::make_binary3<plus_op, BaseT0, BaseT1>::construct(_0, _1);
 
1399
}
 
1400
 
 
1401
///////////////////////////////////////////////////////////////////////////////
 
1402
//
 
1403
//  minus lazy operator (infix -)
 
1404
//
 
1405
///////////////////////////////////////////////////////////////////////////////
 
1406
struct minus_op {
 
1407
 
 
1408
    template <typename T0, typename T1>
 
1409
    struct result {
 
1410
 
 
1411
        typedef typename binary_operator<minus_op, T0, T1>
 
1412
            ::result_type type;
 
1413
    };
 
1414
 
 
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); }
 
1419
};
 
1420
 
 
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)
 
1425
{
 
1426
    return impl::make_binary1<minus_op, BaseT, T1>::construct(_0, _1);
 
1427
}
 
1428
 
 
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)
 
1433
{
 
1434
    return impl::make_binary2<minus_op, T0, BaseT>::construct(_0, _1);
 
1435
}
 
1436
 
 
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)
 
1441
{
 
1442
    return impl::make_binary3<minus_op, BaseT0, BaseT1>::construct(_0, _1);
 
1443
}
 
1444
 
 
1445
///////////////////////////////////////////////////////////////////////////////
 
1446
//
 
1447
//  times lazy operator (infix *)
 
1448
//
 
1449
///////////////////////////////////////////////////////////////////////////////
 
1450
struct times_op {
 
1451
 
 
1452
    template <typename T0, typename T1>
 
1453
    struct result {
 
1454
 
 
1455
        typedef typename binary_operator<times_op, T0, T1>
 
1456
            ::result_type type;
 
1457
    };
 
1458
 
 
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); }
 
1463
};
 
1464
 
 
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)
 
1469
{
 
1470
    return impl::make_binary1<times_op, BaseT, T1>::construct(_0, _1);
 
1471
}
 
1472
 
 
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)
 
1477
{
 
1478
    return impl::make_binary2<times_op, T0, BaseT>::construct(_0, _1);
 
1479
}
 
1480
 
 
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)
 
1485
{
 
1486
    return impl::make_binary3<times_op, BaseT0, BaseT1>::construct(_0, _1);
 
1487
}
 
1488
 
 
1489
///////////////////////////////////////////////////////////////////////////////
 
1490
//
 
1491
//  divide lazy operator (infix /)
 
1492
//
 
1493
///////////////////////////////////////////////////////////////////////////////
 
1494
struct divide_op {
 
1495
 
 
1496
    template <typename T0, typename T1>
 
1497
    struct result {
 
1498
 
 
1499
        typedef typename binary_operator<divide_op, T0, T1>
 
1500
            ::result_type type;
 
1501
    };
 
1502
 
 
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); }
 
1507
};
 
1508
 
 
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)
 
1513
{
 
1514
    return impl::make_binary1<divide_op, BaseT, T1>::construct(_0, _1);
 
1515
}
 
1516
 
 
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)
 
1521
{
 
1522
    return impl::make_binary2<divide_op, T0, BaseT>::construct(_0, _1);
 
1523
}
 
1524
 
 
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)
 
1529
{
 
1530
    return impl::make_binary3<divide_op, BaseT0, BaseT1>::construct(_0, _1);
 
1531
}
 
1532
 
 
1533
///////////////////////////////////////////////////////////////////////////////
 
1534
//
 
1535
//  mod lazy operator (infix %)
 
1536
//
 
1537
///////////////////////////////////////////////////////////////////////////////
 
1538
struct mod_op {
 
1539
 
 
1540
    template <typename T0, typename T1>
 
1541
    struct result {
 
1542
 
 
1543
        typedef typename binary_operator<mod_op, T0, T1>
 
1544
            ::result_type type;
 
1545
    };
 
1546
 
 
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); }
 
1551
};
 
1552
 
 
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)
 
1557
{
 
1558
    return impl::make_binary1<mod_op, BaseT, T1>::construct(_0, _1);
 
1559
}
 
1560
 
 
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)
 
1565
{
 
1566
    return impl::make_binary2<mod_op, T0, BaseT>::construct(_0, _1);
 
1567
}
 
1568
 
 
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)
 
1573
{
 
1574
    return impl::make_binary3<mod_op, BaseT0, BaseT1>::construct(_0, _1);
 
1575
}
 
1576
 
 
1577
///////////////////////////////////////////////////////////////////////////////
 
1578
//
 
1579
//  and lazy operator (infix &)
 
1580
//
 
1581
///////////////////////////////////////////////////////////////////////////////
 
1582
struct and_op {
 
1583
 
 
1584
    template <typename T0, typename T1>
 
1585
    struct result {
 
1586
 
 
1587
        typedef typename binary_operator<and_op, T0, T1>
 
1588
            ::result_type type;
 
1589
    };
 
1590
 
 
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); }
 
1595
};
 
1596
 
 
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)
 
1601
{
 
1602
    return impl::make_binary1<and_op, BaseT, T1>::construct(_0, _1);
 
1603
}
 
1604
 
 
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)
 
1609
{
 
1610
    return impl::make_binary2<and_op, T0, BaseT>::construct(_0, _1);
 
1611
}
 
1612
 
 
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)
 
1617
{
 
1618
    return impl::make_binary3<and_op, BaseT0, BaseT1>::construct(_0, _1);
 
1619
}
 
1620
 
 
1621
///////////////////////////////////////////////////////////////////////////////
 
1622
//
 
1623
//  or lazy operator (infix |)
 
1624
//
 
1625
///////////////////////////////////////////////////////////////////////////////
 
1626
struct or_op {
 
1627
 
 
1628
    template <typename T0, typename T1>
 
1629
    struct result {
 
1630
 
 
1631
        typedef typename binary_operator<or_op, T0, T1>
 
1632
            ::result_type type;
 
1633
    };
 
1634
 
 
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); }
 
1639
};
 
1640
 
 
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)
 
1645
{
 
1646
    return impl::make_binary1<or_op, BaseT, T1>::construct(_0, _1);
 
1647
}
 
1648
 
 
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)
 
1653
{
 
1654
    return impl::make_binary2<or_op, T0, BaseT>::construct(_0, _1);
 
1655
}
 
1656
 
 
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)
 
1661
{
 
1662
    return impl::make_binary3<or_op, BaseT0, BaseT1>::construct(_0, _1);
 
1663
}
 
1664
 
 
1665
///////////////////////////////////////////////////////////////////////////////
 
1666
//
 
1667
//  xor lazy operator (infix ^)
 
1668
//
 
1669
///////////////////////////////////////////////////////////////////////////////
 
1670
struct xor_op {
 
1671
 
 
1672
    template <typename T0, typename T1>
 
1673
    struct result {
 
1674
 
 
1675
        typedef typename binary_operator<xor_op, T0, T1>
 
1676
            ::result_type type;
 
1677
    };
 
1678
 
 
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); }
 
1683
};
 
1684
 
 
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)
 
1689
{
 
1690
    return impl::make_binary1<xor_op, BaseT, T1>::construct(_0, _1);
 
1691
}
 
1692
 
 
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)
 
1697
{
 
1698
    return impl::make_binary2<xor_op, T0, BaseT>::construct(_0, _1);
 
1699
}
 
1700
 
 
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)
 
1705
{
 
1706
    return impl::make_binary3<xor_op, BaseT0, BaseT1>::construct(_0, _1);
 
1707
}
 
1708
 
 
1709
///////////////////////////////////////////////////////////////////////////////
 
1710
//
 
1711
//  shift left lazy operator (infix <<)
 
1712
//
 
1713
///////////////////////////////////////////////////////////////////////////////
 
1714
struct shift_l_op {
 
1715
 
 
1716
    template <typename T0, typename T1>
 
1717
    struct result {
 
1718
 
 
1719
        typedef typename binary_operator<shift_l_op, T0, T1>
 
1720
            ::result_type type;
 
1721
    };
 
1722
 
 
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); }
 
1727
};
 
1728
 
 
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)
 
1733
{
 
1734
    return impl::make_binary1<shift_l_op, BaseT, T1>::construct(_0, _1);
 
1735
}
 
1736
 
 
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)
 
1741
{
 
1742
    return impl::make_binary2<shift_l_op, T0, BaseT>::construct(_0, _1);
 
1743
}
 
1744
 
 
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)
 
1749
{
 
1750
    return impl::make_binary3<shift_l_op, BaseT0, BaseT1>::construct(_0, _1);
 
1751
}
 
1752
 
 
1753
///////////////////////////////////////////////////////////////////////////////
 
1754
//
 
1755
//  shift right lazy operator (infix >>)
 
1756
//
 
1757
///////////////////////////////////////////////////////////////////////////////
 
1758
struct shift_r_op {
 
1759
 
 
1760
    template <typename T0, typename T1>
 
1761
    struct result {
 
1762
 
 
1763
        typedef typename binary_operator<shift_r_op, T0, T1>
 
1764
            ::result_type type;
 
1765
    };
 
1766
 
 
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); }
 
1771
};
 
1772
 
 
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)
 
1777
{
 
1778
    return impl::make_binary1<shift_r_op, BaseT, T1>::construct(_0, _1);
 
1779
}
 
1780
 
 
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)
 
1785
{
 
1786
    return impl::make_binary2<shift_r_op, T0, BaseT>::construct(_0, _1);
 
1787
}
 
1788
 
 
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)
 
1793
{
 
1794
    return impl::make_binary3<shift_r_op, BaseT0, BaseT1>::construct(_0, _1);
 
1795
}
 
1796
 
 
1797
///////////////////////////////////////////////////////////////////////////////
 
1798
//
 
1799
//  equal lazy operator (infix ==)
 
1800
//
 
1801
///////////////////////////////////////////////////////////////////////////////
 
1802
struct eq_op {
 
1803
 
 
1804
    template <typename T0, typename T1>
 
1805
    struct result {
 
1806
 
 
1807
        typedef typename binary_operator<eq_op, T0, T1>
 
1808
            ::result_type type;
 
1809
    };
 
1810
 
 
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); }
 
1815
};
 
1816
 
 
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)
 
1821
{
 
1822
    return impl::make_binary1<eq_op, BaseT, T1>::construct(_0, _1);
 
1823
}
 
1824
 
 
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)
 
1829
{
 
1830
    return impl::make_binary2<eq_op, T0, BaseT>::construct(_0, _1);
 
1831
}
 
1832
 
 
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)
 
1837
{
 
1838
    return impl::make_binary3<eq_op, BaseT0, BaseT1>::construct(_0, _1);
 
1839
}
 
1840
 
 
1841
///////////////////////////////////////////////////////////////////////////////
 
1842
//
 
1843
//  not equal lazy operator (infix !=)
 
1844
//
 
1845
///////////////////////////////////////////////////////////////////////////////
 
1846
struct not_eq_op {
 
1847
 
 
1848
    template <typename T0, typename T1>
 
1849
    struct result {
 
1850
 
 
1851
        typedef typename binary_operator<not_eq_op, T0, T1>
 
1852
            ::result_type type;
 
1853
    };
 
1854
 
 
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); }
 
1859
};
 
1860
 
 
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)
 
1865
{
 
1866
    return impl::make_binary1<not_eq_op, BaseT, T1>::construct(_0, _1);
 
1867
}
 
1868
 
 
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)
 
1873
{
 
1874
    return impl::make_binary2<not_eq_op, T0, BaseT>::construct(_0, _1);
 
1875
}
 
1876
 
 
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)
 
1881
{
 
1882
    return impl::make_binary3<not_eq_op, BaseT0, BaseT1>::construct(_0, _1);
 
1883
}
 
1884
 
 
1885
///////////////////////////////////////////////////////////////////////////////
 
1886
//
 
1887
//  less than lazy operator (infix <)
 
1888
//
 
1889
///////////////////////////////////////////////////////////////////////////////
 
1890
struct lt_op {
 
1891
 
 
1892
    template <typename T0, typename T1>
 
1893
    struct result {
 
1894
 
 
1895
        typedef typename binary_operator<lt_op, T0, T1>
 
1896
            ::result_type type;
 
1897
    };
 
1898
 
 
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); }
 
1903
};
 
1904
 
 
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)
 
1909
{
 
1910
    return impl::make_binary1<lt_op, BaseT, T1>::construct(_0, _1);
 
1911
}
 
1912
 
 
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)
 
1917
{
 
1918
    return impl::make_binary2<lt_op, T0, BaseT>::construct(_0, _1);
 
1919
}
 
1920
 
 
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)
 
1925
{
 
1926
    return impl::make_binary3<lt_op, BaseT0, BaseT1>::construct(_0, _1);
 
1927
}
 
1928
 
 
1929
///////////////////////////////////////////////////////////////////////////////
 
1930
//
 
1931
//  less than equal lazy operator (infix <=)
 
1932
//
 
1933
///////////////////////////////////////////////////////////////////////////////
 
1934
struct lt_eq_op {
 
1935
 
 
1936
    template <typename T0, typename T1>
 
1937
    struct result {
 
1938
 
 
1939
        typedef typename binary_operator<lt_eq_op, T0, T1>
 
1940
            ::result_type type;
 
1941
    };
 
1942
 
 
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); }
 
1947
};
 
1948
 
 
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)
 
1953
{
 
1954
    return impl::make_binary1<lt_eq_op, BaseT, T1>::construct(_0, _1);
 
1955
}
 
1956
 
 
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)
 
1961
{
 
1962
    return impl::make_binary2<lt_eq_op, T0, BaseT>::construct(_0, _1);
 
1963
}
 
1964
 
 
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)
 
1969
{
 
1970
    return impl::make_binary3<lt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
 
1971
}
 
1972
 
 
1973
///////////////////////////////////////////////////////////////////////////////
 
1974
//
 
1975
//  greater than lazy operator (infix >)
 
1976
//
 
1977
///////////////////////////////////////////////////////////////////////////////
 
1978
struct gt_op {
 
1979
 
 
1980
    template <typename T0, typename T1>
 
1981
    struct result {
 
1982
 
 
1983
        typedef typename binary_operator<gt_op, T0, T1>
 
1984
            ::result_type type;
 
1985
    };
 
1986
 
 
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); }
 
1991
};
 
1992
 
 
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)
 
1997
{
 
1998
    return impl::make_binary1<gt_op, BaseT, T1>::construct(_0, _1);
 
1999
}
 
2000
 
 
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)
 
2005
{
 
2006
    return impl::make_binary2<gt_op, T0, BaseT>::construct(_0, _1);
 
2007
}
 
2008
 
 
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)
 
2013
{
 
2014
    return impl::make_binary3<gt_op, BaseT0, BaseT1>::construct(_0, _1);
 
2015
}
 
2016
 
 
2017
///////////////////////////////////////////////////////////////////////////////
 
2018
//
 
2019
//  greater than equal lazy operator (infix >=)
 
2020
//
 
2021
///////////////////////////////////////////////////////////////////////////////
 
2022
struct gt_eq_op {
 
2023
 
 
2024
    template <typename T0, typename T1>
 
2025
    struct result {
 
2026
 
 
2027
        typedef typename binary_operator<gt_eq_op, T0, T1>
 
2028
            ::result_type type;
 
2029
    };
 
2030
 
 
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); }
 
2035
};
 
2036
 
 
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)
 
2041
{
 
2042
    return impl::make_binary1<gt_eq_op, BaseT, T1>::construct(_0, _1);
 
2043
}
 
2044
 
 
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)
 
2049
{
 
2050
    return impl::make_binary2<gt_eq_op, T0, BaseT>::construct(_0, _1);
 
2051
}
 
2052
 
 
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)
 
2057
{
 
2058
    return impl::make_binary3<gt_eq_op, BaseT0, BaseT1>::construct(_0, _1);
 
2059
}
 
2060
 
 
2061
///////////////////////////////////////////////////////////////////////////////
 
2062
//
 
2063
//  logical and lazy operator (infix &&)
 
2064
//
 
2065
//  The logical_and_composite class and its corresponding generators are
 
2066
//  provided to allow short-circuit evaluation of the operator's
 
2067
//  operands.
 
2068
//
 
2069
///////////////////////////////////////////////////////////////////////////////
 
2070
template <typename A0, typename A1>
 
2071
struct logical_and_composite {
 
2072
 
 
2073
    typedef logical_and_composite<A0, A1> self_t;
 
2074
 
 
2075
    template <typename TupleT>
 
2076
    struct result {
 
2077
 
 
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;
 
2082
    };
 
2083
 
 
2084
    logical_and_composite(A0 const& _0, A1 const& _1)
 
2085
    :   a0(_0), a1(_1) {}
 
2086
 
 
2087
    template <typename TupleT>
 
2088
    typename actor_result<self_t, TupleT>::type
 
2089
    eval(TupleT const& args) const
 
2090
    {
 
2091
        return a0.eval(args) && a1.eval(args);
 
2092
    }
 
2093
 
 
2094
    A0 a0; A1 a1; //  actors
 
2095
};
 
2096
 
 
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)
 
2103
{
 
2104
    return logical_and_composite
 
2105
        <actor<BaseT>, typename as_actor<T1>::type>
 
2106
        (_0, as_actor<T1>::convert(_1));
 
2107
}
 
2108
 
 
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)
 
2114
{
 
2115
    return logical_and_composite
 
2116
        <typename as_actor<T0>::type, actor<BaseT> >
 
2117
        (as_actor<T0>::convert(_0), _1);
 
2118
}
 
2119
 
 
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)
 
2125
{
 
2126
    return logical_and_composite
 
2127
        <actor<BaseT0>, actor<BaseT1> >
 
2128
        (_0, _1);
 
2129
}
 
2130
#else
 
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)
 
2136
{
 
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));
 
2140
}
 
2141
#endif // !(__ICL && __ICL <= 500)
 
2142
 
 
2143
///////////////////////////////////////////////////////////////////////////////
 
2144
//
 
2145
//  logical or lazy operator (infix ||)
 
2146
//
 
2147
//  The logical_or_composite class and its corresponding generators are
 
2148
//  provided to allow short-circuit evaluation of the operator's
 
2149
//  operands.
 
2150
//
 
2151
///////////////////////////////////////////////////////////////////////////////
 
2152
template <typename A0, typename A1>
 
2153
struct logical_or_composite {
 
2154
 
 
2155
    typedef logical_or_composite<A0, A1> self_t;
 
2156
 
 
2157
    template <typename TupleT>
 
2158
    struct result {
 
2159
 
 
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;
 
2164
    };
 
2165
 
 
2166
    logical_or_composite(A0 const& _0, A1 const& _1)
 
2167
    :   a0(_0), a1(_1) {}
 
2168
 
 
2169
    template <typename TupleT>
 
2170
    typename actor_result<self_t, TupleT>::type
 
2171
    eval(TupleT const& args) const
 
2172
    {
 
2173
        return a0.eval(args) || a1.eval(args);
 
2174
    }
 
2175
 
 
2176
    A0 a0; A1 a1; //  actors
 
2177
};
 
2178
 
 
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)
 
2184
{
 
2185
    return logical_or_composite
 
2186
        <actor<BaseT>, typename as_actor<T1>::type>
 
2187
        (_0, as_actor<T1>::convert(_1));
 
2188
}
 
2189
 
 
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)
 
2195
{
 
2196
    return logical_or_composite
 
2197
        <typename as_actor<T0>::type, actor<BaseT> >
 
2198
        (as_actor<T0>::convert(_0), _1);
 
2199
}
 
2200
 
 
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)
 
2206
{
 
2207
    return logical_or_composite
 
2208
        <actor<BaseT0>, actor<BaseT1> >
 
2209
        (_0, _1);
 
2210
}
 
2211
 
 
2212
}   //  namespace phoenix
 
2213
 
 
2214
#undef CREF
 
2215
#endif