Jeff Thompson | a28eed8 | 2013-08-22 16:21:10 -0700 | [diff] [blame^] | 1 | |
| 2 | [/ Copyright (C) 2009-2012 Lorenzo Caminiti ] |
| 3 | [/ Distributed under the Boost Software License, Version 1.0 ] |
| 4 | [/ (see accompanying file LICENSE_1_0.txt or a copy at ] |
| 5 | [/ http://www.boost.org/LICENSE_1_0.txt) ] |
| 6 | [/ Home at http://www.boost.org/libs/functional/overloaded_function ] |
| 7 | |
| 8 | [library Boost.Functional/OverloadedFunction |
| 9 | [quickbook 1.5] |
| 10 | [version 1.0.0] |
| 11 | [copyright 2011-2012 Lorenzo Caminiti] |
| 12 | [purpose overload functions with one function object] |
| 13 | [license |
| 14 | Distributed under the Boost Software License, Version 1.0 |
| 15 | (see accompanying file LICENSE_1_0.txt or copy at |
| 16 | [@http://www.boost.org/LICENSE_1_0.txt]) |
| 17 | ] |
| 18 | [authors [Caminiti <email>lorcaminiti@gmail.com</email>, Lorenzo]] |
| 19 | [category Function Objects and Higher-Order Programming] |
| 20 | ] |
| 21 | |
| 22 | [def __Introduction__ [link functional_overloaded_function.introduction Introduction]] |
| 23 | [def __Getting_Started__ [link functional_overloaded_function.getting_started Getting Started]] |
| 24 | [def __Tutorial__ [link functional_overloaded_function.tutorial Tutorial]] |
| 25 | [def __Boost__ [@http://www.boost.org Boost]] |
| 26 | [def __Boost_Test__ [@http://www.boost.org/libs/test Boost.Test]] |
| 27 | [def __Boost_Function__ [@http://www.boost.org/libs/function Boost.Function]] |
| 28 | [def __Boost_Typeof__ [@http://www.boost.org/doc/libs/typeof Boost.Typeof]] |
| 29 | |
| 30 | [import ../test/identity.hpp] |
| 31 | [import ../test/functor.cpp] |
| 32 | [import ../test/make_decl.cpp] |
| 33 | [import ../test/make_call.cpp] |
| 34 | |
| 35 | This library allows to overload different functions into a single function object. |
| 36 | |
| 37 | [section Introduction] |
| 38 | |
| 39 | Consider the following functions which have distinct signatures: |
| 40 | |
| 41 | [identity_decls] |
| 42 | |
| 43 | Instead of calling them using their separate names (here `BOOST_TEST` is equivalent to `assert`): |
| 44 | [footnote |
| 45 | In most of the examples presented in this documentation, the Boost.Detail/LightweightTest (=boost/detail/lightweight_test.hpp=) macro `BOOST_TEST` is used to check correctness conditions (conceptually similar to `assert`). |
| 46 | A failure of the checked condition does not abort the execution of the program, it will instead make `boost::report_errors` return a non-zero program exit code. |
| 47 | Using Boost.Detail/LightweightTest allows to add the examples to the library regression tests so to make sure that they always compile and run correctly. |
| 48 | ] |
| 49 | |
| 50 | [identity_calls] |
| 51 | |
| 52 | It is possible to use this library to create a single [@http://en.wikipedia.org/wiki/Function_overloading overloaded] function object (or [@http://en.wikipedia.org/wiki/Functor functor]) named `identity` that aggregates together the calls to the specific functions (see also [@../../test/functor.cpp =functor.cpp=] and [@../../test/identity.hpp =identity.hpp=]): |
| 53 | |
| 54 | [identity_functor] |
| 55 | |
| 56 | Note how the functions are called via a single overloaded function object `identity` instead of using their different names `identity_s`, `identity_i`, and `identity_d`. |
| 57 | |
| 58 | [endsect] |
| 59 | |
| 60 | [section Getting Started] |
| 61 | |
| 62 | This section explains how to setup a system to use this library. |
| 63 | |
| 64 | [section Compilers and Platforms] |
| 65 | |
| 66 | The authors originally developed and tested this library on: |
| 67 | |
| 68 | # GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin. |
| 69 | # Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. |
| 70 | |
| 71 | See the library [@http://www.boost.org/development/tests/release/developer/functional-overloaded_function.html regressions test results] for detailed information on supported compilers and platforms. |
| 72 | Check the library regression test [@../../test/Jamfile.v2 =Jamfile.v2=] for any special configuration that might be required for a specific compiler. |
| 73 | |
| 74 | [endsect] |
| 75 | |
| 76 | [section Installation] |
| 77 | |
| 78 | This library is composed of header files only. |
| 79 | Therefore there is no pre-compiled object file which needs to be installed. |
| 80 | Programmers can simply instruct the compiler where to find the library header files (`-I` option on GCC, `/I` option on MSVC, etc) and compile code using the library. |
| 81 | |
| 82 | The maximum number of functions to overload is given by the [macroref BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX] configuration macro. |
| 83 | The maximum number of function parameters for each of the specified function type is given by the [macroref BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX] configuration macro. |
| 84 | All configuration macros have appropriate default values when they are left undefined. |
| 85 | |
| 86 | [endsect] |
| 87 | |
| 88 | [endsect] |
| 89 | |
| 90 | [section Tutorial] |
| 91 | |
| 92 | This section explains how to use this library. |
| 93 | |
| 94 | [section Overloading] |
| 95 | |
| 96 | Consider the following functions which have distinct signatures: |
| 97 | |
| 98 | [identity_decls] |
| 99 | |
| 100 | This library header [headerref boost/functional/overloaded_function.hpp] provides a [classref boost::overloaded_function] class template that creates a single overloaded function object that can be used to call the specified functions instead of using the separate function names (see also [@../../test/functor.cpp =functor.cpp=] and [@../../test/identity.hpp =identity.hpp=]): |
| 101 | |
| 102 | [identity_functor] |
| 103 | |
| 104 | Note how each function type is passed as a template parameter of [classref boost::overloaded_function] using the following syntax (this is __Boost_Function__'s preferred syntax): |
| 105 | |
| 106 | ``/result-type/`` (``/argument1-type/``, ``/argument2-type/``, ...) |
| 107 | |
| 108 | Then the relative function pointers, function references, or [@http://en.wikipedia.org/wiki/Polymorphism_(computer_science) monomorphic function] objects are passed to the [classref boost::overloaded_function] constructor matching the order of the specified template parameters. |
| 109 | [footnote |
| 110 | Function pointers are of the form [^['result-type ]]`(*)(`[^['argument1-type]]`, ...)` (the C++ compiler is usually able to automatically promote a function name to a function pointer in a context where a function pointer is expected even if the function name is not prefixed by `&`). |
| 111 | Function references are of the form [^['result-type ]]`(&)(`[^['argument1-type]]`, ...)`. |
| 112 | Function types are of the form [^['result-type ]]`(`[^['argument1-type]]`, ...)` (note how they lack of both `*` and `&` when compared to function pointers and function references). |
| 113 | Finally, monomorphic function objects are instances of classes with a non-template call operator of the form [^['result-type ]]`operator()(`[^['argument1-type]]`, ...)`. |
| 114 | Unfortunately, it is not possible to support polymorphic function objects (see [@http://lists.boost.org/Archives/boost/2012/03/191744.php]). |
| 115 | ] |
| 116 | In the above example, `identity_s` is passed as a function pointer (the function address is automatically taken from the function name by the compiler), `identity_i` as a function reference, and `identity_d` as a function object. |
| 117 | |
| 118 | All specified function types must have distinct parameters from one another (so the overloaded calls can be resolved by this library). |
| 119 | [footnote |
| 120 | Note that in C++ the function result type is not used for overload resolution (to avoid making the overload resolution context dependent). |
| 121 | Therefore, at least one of the function parameters must be distinct for each specified function type. |
| 122 | ] |
| 123 | In order to create an overloaded function object, it is necessary to specify at least two function types (because there is nothing to overload between one or zero functions). |
| 124 | |
| 125 | [endsect] |
| 126 | |
| 127 | [section Without Function Types] |
| 128 | |
| 129 | For convenience, this library also provides the [funcref boost::make_overloaded_function] function template which allows to create the overloaded function object without explicitly specifying the function types. |
| 130 | The function types are automatically deduced from the specified functions and the appropriate [classref boost::overloaded_function] instantiation is returned by [funcref boost::make_overloaded_function]. |
| 131 | |
| 132 | The [funcref boost::make_overloaded_function] function template can be useful when used together with __Boost_Typeof__'s `BOOST_AUTO` (or C++11 `auto`). |
| 133 | For example (see also [@../../test/make_decl.cpp =make_decl.cpp=] and [@../../test/identity.hpp =identity.hpp=]): |
| 134 | |
| 135 | [identity_make_decl] |
| 136 | |
| 137 | Note how the overloaded function object `identity` has been created specifying only the functions `identity_s`, `identity_i`, `identity_d` and without specifying the function types `const std::string& (const std::string&)`, `int (int)`, and `double (double)` as required instead by [classref boost::overloaded_function]. |
| 138 | Therefore, [funcref boost::make_overloaded_function] provides a more concise syntax in this context when compared with [classref boost::overloaded_function]. |
| 139 | |
| 140 | Another case where [funcref boost::make_overloaded_function] can be useful is when the overloaded function object is passed to a function template which can hold the specific [classref boost::overloaded_function] type using a template parameter. |
| 141 | For example (see also [@../../test/make_call.cpp =make_call.cpp=] and [@../../test/identity.hpp =identity.hpp=]): |
| 142 | |
| 143 | [identity_make_checks] |
| 144 | [identity_make_call] |
| 145 | |
| 146 | The library implementation of [funcref boost::make_overloaded_function] uses __Boost_Typeof__ to automatically deduce some of the function types. |
| 147 | In order to compile code in __Boost_Typeof__ emulation mode, all types should be properly registered using `BOOST_TYPEOF_REGISTER_TYPE` and `BOOST_TYPEOF_REGISTER_TEMPLATE`, or appropriate __Boost_Typeof__ headers should be included (see __Boost_Typeof__ for more information). |
| 148 | For the above examples, it is sufficient to include the __Boost_Typeof__ header that registers `std::string` (this library does not require to register `boost::function` for __Boost_Typeof__ emulation): |
| 149 | |
| 150 | [identity_typeof] |
| 151 | |
| 152 | [endsect] |
| 153 | |
| 154 | [endsect] |
| 155 | |
| 156 | [xinclude reference.xml] |
| 157 | |
| 158 | [section Acknowledgments] |
| 159 | |
| 160 | Many thanks to Mathias Gaunard for suggesting to implement [classref boost::overloaded_function] and for some sample code. |
| 161 | |
| 162 | Thanks to John Bytheway for suggesting to implement [funcref boost::make_overloaded_function]. |
| 163 | |
| 164 | Thanks to Nathan Ridge for suggestions on how to implement [funcref boost::make_overloaded_function]. |
| 165 | |
| 166 | Thanks to Robert Stewart for commenting on the library name. |
| 167 | |
| 168 | Many thanks to the entire __Boost__ community and mailing list for providing valuable comments about this library and great insights on the C++ programming language. |
| 169 | |
| 170 | [endsect] |
| 171 | |