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 Core]
11
12Actors are composed to create more complex actors in a tree-like hierarchy. The
13primitives are atomic entities that are like the leaves in the tree. Phoenix is
14extensible. New primitives can be added anytime. Right out of the box, there are
15only a few primitives, these are all defined in the Core module.
16
17This section shall deal with these preset primitives.
18
19[section Values]
20
21
22    #include <boost/phoenix/core/value.hpp>
23
24Whenever we see a constant in a partially applied function, an
25
26    expression::value<T>::type
27
28(where T is the type of the constant) is automatically created for
29us. For instance:
30
31    add(arg1, 6)
32
33Passing a second argument, `6`, an `expression::value<T>::type` is implicitly created
34behind the scenes. This is also equivalent to `add(arg1, val(6))`.
35
36    val(v)
37
38generates an `expression::value<T>::type` where `T` is the type of `v`. In most
39cases, there's no need to explicitly use `val`, but, as we'll see later on,
40there are situations where this is unavoidable.
41
42[h2 Evaluating a Value]
43
44Like arguments, values are also actors. As such, values can be evaluated.
45Invoking a value gives the value's identity. Example:
46
47    cout << val(3)() << val("Hello World")();
48
49prints out "3 Hello World".
50
51[endsect]
52
53[section References]
54
55    #include <boost/phoenix/core/reference.hpp>
56
57Values are immutable constants. Attempting to modify a value will result in a
58compile time error. When we want the function to modify the parameter, we use a
59reference instead. For instance, imagine a lazy function `add_assign`:
60
61    void add_assign(T& x, T y) { x += y; } // pseudo code
62
63Here, we want the first function argument, x, to be mutable. Obviously, we
64cannot write:
65
66    add_assign(1, 2) // error first argument is immutable
67
68In C++, we can pass in a reference to a variable as the first argument in our
69example above. Yet, by default, the library forces arguments passed to partially
70applied functions to be immutable values (see [link phoenix.modules.core.values
71Values]). To achieve our intent, we use:
72
73    expression::reference<T>::type
74
75This is similar to `expression::value<T>::type` before but instead holds a reference to a
76variable.
77
78We normally don't instantiate `expression::reference<T>::type` objects directly. Instead we
79use:
80
81    ref(v)
82
83For example (where `i` is an `int` variable):
84
85    add_assign(ref(i), 2)
86
87[heading Evaluating a Reference]
88
89References are actors. Hence, references can be evaluated. Such invocation gives
90the reference's identity. Example:
91
92    int i = 3;
93    char const* s = "Hello World";
94    cout << ref(i)() << ref(s)();
95
96prints out "3 Hello World"
97
98
99[heading Constant References]
100
101Another free function
102
103    cref(cv)
104
105may also be used. `cref(cv)` creates an
106`expression::reference<T const>::type` object. This is similar to `expression::value<T>::type` but
107when the data to be passed as argument to a function is heavy and expensive to
108copy by value, the `cref(cv)` offers a lighter alternative.
109
110[endsect]
111
112[section Arguments]
113
114    #include <boost/phoenix/core/argument.hpp>
115
116We use an instance of:
117
118    expression::argument<N>::type
119
120to represent the Nth function argument. The argument placeholder acts as an
121imaginary data-bin where a function argument will be placed.
122
123[heading Predefined Arguments]
124
125There 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
127maximum).
128
129Here are some sample preset definitions of `arg1`..`argN`
130
131    namespace placeholders
132    {
133        expression::argument<1>::type const arg1 = {};
134        expression::argument<2>::type const arg2 = {};
135        expression::argument<3>::type const arg3 = {};
136    }
137
138and its __bll__ `_1`..`_N` style counterparts:
139
140
141    namespace placeholders
142    {
143        expression::argument<1>::type const _1 = {};
144        expression::argument<2>::type const _2 = {};
145        expression::argument<3>::type const _3 = {};
146    }
147
148[note You can set `BOOST_PHOENIX_ARG_LIMIT`, the predefined maximum
149placeholder index. By default, `BOOST_PHOENIX_ARG_LIMIT` is set to `BOOST_PHOENIX_LIMIT`
150(See [link phoenix.actor Actor]).]
151
152[heading User Defined Arguments]
153
154When appropriate, you can define your own `argument` names. For example:
155
156    expression::argument<1>::type x; // note one based index
157
158`x` may now be used as a parameter to a lazy function:
159
160    add(x, 6)
161
162which is equivalent to:
163
164    add(arg1, 6)
165
166[/note
167When dealing with argument placeholders the question arises whether you can call
168member functions on an `argument` actor.
169
170This is possible by supplying a custom `actor` which has a member
171generator function. See [link phoenix.advanced_topics.extending_actors Extending Actors]
172for more details.
173]
174
175[heading Evaluating an Argument]
176
177An argument, when evaluated, selects the Nth argument from the those passed
178in by the client.
179
180For example:
181
182    char        c = 'A';
183    int         i = 123;
184    const char* s = "Hello World";
185
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
189
190will print out:
191
192    A
193    123
194    Hello World
195
196[heading Extra Arguments]
197
198In C and C++, a function can have extra arguments that are not at all used by
199the function body itself. These extra arguments are simply ignored.
200
201Phoenix also allows extra arguments to be passed. For example, recall our
202original `add` function:
203
204    add(arg1, arg2)
205
206We know now that partially applying this function results to a function that
207expects 2 arguments. However, the library is a bit more lenient and allows the
208caller to supply more arguments than is actually required. Thus, `add` actually
209allows 2 /or more/ arguments. For instance, with:
210
211    add(arg1, arg2)(x, y, z)
212
213the third argument `z` is ignored. Taking this further, in-between arguments are
214also ignored. Example:
215
216    add(arg1, arg5)(a, b, c, d, e)
217
218Here, arguments b, c, and d are ignored. The function `add` takes in the first
219argument (`arg1`) and the fifth argument (`arg5`).
220
221[note There are a few reasons why enforcing strict arity is not
222desirable. A case in point is the callback function. Typical callback functions
223provide more information than is actually needed. Lambda functions are often
224used as callbacks.]
225
226[endsect]
227
228[section Nothing]
229
230    #include <boost/phoenix/core/nothing.hpp>
231
232Finally, the `expression::null<mpl::void_>::type` does nothing; (a "bum", if you will :-) ).
233There's a sole `expression::null<mpl::void_>::type` instance named "nothing". This actor is
234actually useful in situations where we don't want to do anything. (See
235[link phoenix.modules.statement.for_statement for_ Statement] for example).
236
237[endsect]
238
239[endsect]
240