]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/doc/modules/operator.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / phoenix / doc / modules / operator.qbk
1 [/==============================================================================
2 Copyright (C) 2001-2010 Joel de Guzman
3 Copyright (C) 2001-2005 Dan Marsden
4 Copyright (C) 2001-2010 Thomas Heller
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ===============================================================================/]
9
10 [section Operator]
11 #include <boost/phoenix/operator.hpp>
12
13 This facility provides a mechanism for lazily evaluating operators.
14 Syntactically, a lazy operator looks and feels like an ordinary C/C++ infix,
15 prefix or postfix operator. The operator application looks the same. However,
16 unlike ordinary operators, the actual operator execution is deferred. Samples:
17
18 arg1 + arg2
19 1 + arg1 * arg2
20 1 / -arg1
21 arg1 < 150
22
23 We have seen the lazy operators in action (see [link phoenix.starter_kit.lazy_operators
24 Quick Start - Lazy Operators]). Let's go back and examine them a little bit further:
25
26 std::find_if(c.begin(), c.end(), arg1 % 2 == 1)
27
28 Through operator overloading, the expression `arg1 % 2 == 1` actually generates
29 an actor. This actor object is passed on to STL's `find_if` function. From
30 the viewpoint of STL, the expression is simply a function object expecting a
31 single argument of the containers value_type. For each element in `c`,
32 the element is passed on as an argument `arg1` to the actor (function
33 object). The actor checks if this is an odd value based on the expression
34 `arg1 % 2 == 1` where arg1 is replaced by the container's element.
35
36 Like lazy functions (see
37 [link phoenix.modules.function Function]), lazy operators are not immediately executed
38 when invoked. Instead, an actor (see [link phoenix.actor Actor])
39 object is created and returned to the caller. Example:
40
41 (arg1 + arg2) * arg3
42
43 does nothing more than return an actor. A second function call will evaluate
44 the actual operators. Example:
45
46 std::cout << ((arg1 + arg2) * arg3)(4, 5, 6);
47
48 will print out "54".
49
50 Operator expressions are lazily evaluated following four simple rules:
51
52 # A binary operator, except `->*` will be lazily evaluated when
53 /at least/ one of its operands is an actor object
54 (see [link phoenix.actor Actor]).
55 # Unary operators are lazily evaluated if their argument is an actor object.
56 # Operator `->*` is lazily evaluated if the left hand argument is an actor object.
57 # The result of a lazy operator is an actor object that can in turn allow the
58 applications of rules 1, 2 and 3.
59
60 For example, to check the following expression is lazily evaluated:
61
62 -(arg1 + 3 + 6)
63
64 # Following rule 1, `arg1 + 3` is lazily evaluated since `arg1` is an actor
65 (see [link phoenix.modules.core.arguments Arguments]).
66 # The result of this `arg1 + 3` expression is an actor object, following rule 4.
67 # Continuing, `arg1 + 3 + 6` is again lazily evaluated.
68 Rule 2.
69 # By rule 4 again, the result of `arg1 + 3 + 6` is an actor object.
70 # As `arg1 + 3 + 6` is an actor, `-(arg1 + 3 + 6)` is lazily evaluated. Rule 2.
71
72 Lazy-operator application is highly contagious. In most cases, a single `argN`
73 actor infects all its immediate neighbors within a group (first level or
74 parenthesized expression).
75
76 Note that at least one operand of any operator must be a valid actor
77 for lazy evaluation to take effect. To force lazy evaluation of an
78 ordinary expression, we can use `ref(x)`, `val(x)` or `cref(x)` to
79 transform an operand into a valid actor object (see [link phoenix.modules.core Core]).
80 For example:
81
82 1 << 3; // Immediately evaluated
83 val(1) << 3; // Lazily evaluated
84
85 [heading Supported operators]
86
87 [heading Unary operators]
88
89 prefix: ~, !, -, +, ++, --, & (reference), * (dereference)
90 postfix: ++, --
91
92 [heading Binary operators]
93
94 =, [], +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
95 +, -, *, /, %, &, |, ^, <<, >>
96 ==, !=, <, >, <=, >=
97 &&, ||, ->*
98
99 [heading Ternary operator]
100
101 if_else(c, a, b)
102
103 The ternary operator deserves special mention. Since C++ does not allow us to
104 overload the conditional expression: `c ? a : b`, the if_else pseudo function is
105 provided for this purpose. The behavior is identical, albeit in a lazy manner.
106
107 [heading Member pointer operator]
108
109 a->*member_object_pointer
110 a->*member_function_pointer
111
112 The left hand side of the member pointer operator must be an actor returning a pointer
113 type. The right hand side of the member pointer operator may be either a pointer to member
114 object or pointer to member function.
115
116 If the right hand side is a member object pointer, the result is an actor which, when evaluated,
117 returns a reference to that member. For example:
118
119 struct A
120 {
121 int member;
122 };
123
124 A* a = new A;
125 ...
126
127 (arg1->*&A::member)(a); // returns member a->member
128
129 If the right hand side is a member function pointer, the result is an actor which, when invoked, calls the specified member function. For example:
130
131 struct A
132 {
133 int func(int);
134 };
135
136 A* a = new A;
137 int i = 0;
138
139 (arg1->*&A::func)(arg2)(a, i); // returns a->func(i)
140
141 [heading Include Files]
142
143 [table
144 [[Operators] [File]]
145 [[`-`, `+`, `++`, `--`, `+=`,
146 `-=`, `*=`, `/=`, `%=`,
147 `*`, `/`, `%`] [`#include <boost/phoenix/operator/arithmetic.hpp>`]]
148 [[`&=`, `|=`, `^=`, `<<=`,
149 `>>=`, `&`, `|`, `^`, `<<`,
150 `>>`] [`#include <boost/phoenix/operator/bitwise.hpp>`]]
151 [[`==`, `!=`, `<`,
152 `<=`, `>`, `>=`] [`#include <boost/phoenix/operator/comparison.hpp>`]]
153 [[`<<`, `>>`] [`#include <boost/phoenix/operator/io.hpp>`]]
154 [[`!`, &&, `||`] [`#include <boost/phoenix/operator/logical.hpp>`]]
155 [[`&x`, `*p`, `=`, `[]`] [`#include <boost/phoenix/operator/self.hpp>`]]
156 [[`if_else(c, a, b)`] [`#include <boost/phoenix/operator/if_else.hpp>`]]
157 [[`->*`] [`#include <boost/phoenix/operator/member.hpp>`]]
158 ]
159
160 [endsect]