File: function.qbk

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (402 lines) | stat: -rw-r--r-- 10,434 bytes parent folder | download | duplicates (15)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
[/==============================================================================
    Copyright (C) 2001-2010 Joel de Guzman
    Copyright (C) 2001-2005 Dan Marsden
    Copyright (C) 2001-2010 Thomas Heller

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
===============================================================================/]

[section Function]

The `function` class template provides a mechanism for implementing lazily
evaluated functions. Syntactically, a lazy function looks like an ordinary C/C++
function. The function call looks familiar and feels the same as ordinary C++
functions. However, unlike ordinary functions, the actual function execution is
deferred.

    #include <boost/phoenix/function.hpp>

Unlike ordinary function pointers or functor objects that need to be explicitly
bound through the bind function (see [link phoenix.modules.bind Bind]),
the argument types of these functions are automatically lazily bound.

In order to create a lazy function, we need to implement a model of the
__PFO__ concept. For a function that takes `N` arguments, a model of __PFO__ must
provide:

* An `operator()` that takes `N` arguments, and implements
the function logic. This is also true for ordinary function pointers.
* A nested metafunction `result<Signature>` or nested typedef `result_type`, following the __boost_result_of__ Protocol

[/
* A nested metafunction `result<A1, ... AN>` that takes the types of the `N` arguments to
the function and returns the result type of the function. (There is a special case for function
objects that accept no arguments. Such nullary functors are only required to define a typedef
`result_type` that reflects the return type of its `operator()`).
]

For example, the following type implements the FunctionEval concept, in order to provide a
lazy factorial function:

    struct factorial_impl
    {
        template <typename Sig>
        struct result;
        
        template <typename This, typename Arg>
        struct result<This(Arg const &)>
        {
            typedef Arg type;
        };

        template <typename Arg>
        Arg operator()(Arg const & n) const
        {
            return (n <= 0) ? 1 : n * (*this)(n-1);
        }
    };

(See [@../../example/factorial.cpp factorial.cpp])

[/note The type of Arg is either a const-reference or non-const-reference
(depending on whether your argument to the actor evaluation is a const-ref or
non-const-ref).]

Having implemented the `factorial_impl` type, we can declare and instantiate a lazy
`factorial` function this way:

    function<factorial_impl> factorial;

Invoking a lazy function such as `factorial` does not immediately execute the function
object `factorial_impl`. Instead, an [link phoenix.actor actor] object is
created and returned to the caller. Example:

    factorial(arg1)

does nothing more than return an actor. A second function call will invoke
the actual factorial function. Example:

    std::cout << factorial(arg1)(4);

will print out "24".

Take note that in certain cases (e.g. for function objects with state), an
instance of the model of __PFO__ may be passed on to the constructor. Example:

    function<factorial_impl> factorial(ftor);

where ftor is an instance of factorial_impl (this is not necessary in this case
as `factorial_impl` does not require any state).

[important Take care though when using function objects with state because they are
often copied repeatedly, and state may change in one of the copies, rather than the
original.]

[section Adapting Functions]

If you want to adapt already existing functions or function objects it will become
a repetetive task. Therefor the following boilerplate macros are provided to help
you adapt already exsiting functions, thus reducing the need to
[link phoenix.modules.bind] functions.

[section BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY]

