]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/doc/starter_kit/operator.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / phoenix / doc / starter_kit / 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 Lazy Operators]
11
12 You can use the usual set of operators to form expressions. Examples:
13
14 arg1 * arg1
15 ref(x) = arg1 + ref(z)
16 arg1 = arg2 + (3 * arg3)
17 ref(x) = arg1[arg2] // assuming arg1 is indexable and arg2 is a valid index
18
19 Note the expression: `3 * arg3`. This expression is actually a short-hand
20 equivalent to: `val(3) * arg3`. In most cases, like above, you can get away with
21 it. But in some cases, you will have to explicitly wrap your values in `val`.
22 Rules of thumb:
23
24 * In a binary expression (e.g. `3 * arg3`), at least one of the operands must be
25 a phoenix primitive or expression.
26 * In a unary expression (e.g. `arg1++`), the single operand must be a phoenix
27 primitive or expression.
28
29 If these basic rules are not followed, the result is either an error, or is
30 immediately evaluated. Some examples:
31
32 ref(x) = 123 // lazy
33 x = 123 // immediate
34
35 ref(x)[0] // lazy
36 x[0] // immediate
37
38 ref(x)[ref(i)] // lazy
39 ref(x)[i] // lazy (equivalent to ref(x)[val(i)])
40 x[ref(i)] // illegal (x is not a phoenix primitive or expression)
41 ref(x[ref(i)]) // illegal (x is not a phoenix primitive or expression)
42
43 Why are the last two expression illegal? Although `operator[]` looks as
44 much like a binary operator as `operator=` above it; the difference is
45 that the former must be a member (i.e. `x` must have an `operator[]`
46 that takes a phoenix primitive or expression as its argument). This will
47 most likely not be the case.
48
49 [blurb __tip__ Learn more about operators [link phoenix.modules.operator here.]]
50
51 [heading First Practical Example]
52
53 We've covered enough ground to present a real world example. We want to find the
54 first odd number in an STL container. Normally we use a functor (function
55 object) or a function pointer and pass that in to STL's `find_if` generic
56 function:
57
58 Write a function:
59
60 bool
61 is_odd(int arg1)
62 {
63 return arg1 % 2 == 1;
64 }
65
66 Pass a pointer to the function to STL's `find_if` algorithm:
67
68 std::find_if(c.begin(), c.end(), &is_odd)
69
70 Using Phoenix, the same can be achieved directly with a one-liner:
71
72 std::find_if(c.begin(), c.end(), arg1 % 2 == 1)
73
74 The expression `arg1 % 2 == 1` automagically creates a functor with the expected
75 behavior. In FP, this unnamed function is called a lambda function. Unlike the
76 function pointer version, which is monomorphic (expects and works only with a
77 fixed type int argument), the Phoenix version is fully polymorphic and works
78 with any container (of ints, of longs, of bignum, etc.) as long as its elements
79 can handle the `arg1 % 2 == 1` expression.
80
81 (See [@../../example/find_if.cpp find_if.cpp])
82
83 [blurb __tip__ ...[*That's it, we're done]. Well if you wish to know a little bit
84 more, read on...]
85
86 [endsect]
87