• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/==============================================================================
2    Copyright (C) 2006 Tobias Schwinger
3
4    Use, modification and distribution is subject to the Boost Software
5    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6    http://www.boost.org/LICENSE_1_0.txt)
7===============================================================================/]
8[section Functional]
9
10Components to call functions and function objects and to make Fusion code
11callable through a function object interface.
12
13[heading Header]
14
15  #include <boost/fusion/functional.hpp>
16
17[heading Fused and unfused forms]
18
19What is a function call?
20
21    f (a,b,c)
22
23It is a name and a tuple written next to each other, left-to-right.
24
25Although the C++ syntax does not allow to replace [^(a,b,c)] with some Fusion
26__sequence__, introducing yet another function provides a solution:
27
28   invoke(f,my_sequence)
29
30Alternatively it is possible to apply a simple transformation to [^f] in order
31to achieve the same effect:
32
33   f tuple <=> ``f'`` (tuple)
34
35Now, [^f'] is an unary function that takes the arguments to `f` as a tuple;
36[^f'] is the /fused/ form of `f`.
37Reading the above equivalence right-to-left to get the inverse transformation,
38`f` is the /unfused/ form of [^f'].
39
40[heading Calling functions and function objects]
41
42Having generic C++ code call back arbitrary functions provided by the client
43used to be a heavily repetitive task, as different functions can differ in
44arity, invocation syntax and other properties that might be part of the type.
45Transporting arguments as Fusion sequences and factoring out the invocation
46makes Fusion algorithms applicable to function arguments and also reduces
47the problem to one invocation syntax and a fixed arity (instead of an arbitrary
48number of arbitrary arguments times several syntactic variants times additional
49properties).
50
51Transforming an unfused function into its fused counterpart allows n-ary
52calls from an algorithm that invokes an unary __poly_func_obj__ with
53__sequence__ arguments.
54
55The library provides several function templates to invoke different kinds of
56functions and adapters to transform them into fused form, respectively.
57Every variant has a corresponding generator function template that returns
58an adapter instance for the given argument.
59
60Constructors can be called applying __boost_func_factory__.
61
62[heading Making Fusion code callable through a function object interface]
63
64Transforming a fused function into its unfused counterpart allows to create
65function objects to accept arbitrary calls. In other words, an unary function
66object can be implemented instead of (maybe heavily overloaded) function
67templates or function call operators.
68
69The library provides both a strictly typed and a generic variant for this
70transformation. The latter should be used in combination with
71__boost_func_forward__ to attack __the_forwarding_problem__.
72
73Both variants have a corresponding generator function template that returns an
74adapter instance for the given argument.
75
76[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]
77
78[section Concepts]
79
80
81[section:callable Callable Object]
82
83[heading Description]
84
85A pointer to a function, a pointer to member function, a pointer to member
86data, or a class type whose objects can appear immediately to the left of a
87function call operator.
88
89[heading Models]
90* function pointer types
91* member (function or data) pointer types
92* all kinds of function objects
93
94[heading Examples]
95
96  & a_free_function
97  & a_class::a_static_member_function
98  & a_class::a_nonstatic_data_member
99  & a_class::a_nonstatic_member_function
100  std::less<int>()
101  // using namespace boost;
102  bind(std::less<int>(), _1, 5)
103  lambda::_1 += lambda::_2;
104  fusion::__make_fused_function_object__(std::less<int>())
105
106
107[endsect]
108
109
110[section:reg_callable Regular Callable Object]
111
112[heading Description]
113
114A non-member-pointer __callable_obj__ type: A pointer to a function or a class
115type whose objects can appear immediately to the left of a function call operator.
116
117[heading Refinement of]
118* __callable_obj__
119
120[variablelist Notation
121    [[`F`][A possibly const qualified Deferred Callable Object type]]
122    [[`f`][An object or reference to an object of type F]]
123    [[`A1 ...AN`][Argument types]]
124    [[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
125]
126
127[heading Expression requirements]
128
129[table
130    [[Expression][Return Type][Runtime Complexity]]
131    [[`f(a1, ...aN)`][Unspecified][Unspecified]]
132]
133
134[heading Models]
135* function pointer types
136* all kinds of function objects
137
138[heading Examples]
139
140  & a_free_function
141  & a_class::a_static_member_function
142  std::less<int>()
143  // using namespace boost;
144  bind(std::less<int>(), _1, 5)
145  lambda::_1 += lambda::_2;
146  fusion::__make_fused_function_object__(std::less<int>())
147
148[endsect]
149
150
151[section:def_callable Deferred Callable Object]
152
153[heading Description]
154
155__callable_obj__ types that work with __boost_result_of__ to determine the
156result of a call.
157
158[heading Refinement of]
159* __callable_obj__
160
161[blurb note Once C++ supports the [^decltype] keyword, all models of
162__callable_obj__ will also be models of __def_callable_obj__, because
163function objects won't need client-side support for `result_of`.
164]
165
166[variablelist Notation
167    [[`F`][A possibly const qualified Deferred Callable Object type]]
168    [[`A1 ...AN`][Argument types]]
169    [[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
170    [[`T1 ...TN`][`T`i is `A`i `&` if `a`i is an __lvalue__, same as `A`i, otherwise]]
171]
172
173[heading Expression requirements]
174
175[table
176    [[Expression][Type]]
177    [[__boost_result_of_call__`< F(T1 ...TN) >::type`][Result of a call with `A1 ...AN`-typed arguments]]
178]
179
180[heading Models]
181* __poly_func_obj__ types
182* member (function or data) pointer types
183
184[heading Examples]
185
186  & a_free_function
187  & a_class::a_static_member_function
188  & a_class::a_nonstatic_data_member
189  & a_class::a_nonstatic_member_function
190  std::less<int>()
191  // using namespace boost;
192  bind(std::less<int>(), _1, 5)
193  // Note: Boost.Lambda expressions don't work with __boost_result_of__
194  fusion::__make_fused_function_object__(std::less<int>())
195
196[endsect]
197
198
199[section:poly Polymorphic Function Object]
200
201[heading Description]
202
203A non-member-pointer __def_callable_obj__ type.
204
205[heading Refinement of]
206* __reg_callable_obj__
207* __def_callable_obj__
208
209[variablelist Notation
210    [[`F`][A possibly const-qualified Polymorphic Function Object type]]
211    [[`f`][An object or reference to an object of type F]]
212    [[`A1 ...AN`][Argument types]]
213    [[`a1 ...aN`][Objects or references to objects with types `A1 ...AN`]]
214    [[`T1 ...TN`][`T`i is `A`i `&` if `a`i is an __lvalue__, same as `A`i, otherwise]]
215]
216
217[heading Expression requirements]
218
219[table
220    [[Expression][Return Type][Runtime Complexity]]
221    [[`f(a1, ...aN)`][`result_of< F(T1, ...TN) >::type`][Unspecified]]
222]
223
224[heading Models]
225* function pointers
226* function objects of the Standard Library
227* all Fusion __functional_adapters__
228
229[heading Examples]
230
231  & a_free_function
232  & a_class::a_static_member_function
233  std::less<int>()
234  // using namespace boost;
235  bind(std::less<int>(), _1, 5)
236  // Note: Boost.Lambda expressions don't work with __boost_result_of__
237  fusion::__make_fused_function_object__(std::less<int>())
238
239[endsect]
240
241
242[endsect]
243
244[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]
245
246[section Invocation]
247
248[section Functions]
249
250[section invoke]
251
252[heading Description]
253
254Calls a __def_callable_obj__ with the arguments from a __sequence__.
255
256The first template parameter can be specialized explicitly to avoid copying
257and/or to control the const qualification of a function object.
258
259If the target function is a pointer to a class members, the corresponding
260object can be specified as a reference, pointer, or smart pointer.
261In case of the latter, a freestanding [^get_pointer] function must be
262defined (Boost provides this function for [^std::auto_ptr] and
263__boost_shared_ptr_call__).
264
265Constructors can be called applying __boost_func_factory__.
266
267[heading Synopsis]
268    template<
269        typename Function,
270        class Sequence
271        >
272    typename __result_of_invoke__<Function, Sequence>::type
273    invoke(Function f, Sequence & s);
274
275    template<
276        typename Function,
277        class Sequence
278        >
279    typename __result_of_invoke__<Function, Sequence const>::type
280    invoke(Function f, Sequence const & s);
281
282[heading Parameters]
283[table
284    [[Parameter]  [Requirement]                    [Description]]
285    [[`f`]        [A __def_callable_obj__]         [The function to call.]]
286    [[`s`]        [A __forward_sequence__]         [The arguments.]]
287]
288
289[heading Expression Semantics]
290
291    invoke(f,s);
292
293[*Return type]: Return type of `f` when invoked with the elements in `s` as its
294arguments.
295
296[*Semantics]: Invokes `f` with the elements in `s` as arguments and returns
297the result of the call expression.
298
299[heading Header]
300
301  #include <boost/fusion/functional/invocation/invoke.hpp>
302
303[heading Example]
304    __std_plus_doc__<int> add;
305    assert(invoke(add,__make_vector__(1,1)) == 2);
306
307[heading See also]
308* __invoke_procedure__
309* __invoke_function_object__
310* __result_of_invoke__
311* __fused__
312* __make_fused__
313
314[endsect]
315
316[section:invoke_proc invoke_procedure]
317
318[heading Description]
319
320Calls a __callable_obj__ with the arguments from a __sequence__. The result
321of the call is ignored.
322
323The first template parameter can be specialized explicitly to avoid copying
324and/or to control the const qualification of a function object.
325
326For pointers to class members corresponding object can be specified as
327a reference, pointer, or smart pointer. In case of the latter, a freestanding
328[^get_pointer] function must be defined (Boost provides this function for
329[^std::auto_ptr] and __boost_shared_ptr_call__).
330
331The target function must not be a pointer to a member object (dereferencing
332such a pointer without returning anything does not make sense, so it isn't
333implemented).
334
335[heading Synopsis]
336    template<
337        typename Function,
338        class Sequence
339        >
340    typename __result_of_invoke_procedure__<Function, Sequence>::type
341    invoke_procedure(Function f, Sequence & s);
342
343    template<
344        typename Function,
345        class Sequence
346        >
347    typename __result_of_invoke_procedure__<Function, Sequence const>::type
348    invoke_procedure(Function f, Sequence const & s);
349
350[heading Parameters]
351[table
352    [[Parameter]  [Requirement]                    [Description]]
353    [[`f`]        [Model of __callable_obj__]      [The function to call.]]
354    [[`s`]        [Model of __forward_sequence__]  [The arguments.]]
355]
356
357[heading Expression Semantics]
358
359    invoke_procedure(f,s);
360
361[*Return type]: `void`
362
363[*Semantics]: Invokes `f` with the elements in `s` as arguments.
364
365[heading Header]
366
367  #include <boost/fusion/functional/invocation/invoke_procedure.hpp>
368
369[heading Example]
370    __vector__<int,int> v(1,2);
371    using namespace boost::lambda;
372    invoke_procedure(_1 += _2, v);
373    assert(__front__(v) == 3);
374
375[heading See also]
376* __invoke__
377* __invoke_function_object__
378* __result_of_invoke_procedure__
379* __fused_procedure__
380* __make_fused_procedure__
381
382[endsect]
383
384[section:invoke_fobj invoke_function_object]
385
386[heading Description]
387
388Calls a __poly_func_obj__ with the arguments from a __sequence__.
389
390The first template parameter can be specialized explicitly to avoid copying
391and/or to control the const qualification of a function object.
392
393Constructors can be called applying __boost_func_factory__.
394
395[heading Synopsis]
396    template<
397        typename Function,
398        class Sequence
399        >
400    typename __result_of_invoke_function_object__<Function, Sequence>::type
401    invoke_function_object(Function f, Sequence & s);
402
403    template<
404        typename Function,
405        class Sequence
406        >
407    typename __result_of_invoke_function_object__<Function, Sequence const>::type
408    invoke_function_object(Function f, Sequence const & s);
409
410[heading Parameters]
411[table
412    [[Parameter]  [Requirement]                    [Description]]
413    [[`f`]        [Model of __poly_func_obj__]     [The function object to call.]]
414    [[`s`]        [Model of __forward_sequence__]  [The arguments.]]
415]
416
417[heading Expression Semantics]
418
419    invoke_function_object(f,s);
420
421[*Return type]: Return type of `f` when invoked with the elements in `s` as its
422arguments.
423
424[*Semantics]: Invokes `f` with the elements in `s` as arguments and returns the
425result of the call expression.
426
427[heading Header]
428
429  #include <boost/fusion/functional/invocation/invoke_function_object.hpp>
430
431[heading Example]
432    struct sub
433    {
434        template <typename Sig>
435        struct result;
436
437        template <class Self, typename T>
438        struct result< Self(T,T) >
439        { typedef typename remove_reference<T>::type type; };
440
441        template<typename T>
442        T operator()(T lhs, T rhs) const
443        {
444            return lhs - rhs;
445        }
446    };
447
448    void try_it()
449    {
450        sub f;
451        assert(f(2,1) == invoke_function_object(f,__make_vector__(2,1)));
452    }
453
454[heading See also]
455* __invoke__
456* __invoke_procedure__
457* __result_of_invoke_function_object__
458* __fused_function_object__
459* __make_fused_function_object__
460
461[endsect]
462
463[endsect] [/ Functions]
464
465[section Metafunctions]
466
467[section invoke]
468
469[heading Description]
470Returns the result type of __invoke__.
471
472[heading Synopsis]
473    namespace result_of
474    {
475        template<
476            typename Function,
477            class Sequence
478            >
479        struct invoke
480        {
481            typedef __unspecified__ type;
482        };
483    }
484
485[heading See also]
486* __invoke__
487* __fused__
488
489[endsect]
490
491[section:invoke_proc invoke_procedure]
492
493[heading Description]
494Returns the result type of __invoke_procedure__.
495
496[heading Synopsis]
497    namespace result_of
498    {
499        template<
500            typename Function,
501            class Sequence
502            >
503        struct invoke_procedure
504        {
505            typedef __unspecified__ type;
506        };
507    }
508
509[heading See also]
510* __invoke_procedure__
511* __fused_procedure__
512
513[endsect]
514
515[section:invoke_fobj invoke_function_object]
516
517[heading Description]
518Returns the result type of __invoke_function_object__.
519
520[heading Synopsis]
521    namespace result_of
522    {
523        template<
524            class Function,
525            class Sequence
526            >
527        struct invoke_function_object
528        {
529            typedef __unspecified__ type;
530        };
531    }
532
533[heading See also]
534* __invoke_function_object__
535* __fused_function_object__
536
537[endsect]
538
539[endsect] [/ Metafunctions ]
540
541[section Limits]
542
543[heading Header]
544
545  #include <boost/fusion/functional/invocation/limits.hpp>
546
547[heading Macros]
548
549The following macros can be defined to change the maximum arity.
550The default is 6.
551
552* BOOST_FUSION_INVOKE_MAX_ARITY
553* BOOST_FUSION_INVOKE_PROCEDURE_MAX_ARITY
554* BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY
555
556[endsect]
557
558[endsect] [/ Invocation ]
559
560[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]
561
562[section:adapters Adapters]
563
564Function object templates to transform a particular target function.
565
566[section fused]
567
568[heading Description]
569
570An unary __poly_func_obj__ adapter template for __def_callable_obj__ target
571functions. It takes a __forward_sequence__ that contains the arguments for the
572target function.
573
574The type of the target function is allowed to be const qualified or a
575reference. Const qualification is preserved and propagated appropriately
576(in other words, only const versions of [^operator()] can be used for a
577target function object that is const or, if the target function object
578is held by value, the adapter is const - these semantics have nothing to
579do with the const qualification of a member function, which is referring
580to the type of object pointed to by [^this] which is specified with the
581first element in the sequence passed to the adapter).
582
583If the target function is a pointer to a class members, the corresponding
584object can be specified as a reference, pointer, or smart pointer.
585In case of the latter, a freestanding [^get_pointer] function must be
586defined (Boost provides this function for [^std::auto_ptr] and
587__boost_shared_ptr_call__).
588
589[heading Header]
590
591  #include <boost/fusion/functional/adapter/fused.hpp>
592
593[heading Synopsis]
594    template <typename Function>
595    class fused;
596
597[heading Template parameters]
598
599[table
600    [[Parameter]            [Description]                   [Default]]
601    [[`Function`]           [A __def_callable_obj__]        []]
602]
603
604[heading Model of]
605
606* __poly_func_obj__
607* __def_callable_obj__
608
609[variablelist Notation
610    [[`R`] [A possibly const qualified __def_callable_obj__ type or reference type thereof]]
611    [[`r`] [An object convertible to `R`]]
612    [[`s`] [A __sequence__ of arguments that are accepted by `r`]]
613    [[`f`] [An instance of `fused<R>`]]
614]
615
616[heading Expression Semantics]
617
618[table
619    [[Expression]    [Semantics]]
620    [[`fused<R>(r)`] [Creates a fused function as described above, initializes the target function with `r`.]]
621    [[`fused<R>()`]  [Creates a fused function as described above, attempts to use `R`'s default constructor.]]
622    [[`f(s)`]        [Calls `r` with the elements in `s` as its arguments.]]
623]
624
625[heading Example]
626    fused< __std_plus_doc__<long> > f;
627    assert(f(__make_vector__(1,2l)) == 3l);
628
629[heading See also]
630
631* __fused_procedure__
632* __fused_function_object__
633* __invoke__
634* __make_fused__
635* __deduce__
636
637[endsect]
638
639[section fused_procedure]
640
641[heading Description]
642
643An unary __poly_func_obj__ adapter template for __callable_obj__ target
644functions. It takes a __forward_sequence__ that contains the arguments for
645the target function.
646
647The result is discarded and the adapter's return type is `void`.
648
649The type of the target function is allowed to be const qualified or a
650reference. Const qualification is preserved and propagated appropriately
651(in other words, only const versions of [^operator()] can be used for a
652target function object that is const or, if the target function object
653is held by value, the adapter is const - these semantics have nothing to
654do with the const qualification of a member function, which is referring
655to the type of object pointed to by [^this] which is specified with the
656first element in the sequence passed to the adapter).
657
658If the target function is a pointer to a members function, the corresponding
659object can be specified as a reference, pointer, or smart pointer.
660In case of the latter, a freestanding [^get_pointer] function must be
661defined (Boost provides this function for [^std::auto_ptr] and
662__boost_shared_ptr_call__).
663
664The target function must not be a pointer to a member object (dereferencing
665such a pointer without returning anything does not make sense, so this case
666is not implemented).
667
668[heading Header]
669
670  #include <boost/fusion/functional/adapter/fused_procedure.hpp>
671
672[heading Synopsis]
673    template <typename Function>
674    class fused_procedure;
675
676[heading Template parameters]
677
678[table
679    [[Parameter]            [Description]                   [Default]]
680    [[`Function`]           [__callable_obj__ type]         []]
681]
682
683[heading Model of]
684
685* __poly_func_obj__
686* __def_callable_obj__
687
688[variablelist Notation
689    [[`R`] [A possibly const qualified __callable_obj__ type or reference type thereof]]
690    [[`r`] [An object convertible to `R`]]
691    [[`s`] [A __sequence__ of arguments that are accepted by `r`]]
692    [[`f`] [An instance of `fused_procedure<R>`]]
693]
694
695[heading Expression Semantics]
696
697[table
698    [[Expression]              [Semantics]]
699    [[`fused_procedure<R>(r)`] [Creates a fused function as described above, initializes the target function with `r`.]]
700    [[`fused_procedure<R>()`]  [Creates a fused function as described above, attempts to use `R`'s default constructor.]]
701    [[`f(s)`]                  [Calls `r` with the elements in `s` as its arguments.]]
702]
703
704[heading Example]
705    template<class SequenceOfSequences, class Func>
706    void n_ary_for_each(SequenceOfSequences const & s, Func const & f)
707    {
708        __for_each__(__zip_view__<SequenceOfSequences>(s),
709            fused_procedure<Func const &>(f));
710    }
711
712    void try_it()
713    {
714        __vector__<int,float> a(2,2.0f);
715        __vector__<int,float> b(1,1.5f);
716        using namespace boost::lambda;
717        n_ary_for_each(__vector_tie__(a,b), _1 -= _2);
718        assert(a == __make_vector__(1,0.5f));
719    }
720
721[heading See also]
722
723* __fused__
724* __fused_function_object__
725* __invoke_procedure__
726* __make_fused_procedure__
727
728[endsect]
729
730[section fused_function_object]
731
732[heading Description]
733
734An unary __poly_func_obj__ adapter template for a __poly_func_obj__ target
735function. It takes a __forward_sequence__ that contains the arguments for the
736target function.
737
738The type of the target function is allowed to be const qualified or a
739reference. Const qualification is preserved and propagated appropriately
740(in other words, only const versions of [^operator()] can be used for an
741target function object that is const or, if the target function object
742is held by value, the adapter is const).
743
744[heading Header]
745
746  #include <boost/fusion/functional/adapter/fused_function_object.hpp>
747
748[heading Synopsis]
749    template <class Function>
750    class fused_function_object;
751
752[heading Template parameters]
753
754[table
755    [[Parameter]            [Description]                   [Default]]
756    [[`Function`]           [__poly_func_obj__ type]        []]
757]
758
759[heading Model of]
760
761* __poly_func_obj__
762* __def_callable_obj__
763
764[variablelist Notation
765    [[`R`] [A possibly const qualified __poly_func_obj__ type or reference type thereof]]
766    [[`r`] [An object convertible to `R`]]
767    [[`s`] [A __sequence__ of arguments that are accepted by `r`]]
768    [[`f`] [An instance of `fused<R>`]]
769]
770
771[heading Expression Semantics]
772
773[table
774    [[Expression]                    [Semantics]]
775    [[`fused_function_object<R>(r)`] [Creates a fused function as described above, initializes the target function with `r`.]]
776    [[`fused_function_object<R>()`]  [Creates a fused function as described above, attempts to use `R`'s default constructor.]]
777    [[`f(s)`]                        [Calls `r` with the elements in `s` as its arguments.]]
778]
779
780[heading Example]
781    template<class SeqOfSeqs, class Func>
782    typename __result_of_transform__< zip_view<SeqOfSeqs> const,
783        fused_function_object<Func const &> >::type
784    n_ary_transform(SeqOfSeqs const & s, Func const & f)
785    {
786        return __transform__(zip_view<SeqOfSeqs>(s),
787            fused_function_object<Func const &>(f));
788    }
789
790    struct sub
791    {
792        template <typename Sig>
793        struct result;
794
795        template <class Self, typename T>
796        struct result< Self(T,T) >
797        { typedef typename remove_reference<T>::type type; };
798
799        template<typename T>
800        T operator()(T lhs, T rhs) const
801        {
802            return lhs - rhs;
803        }
804    };
805
806    void try_it()
807    {
808        __vector__<int,float> a(2,2.0f);
809        __vector__<int,float> b(1,1.5f);
810        __vector__<int,float> c(1,0.5f);
811        assert(c == n_ary_transform(__vector_tie__(a,b), sub()));
812    }
813
814[heading See also]
815
816* __fused__
817* __fused_procedure__
818* __invoke_function_object__
819* __make_fused_function_object__
820* __deduce__
821
822[endsect]
823
824
825[section unfused]
826
827[heading Description]
828
829An n-ary __poly_func_obj__ adapter template for an unary __poly_func_obj__
830target function. When called, its arguments are bundled to a
831__random_access_sequence__ of references that is passed to the target function
832object.
833
834The nullary overload of the call operator can be removed by setting the
835second template parameter to `false`, which is very useful if the result type
836computation would result in a compile error, otherwise (nullary call
837operator's prototypes can't be templates and thus are instantiated as early
838as the class template).
839
840Only __lvalue__ arguments are accepted. To overcome this limitation, apply
841__boost_func_forward__.
842
843The type of the target function is allowed to be const qualified or a
844reference. Const qualification is preserved and propagated appropriately.
845In other words, only const versions of [^operator()] can be used if
846the target function object is const - or, in case the target function
847object is held by value, the adapter is const.
848
849[heading Header]
850
851  #include <boost/fusion/functional/adapter/unfused.hpp>
852
853[heading Synopsis]
854    template <class Function, bool AllowNullary = true>
855    class unfused;
856
857[heading Template parameters]
858
859[table
860    [[Parameter]  [Description]               [Default]]
861    [[`Function`] [A unary __poly_func_obj__] []]
862    [[`AllowNullary`] [Boolean constant] [true]]
863]
864
865[heading Model of]
866
867* __poly_func_obj__
868* __def_callable_obj__
869
870[variablelist Notation
871    [[`F`]         [A possibly const qualified, unary __poly_func_obj__ type or reference type thereof]]
872    [[`f`]         [An object convertible to `F`]]
873    [[`UL`]        [The type `unfused<F>`]]
874    [[`ul`]        [An instance of `UL`, initialized with `f`]]
875    [[`a0`...`aN`] [Arguments to `ul`]]
876]
877
878[heading Expression Semantics]
879
880[table
881    [[Expression]      [Semantics]]
882    [[`UL(f)`]         [Creates a fused function as described above, initializes the target function with `f`.]]
883    [[`UL()`]          [Creates a fused function as described above, attempts to use `F`'s default constructor.]]
884    [[`ul(a0`...`aN)`] [Calls `f` with a __sequence__ that contains references to the arguments `a0`...`aN`.]]
885]
886
887[heading Example]
888    struct fused_incrementer
889    {
890        template <class Seq>
891        struct result
892        {
893            typedef void type;
894        };
895
896        template <class Seq>
897        void operator()(Seq const & s) const
898        {
899            __for_each__(s,++boost::lambda::_1);
900        }
901    };
902
903    void try_it()
904    {
905        unfused<fused_incrementer> increment;
906        int a = 2; char b = 'X';
907        increment(a,b);
908        assert(a == 3 && b == 'Y');
909    }
910
911[heading See also]
912* __unfused_typed__
913* __make_unfused__
914
915[endsect]
916
917[section unfused_typed]
918
919[heading Description]
920
921An n-ary __poly_func_obj__ adapter template for an unary __poly_func_obj__
922target function. When called, its arguments are bundled to a
923__random_access_sequence__ that is passed to the target function object.
924
925The call operators of resulting function objects are strictly typed
926(in other words, non-templatized) with the types from a __sequence__.
927
928The type of the target function is allowed to be const qualified or a
929reference. Const qualification is preserved and propagated appropriately
930(in other words, only const versions of [^operator()] can be used if
931the target function object is const - or, in case the target function object
932is held by value, the adapter is const).
933
934[note For Microsoft Visual C++ 7.1 (Visual Studio 2003) the detection
935of the Function Object's const qualification easily causes an internal error.
936Therefore the adapter is always treated as if it was const. ]
937
938[tip If the type sequence passed to this template contains
939non-reference elements, the element is copied only once - the call operator's
940signature is optimized automatically to avoid by-value parameters.]
941
942[heading Header]
943
944  #include <boost/fusion/functional/adapter/unfused_typed.hpp>
945
946[heading Synopsis]
947    template <class Function, class Sequence>
948    class unfused_typed;
949
950[heading Template parameters]
951
952[table
953    [[Parameter]  [Description]               [Default]]
954    [[`Function`] [A unary __poly_func_obj__] []]
955    [[`Sequence`] [A __sequence__]            []]
956]
957
958[heading Model of]
959
960* __poly_func_obj__
961* __def_callable_obj__
962
963[variablelist Notation
964    [[`F`]         [A possibly const qualified, unary __poly_func_obj__ type or reference type thereof]]
965    [[`f`]         [An object convertible to `F`]]
966    [[`S`]         [A __sequence__ of parameter types]]
967    [[`UT`]        [The type `unfused_typed<F,S>`]]
968    [[`ut`]        [An instance of `UT`, initialized with `f`]]
969    [[`a0`...`aN`] [Arguments to `ut`, convertible to the types in `S`]]
970]
971
972[heading Expression Semantics]
973
974[table
975    [[Expression]      [Semantics]]
976    [[`UT(f)`]         [Creates a fused function as described above, initializes the target function with `f`.]]
977    [[`UT()`]          [Creates a fused function as described above, attempts to use `F`'s default constructor.]]
978    [[`ut(a0`...`aN)`] [Calls `f` with an instance of `S` (or a subsequence of `S` starting at the first element,
979                        if fewer arguments are given and the overload hasn't been disabled) initialized with
980                        `a0`...`aN`.]]
981]
982
983[heading Example]
984    struct add_assign // applies operator+=
985    {
986        typedef void result_type; // for simplicity
987
988        template <typename T>
989        void operator()(T & lhs, T const & rhs) const
990        {
991            lhs += rhs;
992        }
993    };
994
995    template <class Tie>
996    class fused_parallel_adder
997    {
998        Tie tie_dest;
999    public:
1000        explicit fused_parallel_adder(Tie const & dest)
1001            : tie_dest(dest)
1002        { }
1003
1004        typedef void result_type;
1005
1006        template <class Seq>
1007        void operator()(Seq const & s) const
1008        {
1009            for_each( zip(tie_dest,s), fused<add_assign>() );
1010        }
1011    };
1012
1013    // accepts a tie and creates a typed function object from it
1014    struct fused_parallel_adder_maker
1015    {
1016        template <typename Sig>
1017        struct result;
1018
1019        template <class Self, class Seq>
1020        struct result< Self(Seq) >
1021        {
1022            typedef typename remove_reference<Seq>::type seq;
1023
1024            typedef unfused_typed< fused_parallel_adder<seq>,
1025                typename mpl::transform<seq, remove_reference<_> >::type > type;
1026        };
1027
1028        template <class Seq>
1029        typename result< void(Seq) >::type operator()(Seq const & tie)
1030        {
1031            return typename result< void(Seq) >::type(
1032                fused_parallel_adder<Seq>(tie) );
1033        }
1034    };
1035    unfused<fused_parallel_adder_maker> parallel_add;
1036
1037    void try_it()
1038    {
1039        int a = 2; char b = 'X';
1040        // the second call is strictly typed with the types deduced from the
1041        // first call
1042        parallel_add(a,b)(3,2);
1043        parallel_add(a,b)(3);
1044        parallel_add(a,b)();
1045        assert(a == 8 && b == 'Z');
1046    }
1047
1048[heading See also]
1049* __unfused__
1050* __deduce__
1051* __deduce_sequence__
1052
1053[endsect]
1054
1055[section Limits]
1056
1057[heading Header]
1058
1059  #include <boost/fusion/functional/adapter/limits.hpp>
1060
1061[heading Macros]
1062
1063The following macros can be defined to change the maximum arity.
1064The value used for these macros must not exceed `FUSION_MAX_VECTOR_SIZE`.
1065The default is 6.
1066
1067* BOOST_FUSION_UNFUSED_MAX_ARITY
1068* BOOST_FUSION_UNFUSED_TYPE_MAX_ARITY
1069
1070[endsect]
1071
1072[endsect] [/ Adapters]
1073
1074[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]
1075
1076[section Generation]
1077
1078[section Functions]
1079
1080[section:mk_fused make_fused]
1081
1082[heading Description]
1083Creates a __fused__ adapter for a given __def_callable_obj__. The usual
1084__element_conversion__ is applied to the target function.
1085
1086[heading Synopsis]
1087    template <typename F>
1088    inline typename __result_of_make_fused__<F>::type
1089    make_fused(F const & f);
1090
1091[heading Parameters]
1092[table
1093    [[Parameter]  [Requirement]                    [Description]]
1094    [[`f`]        [Model of __def_callable_obj__]  [The function to transform.]]
1095]
1096
1097[heading Expression Semantics]
1098
1099    make_fused(f);
1100
1101[*Return type]: A specialization of __fused__.
1102
1103[*Semantics]: Returns a __fused__ adapter for `f`.
1104
1105[heading Header]
1106
1107    #include <boost/fusion/functional/generation/make_fused.hpp>
1108    #include <boost/fusion/include/make_fused.hpp>
1109
1110[heading Example]
1111    float sub(float a, float b) { return a - b; }
1112
1113    void try_it()
1114    {
1115        __vector__<int,float> a(2,2.0f);
1116        __vector__<int,float> b(1,1.5f);
1117        __vector__<float,float> c(1.0f,0.5f);
1118        assert(c == __transform__(__zip__(a,b), make_fused(& sub)));
1119        assert(c == __transform__(__zip__(a,b), make_fused(__std_minus_doc__<float>())));
1120    }
1121
1122[heading See also]
1123* __fused__
1124* __deduce__
1125* __result_of_make_fused__
1126
1127[endsect]
1128
1129[section:mk_fused_proc make_fused_procedure]
1130
1131[heading Description]
1132Creates a __fused_procedure__ adapter for a given __def_callable_obj__.
1133The usual __element_conversion__ applied to the target function.
1134
1135[heading Synopsis]
1136    template <typename F>
1137    inline typename __result_of_make_fused_procedure__<F>::type
1138    make_fused_procedure(F const & f);
1139
1140[heading Parameters]
1141[table
1142    [[Parameter]  [Requirement]                    [Description]]
1143    [[`f`]        [Model of __callable_obj__]      [The function to transform.]]
1144]
1145
1146[heading Expression Semantics]
1147
1148    make_fused_procedure(f);
1149
1150[*Return type]: A specialization of __fused_procedure__.
1151
1152[*Semantics]: Returns a __fused_procedure__ adapter for `f`.
1153
1154[heading Header]
1155
1156    #include <boost/fusion/functional/generation/make_fused_procedure.hpp>
1157    #include <boost/fusion/include/make_fused_procedure.hpp>
1158
1159[heading Example]
1160    __vector__<int,int,int> v(1,2,3);
1161    using namespace boost::lambda;
1162    make_fused_procedure(_1 += _2 - _3)(v);
1163    assert(__front__(v) == 0);
1164
1165[heading See also]
1166* __fused_procedure__
1167* __deduce__
1168* __result_of_make_fused_procedure__
1169
1170[endsect]
1171
1172[section:mk_fused_fobj make_fused_function_object]
1173
1174[heading Description]
1175Creates a __fused_function_object__ adapter for a given __def_callable_obj__.
1176The usual __element_conversion__ is applied to the target function.
1177
1178[heading Synopsis]
1179    template <typename F>
1180    inline typename __result_of_make_fused_function_object__<F>::type
1181    make_fused_function_object(F const & f);
1182
1183[heading Parameters]
1184[table
1185    [[Parameter]  [Requirement]                    [Description]]
1186    [[`f`]        [Model of __poly_func_obj__]     [The function to transform.]]
1187]
1188
1189[heading Expression Semantics]
1190
1191    make_fused_function_object(f);
1192
1193[*Return type]: A specialization of __fused_function_object__.
1194
1195[*Semantics]: Returns a __fused_function_object__ adapter for `f`.
1196
1197[heading Header]
1198
1199    #include <boost/fusion/functional/generation/make_fused_function_object.hpp>
1200    #include <boost/fusion/include/make_fused_function_object.hpp>
1201
1202[heading Example]
1203    struct sub
1204    {
1205        template <typename Sig>
1206        struct result;
1207
1208        template <class Self, typename T>
1209        struct result< Self(T,T) >
1210        { typedef typename remove_reference<T>::type type; };
1211
1212        template<typename T>
1213        T operator()(T lhs, T rhs) const
1214        {
1215            return lhs - rhs;
1216        }
1217    };
1218
1219    void try_it()
1220    {
1221        __vector__<int,float> a(2,2.0f);
1222        __vector__<int,float> b(1,1.5f);
1223        __vector__<int,float> c(1,0.5f);
1224        assert(c == __transform__(__zip__(a,b), make_fused_function_object(sub())));
1225    }
1226
1227[heading See also]
1228* __fused_function_object__
1229* __deduce__
1230* __result_of_make_fused_function_object__
1231
1232[endsect]
1233
1234[section:mk_unfused make_unfused]
1235
1236[heading Description]
1237Creates a __unfused__ adapter for a given, unary __poly_func_obj__.
1238The usual __element_conversion__ is applied to the target function.
1239
1240[heading Synopsis]
1241    template <typename F>
1242    inline typename __result_of_make_unfused__<F>::type
1243    make_unfused(F const & f);
1244
1245[heading Parameters]
1246[table
1247    [[Parameter]  [Requirement]                    [Description]]
1248    [[`f`]        [Model of __poly_func_obj__]     [The function to transform.]]
1249]
1250
1251[heading Expression Semantics]
1252
1253    make_unfused(f);
1254
1255[*Return type]: A specialization of __unfused__.
1256
1257[*Semantics]: Returns a __unfused__ adapter for `f`.
1258
1259[heading Header]
1260
1261    #include <boost/fusion/functional/generation/make_unfused.hpp>
1262    #include <boost/fusion/include/make_unfused.hpp>
1263
1264[heading Example]
1265    struct fused_incrementer
1266    {
1267        template <class Seq>
1268        struct result
1269        {
1270            typedef void type;
1271        };
1272
1273        template <class Seq>
1274        void operator()(Seq const & s) const
1275        {
1276            __for_each__(s,++boost::lambda::_1);
1277        }
1278    };
1279
1280    void try_it()
1281    {
1282        int a = 2; char b = 'X';
1283        make_unfused(fused_incrementer())(a,b);
1284        assert(a == 3 && b == 'Y');
1285    }
1286
1287[heading See also]
1288* __unfused__
1289* __deduce__
1290* __result_of_make_unfused__
1291
1292[endsect]
1293
1294[endsect] [/ Functions]
1295
1296[section Metafunctions]
1297
1298[section:mk_fused make_fused]
1299
1300[heading Description]
1301Returns the result type of __make_fused__.
1302
1303[heading Header]
1304
1305    #include <boost/fusion/functional/generation/make_fused.hpp>
1306    #include <boost/fusion/include/make_fused.hpp>
1307
1308[heading Synopsis]
1309    namespace result_of
1310    {
1311        template<typename Function>
1312        struct make_fused
1313        {
1314            typedef __unspecified__ type;
1315        };
1316    }
1317
1318[heading See also]
1319* __make_fused__
1320
1321[endsect]
1322
1323[section:mk_fused_proc make_fused_procedure]
1324
1325[heading Description]
1326Returns the result type of __make_fused_procedure__.
1327
1328[heading Header]
1329
1330    #include <boost/fusion/functional/generation/make_fused_procedure.hpp>
1331    #include <boost/fusion/include/make_fused_procedure.hpp>
1332
1333[heading Synopsis]
1334    namespace result_of
1335    {
1336        template<typename Function>
1337        struct make_fused_procedure
1338        {
1339            typedef __unspecified__ type;
1340        };
1341    }
1342
1343[heading See also]
1344* __make_fused_procedure__
1345
1346[endsect]
1347
1348[section:mk_fused_fobj make_fused_function_object]
1349
1350[heading Description]
1351Returns the result type of __make_fused_function_object__.
1352
1353[heading Header]
1354
1355    #include <boost/fusion/functional/generation/make_fused_function_object.hpp>
1356    #include <boost/fusion/include/make_fused_function_object.hpp>
1357
1358[heading Synopsis]
1359    namespace result_of
1360    {
1361        template<typename Function>
1362        struct make_fused_function_object
1363        {
1364            typedef __unspecified__ type;
1365        };
1366    }
1367
1368[heading See also]
1369* __make_fused_function_object__
1370
1371[endsect]
1372
1373[section:mk_unfused make_unfused]
1374
1375[heading Description]
1376Returns the result type of __make_unfused__.
1377
1378[heading Header]
1379
1380    #include <boost/fusion/functional/generation/make_unfused.hpp>
1381    #include <boost/fusion/include/make_unfused.hpp>
1382
1383[heading Synopsis]
1384    namespace result_of
1385    {
1386        template<typename Function>
1387        struct make_unfused
1388        {
1389            typedef __unspecified__ type;
1390        };
1391    }
1392
1393[heading See also]
1394* __make_unfused__
1395
1396[endsect]
1397
1398[endsect] [/ Metafunctions]
1399
1400[endsect] [/ Generation]
1401
1402[endsect] [/ Functional ]
1403