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