[heading Description]
`BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary nullary function a lazy
function.

[note These macros generate no global objects. The resulting lazy functions are real functions
      that create the lazy function expression object]

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(
        RETURN_TYPE
      , LAZY_FUNCTION
      , FUNCTION
    )

[heading Semantics]

The above macro generates all necessary code to have a nullary lazy function
`LAZY_FUNCTION` which calls the nullary `FUNCTION` that has the return type
`RETURN_TYPE`

[heading Header]

    #include <boost/phoenix/function/adapt_function.hpp>

[heading Example]

    namespace demo
    {
        int foo()
        {
            return 42;
        }
    }

    BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int, foo, demo::foo)

    int main()
    {
        using boost::phoenix::placeholders::_1;

        assert((_1 + foo())(1) == 43);
    }

[endsect]

[section BOOST_PHOENIX_ADAPT_FUNCTION]

[heading Description]
`BOOST_PHOENIX_ADAPT_FUNCTION` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary function a lazy function.

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_FUNCTION(
        RETURN_TYPE
      , LAZY_FUNCTION
      , FUNCTION
      , FUNCTION_ARITY
    )

[heading Semantics]

The above macro generates all necessary code to have a lazy function
`LAZY_FUNCTION` which calls `FUNCTION` that has the return type
`RETURN_TYPE` with `FUNCTION_ARITY` number of arguments.

[heading Header]

    #include <boost/phoenix/function/adapt_function.hpp>

[heading Example]

    namespace demo
    {
        int plus(int a, int b)
        {
            return a + b;
        }

        template <typename T>
        T
        plus(T a, T b, T c)
        {
            return a + b + c;
        }
    }

    BOOST_PHOENIX_ADAPT_FUNCTION(int, plus, demo::plus, 2)

    BOOST_PHOENIX_ADAPT_FUNCTION(
        typename remove_reference<A0>::type
      , plus
      , demo::plus
      , 3
    )

    int main()
    {
        using boost::phoenix::arg_names::arg1;
        using boost::phoenix::arg_names::arg2;

        int a = 123;
        int b = 256;

        assert(plus(arg1, arg2)(a, b) == a+b);
        assert(plus(arg1, arg2, 3)(a, b) == a+b+3);
    }

[endsect]

[/

[section BOOST_PHOENIX_ADAPT_FUNCTION_VARARG]

[heading Description]
`BOOST_PHOENIX_ADAPT_FUNCTION_VARARG` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary function a lazy
function.

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_FUNCTION_VARARG(
        RETURN_TYPE
      , LAZY_FUNCTION
      , FUNCTION
    )

[heading Semantics]

[heading Header]
    
    #include <boost/phoenix/function/adapt_function.hpp>

[heading Example]

[endsect]
]

[section BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY]

[heading Description]
`BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary nullary function object a
lazy function.

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY(
        LAZY_FUNCTION
      , CALLABLE
    )

[heading Semantics]

The above macro generates all necessary code to create `LAZY_FUNCTION` which
creates a lazy function object that represents a nullary call to `CALLABLE`.
The return type is specified by `CALLABLE` conforming to the __boost_result_of__
protocol.

[heading Header]
    
    #include <boost/phoenix/function/adapt_callable.hpp>

[heading Example]

    namespace demo
    {
        struct foo
        {
            typedef int result_type;

            result_type operator()() const
            {
                return 42;
            }
        }
    }
    
    BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY(foo, demo::foo)

    int main()
    {
        using boost::phoenix::placeholders::_1;

        assert((_1 + foo())(1) == 43);
    }

[endsect]

[section BOOST_PHOENIX_ADAPT_CALLABLE]

[heading Description]
`BOOST_PHOENIX_ADAPT_CALLABLE` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary function object a lazy
function.

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_CALLABLE(
        LAZY_FUNCTION
      , FUNCTION_NAME
      , FUNCTION_ARITY
    )

[heading Semantics]

The above macro generates all necessary code to create `LAZY_FUNCTION` which
creates a lazy function object that represents a call to `CALLABLE` with `FUNCTION_ARITY`
arguments.
The return type is specified by `CALLABLE` conforming to the __boost_result_of__
protocol.

[heading Header]
    
    #include <boost/phoenix/function/adapt_callable.hpp>

[heading Example]

    namespace demo
    {
        struct plus
        {
            template <typename Sig>
            struct result;

            template <typename This, typename A0, typename A1>
            struct result<This(A0, A1)>
                : remove_reference<A0>
            {};

            template <typename This, typename A0, typename A1, typename A2>
            struct result<This(A0, A1, A2)>
                : remove_reference<A0>
            {};

            template <typename A0, typename A1>
            A0 operator()(A0 const & a0, A1 const & a1) const
            {
                return a0 + a1;
            }

            template <typename A0, typename A1, typename A2>
            A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const
            {
                return a0 + a1 + a2;
            }
        };
    }

    BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 2)

    BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 3)

    int main()
    {
        using boost::phoenix::arg_names::arg1;
        using boost::phoenix::arg_names::arg2;

        int a = 123;
        int b = 256;

        assert(plus(arg1, arg2)(a, b) == a+b);
        assert(plus(arg1, arg2, 3)(a, b) == a+b+3);
    }

[endsect]

[/
[section BOOST_PHOENIX_ADAPT_CALLABLE_VARARG]

[heading Description]
`BOOST_PHOENIX_ADAPT_CALLABLE_VARARG` is a macro that can be used to generate
all the necessary boilerplate to make an arbitrary function object a lazy
function.

[heading Synopsis]

    BOOST_PHOENIX_ADAPT_CALLABLE_VARARG(
        LAZY_FUNCTION_NAME
      , FUNCTION_NAME
    )

[heading Semantics]

[heading Header]
    
    #include <boost/phoenix/function/adapt_callable.hpp>

[heading Example]

[endsect]
/]

[endsect]

[endsect]