1 [/==============================================================================
2 Copyright (C) 2001-2010 Joel de Guzman
3 Copyright (C) 2001-2005 Dan Marsden
4 Copyright (C) 2001-2010 Thomas Heller
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 ===============================================================================/]
12 Actors are composed to create more complex actors in a tree-like hierarchy. The
13 primitives are atomic entities that are like the leaves in the tree. Phoenix is
14 extensible. New primitives can be added anytime. Right out of the box, there are
15 only a few primitives, these are all defined in the Core module.
17 This section shall deal with these preset primitives.
22 #include <boost/phoenix/core/value.hpp>
24 Whenever we see a constant in a partially applied function, an
26 expression::value<T>::type
28 (where T is the type of the constant) is automatically created for
33 Passing a second argument, `6`, an `expression::value<T>::type` is implicitly created
34 behind the scenes. This is also equivalent to `add(arg1, val(6))`.
38 generates an `expression::value<T>::type` where `T` is the type of `x`. In most
39 cases, there's no need to explicitly use `val`, but, as we'll see later on,
40 there are situations where this is unavoidable.
42 [h2 Evaluating a Value]
44 Like arguments, values are also actors. As such, values can be evaluated.
45 Invoking a value gives the value's identity. Example:
47 cout << val(3)() << val("Hello World")();
49 prints out "3 Hello World".
55 #include <boost/phoenix/core/reference.hpp>
57 Values are immutable constants. Attempting to modify a value will result in a
58 compile time error. When we want the function to modify the parameter, we use a
59 reference instead. For instance, imagine a lazy function `add_assign`:
61 void add_assign(T& x, T y) { x += y; } // pseudo code
63 Here, we want the first function argument, x, to be mutable. Obviously, we
66 add_assign(1, 2) // error first argument is immutable
68 In C++, we can pass in a reference to a variable as the first argument in our
69 example above. Yet, by default, the library forces arguments passed to partially
70 applied functions to be immutable values (see [link phoenix.modules.core.values
71 Values]). To achieve our intent, we use:
73 expression::reference<T>::type
75 This is similar to `expression::value<T>::type` before but instead holds a reference to a
78 We normally don't instantiate `expression::reference<T>::type` objects directly. Instead we
83 For example (where `i` is an `int` variable):
87 [heading Evaluating a Reference]
89 References are actors. Hence, references can be evaluated. Such invocation gives
90 the reference's identity. Example:
93 char const* s = "Hello World";
94 cout << ref(i)() << ref(s)();
96 prints out "3 Hello World"
99 [heading Constant References]
101 Another free function
105 may also be used. `cref(cv)` creates an
106 `expression::reference<T const>::type` object. This is similar to `expression::value<T>::type` but
107 when the data to be passed as argument to a function is heavy and expensive to
108 copy by value, the `cref(cv)` offers a lighter alternative.
114 #include <boost/phoenix/core/argument.hpp>
116 We use an instance of:
118 expression::argument<N>::type
120 to represent the Nth function argument. The argument placeholder acts as an
121 imaginary data-bin where a function argument will be placed.
123 [heading Predefined Arguments]
125 There are a few predefined instances of `expression::argument<N>::type` named
126 `arg1`..`argN`, and its __bll__ counterpart `_1`..`_N`. (where N is a predefined
129 Here are some sample preset definitions of `arg1`..`argN`
131 namespace placeholders
133 expression::argument<1>::type const arg1 = {};
134 expression::argument<2>::type const arg2 = {};
135 expression::argument<3>::type const arg3 = {};
138 and its __bll__ `_1`..`_N` style counterparts:
141 namespace placeholders
143 expression::argument<1>::type const _1 = {};
144 expression::argument<2>::type const _2 = {};
145 expression::argument<3>::type const _3 = {};
148 [note You can set `BOOST_PHOENIX_ARG_LIMIT`, the predefined maximum
149 placeholder index. By default, `BOOST_PHOENIX_ARG_LIMIT` is set to `BOOST_PHOENIX_LIMIT`
150 (See [link phoenix.actor Actor]).]
152 [heading User Defined Arguments]
154 When appropriate, you can define your own `argument` names. For example:
156 expression::argument<1>::type x; // note one based index
158 `x` may now be used as a parameter to a lazy function:
162 which is equivalent to:
167 When dealing with argument placeholders the question arises whether you can call
168 member functions on an `argument` actor.
170 This is possible by supplying a custom `actor` which has a member
171 generator function. See [link phoenix.advanced_topics.extending_actors Extending Actors]
175 [heading Evaluating an Argument]
177 An argument, when evaluated, selects the Nth argument from the those passed
184 const char* s = "Hello World";
186 cout << arg1(c) << endl; // Get the 1st argument: c
187 cout << arg1(i, s) << endl; // Get the 1st argument: i
188 cout << arg2(i, s) << endl; // Get the 2nd argument: s
196 [heading Extra Arguments]
198 In C and C++, a function can have extra arguments that are not at all used by
199 the function body itself. These extra arguments are simply ignored.
201 Phoenix also allows extra arguments to be passed. For example, recall our
202 original `add` function:
206 We know now that partially applying this function results to a function that
207 expects 2 arguments. However, the library is a bit more lenient and allows the
208 caller to supply more arguments than is actually required. Thus, `add` actually
209 allows 2 /or more/ arguments. For instance, with:
211 add(arg1, arg2)(x, y, z)
213 the third argument `z` is ignored. Taking this further, in-between arguments are
214 also ignored. Example:
216 add(arg1, arg5)(a, b, c, d, e)
218 Here, arguments b, c, and d are ignored. The function `add` takes in the first
219 argument (`arg1`) and the fifth argument (`arg5`).
221 [note There are a few reasons why enforcing strict arity is not
222 desirable. A case in point is the callback function. Typical callback functions
223 provide more information than is actually needed. Lambda functions are often
230 #include <boost/phoenix/core/nothing.hpp>
232 Finally, the `expression::null<mpl::void_>::type` does nothing; (a "bum", if you will :-) ).
233 There's a sole `expression::null<mpl::void_>::type` instance named "nothing". This actor is
234 actually useful in situations where we don't want to do anything. (See
235 [link phoenix.modules.statement.for_statement for_ Statement] for example).