|
||||
File indexing completed on 2024-11-15 09:34:14
0001 0002 // Copyright (C) 2009-2012 Lorenzo Caminiti 0003 // Distributed under the Boost Software License, Version 1.0 0004 // (see accompanying file LICENSE_1_0.txt or a copy at 0005 // http://www.boost.org/LICENSE_1_0.txt) 0006 // Home at http://www.boost.org/libs/local_function 0007 0008 #ifndef BOOST_LOCAL_FUNCTION_HPP_ 0009 #define BOOST_LOCAL_FUNCTION_HPP_ 0010 0011 #ifndef DOXYGEN 0012 0013 #include <boost/local_function/aux_/macro/decl.hpp> 0014 #include <boost/local_function/aux_/macro/name.hpp> 0015 #include <boost/local_function/aux_/macro/typeof.hpp> 0016 #include <boost/local_function/aux_/preprocessor/traits/decl.hpp> 0017 #include <boost/local_function/detail/preprocessor/line_counter.hpp> 0018 #include <boost/local_function/detail/preprocessor/void_list.hpp> 0019 #include <boost/config.hpp> 0020 0021 // PUBLIC // 0022 0023 #ifdef BOOST_NO_CXX11_VARIADIC_MACROS 0024 # define BOOST_LOCAL_FUNCTION_ID(id, declarations) \ 0025 BOOST_LOCAL_FUNCTION_AUX_DECL(id, 0 /* not within template */, \ 0026 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \ 0027 BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST( \ 0028 declarations))) 0029 # define BOOST_LOCAL_FUNCTION(declarations) \ 0030 BOOST_LOCAL_FUNCTION_ID( \ 0031 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, declarations) 0032 # define BOOST_LOCAL_FUNCTION_ID_TPL(id, declarations) \ 0033 BOOST_LOCAL_FUNCTION_AUX_DECL(id, 1 /* within template */, \ 0034 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \ 0035 BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST( \ 0036 declarations))) 0037 # define BOOST_LOCAL_FUNCTION_TPL(declarations) \ 0038 BOOST_LOCAL_FUNCTION_ID_TPL( \ 0039 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, declarations) 0040 #else // VARIADIC 0041 # define BOOST_LOCAL_FUNCTION_ID(id, ...) \ 0042 BOOST_LOCAL_FUNCTION_AUX_DECL(id, 0 /* not within template */, \ 0043 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \ 0044 BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__))) 0045 # define BOOST_LOCAL_FUNCTION(...) \ 0046 BOOST_LOCAL_FUNCTION_ID( \ 0047 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, __VA_ARGS__) 0048 # define BOOST_LOCAL_FUNCTION_ID_TPL(id, ...) \ 0049 BOOST_LOCAL_FUNCTION_AUX_DECL(id, 1 /* within template */, \ 0050 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \ 0051 BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__))) 0052 # define BOOST_LOCAL_FUNCTION_TPL(...) \ 0053 BOOST_LOCAL_FUNCTION_ID_TPL( \ 0054 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, __VA_ARGS__) 0055 #endif // VARIADIC 0056 0057 #define BOOST_LOCAL_FUNCTION_NAME(qualified_name) \ 0058 BOOST_LOCAL_FUNCTION_AUX_NAME(0 /* not within template */, qualified_name) 0059 #define BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name) \ 0060 BOOST_LOCAL_FUNCTION_AUX_NAME(1 /* within template */, qualified_name) 0061 0062 #define BOOST_LOCAL_FUNCTION_TYPEOF(bound_variable_name) \ 0063 BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE(bound_variable_name) 0064 0065 // DOCUMENTATION // 0066 0067 #else // DOXYGEN 0068 0069 /** @file 0070 @brief Local functions allow to program functions locally, within other 0071 functions, and directly within the scope where they are needed. 0072 */ 0073 0074 /** 0075 @brief This macro is used to start a local function declaration. 0076 0077 This macro must be used within a declarative context, it must follow the local 0078 function result type, it must be followed by the local function body code, and 0079 then by the @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro (see the 0080 @RefSect{tutorial, Tutorial} and @RefSect{advanced_topics, Advanced Topics} 0081 sections): 0082 @code 0083 { // Some declarative context. 0084 ... 0085 result_type BOOST_LOCAL_FUNCTION(declarations) { 0086 ... // Body code. 0087 } BOOST_LOCAL_FUNCTION_NAME(qualified_name) 0088 ... 0089 } 0090 @endcode 0091 0092 As usual, exceptions specifications can be optionally programmed just after the 0093 macro and before the body code block <c>{ ... }</c> (but the exception 0094 specifications will only apply to the body code and not to the library code 0095 automatically generated by the macro expansion, see the 0096 @RefSect{advanced_topics, Advanced Topics} section). 0097 0098 Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_TPL} 0099 and @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used. 0100 0101 @Params 0102 @Param{declarations, 0103 On compilers that support variadic macros\, the parameter declarations are 0104 defined by the following grammar: 0105 @code 0106 declarations: 0107 void | declaration_tuple | declaration_sequence 0108 declaration_tuple: 0109 declaration\, declaration\, ... 0110 declaration_sequence: 0111 (declaration) (declaration) ... 0112 declaration: 0113 bound_variable | parameter | default_value | result_type 0114 bound_variable: 0115 [const] bind [(variable_type)] [&] variable_name 0116 parameter: 0117 [auto | register] parameter_type parameter_name 0118 default_value: 0119 default parameter_default_value 0120 result_type: 0121 return function_result_type 0122 @endcode 0123 On compilers that do not support variadic macros\, <c>declaration_tuple</c> 0124 cannot be used: 0125 @code 0126 declarations: 0127 void | declaration_sequence 0128 @endcode 0129 0130 (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or 0131 <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing; 0132 <c>{expression}</c> means the token resulting from the expression.) 0133 } 0134 @EndParams 0135 0136 Note that on compilers that support variadic macros, commas can be used to 0137 separate the declarations resembling more closely the usual C++ function 0138 declaration syntax (this is the preferred syntax). 0139 However, for portability, on all C++ compilers (with and without variadic 0140 macros) the same library macros also accept parameter declarations specified as 0141 a Boost.Preprocessor sequence separated by round parenthesis <c>()</c>. 0142 0143 When binding the object <c>this</c>, the special symbol <c>this_</c> needs to 0144 be used instead of <c>this</c> as the name of the variable to bind and also 0145 within the local function body to access the object. 0146 (Mistakenly using <c>this</c> instead of <c>this_</c> might not always result in a compiler error and will in general result in undefined behaviour.) 0147 0148 The result type must either be specified just before the macro or within the 0149 macro declarations prefixed by <c>return</c> (but not in both places). 0150 0151 Within the local function body it possible to access the result type using <c>result_type</c>, the type of the first parameter using <c>arg1_type</c>, the type of the second parameter using <c>arg2_type</c>, etc. 0152 The bound variable types can be accessed using @RefMacro{BOOST_LOCAL_FUNCTION_TYPEOF}. 0153 0154 This macro cannot be portably expanded multiple times on the same line. 0155 In these cases, use the @RefMacro{BOOST_LOCAL_FUNCTION_ID} macro instead. 0156 0157 The maximum number of local function parameters (excluding bound variables) is 0158 specified by the configuration macro 0159 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX}. 0160 The maximum number of bound variables is specified by the configuration macro 0161 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX}. 0162 The configuration macro 0163 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS} can be used to force 0164 optimizations that reduce the local function call run-time overhead. 0165 0166 @Note Local functions are functors so they can be assigned to other functors 0167 like <c>boost::function</c> (see Boost.Function). 0168 0169 @See @RefSect{tutorial, Tutorial} section, 0170 @RefSect{advanced_topics, Advanced Topics} section, 0171 @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, @RefMacro{BOOST_LOCAL_FUNCTION_TPL}, 0172 @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL}, 0173 @RefMacro{BOOST_LOCAL_FUNCTION_TYPEOF}, @RefMacro{BOOST_LOCAL_FUNCTION_ID}, 0174 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX}, 0175 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX}, 0176 @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS}. 0177 */ 0178 #define BOOST_LOCAL_FUNCTION(declarations) 0179 0180 /** 0181 @brief This macro is used to start a local function declaration within 0182 templates. 0183 0184 This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION} when 0185 declaring a local function within a template. 0186 A part from that, this macro has the exact same syntax a 0187 @RefMacro{BOOST_LOCAL_FUNCTION} (see @RefMacro{BOOST_LOCAL_FUNCTION} for more 0188 information): 0189 @code 0190 { // Some declarative context within a template. 0191 ... 0192 result_type BOOST_LOCAL_FUNCTION_TPL(declarations) { 0193 ... // Body code. 0194 } BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name) 0195 ... 0196 } 0197 @endcode 0198 0199 Note that @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used with this 0200 macro instead of @RefMacro{BOOST_LOCAL_FUNCTION_NAME}. 0201 0202 This macro cannot be portably expanded multiple times on the same line. 0203 In these cases, use the @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL} macro instead. 0204 0205 @Note C++03 does not allow to use <c>typename</c> outside templates. 0206 This library internally manipulates types, these operations require 0207 <c>typename</c> but only within templates. 0208 This macro is used to indicate to the library when the enclosing scope is a 0209 template so the library can correctly use <c>typename</c>. 0210 0211 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_LOCAL_FUNCTION}, 0212 @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL}, 0213 @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL}. 0214 */ 0215 #define BOOST_LOCAL_FUNCTION_TPL(declarations) 0216 0217 /** 0218 @brief This macro allows to declare multiple local functions on the same line. 0219 0220 This macro is equivalent to @RefMacro{BOOST_LOCAL_FUNCTION} but it can be 0221 expanded multiple times on the same line if different identifiers <c>id</c> are 0222 provided for each expansion (see the 0223 @RefSect{advanced_topics, Advanced Topics} section). 0224 0225 @Params 0226 @Param{id, 0227 A unique identifier token which can be concatenated by the preprocessor 0228 (<c>__LINE__</c>\, <c>local_function_number_1_on_line_123</c>\, etc). 0229 } 0230 @Param{declarations, 0231 Same as the <c>declarations</c> parameter of the 0232 @RefMacro{BOOST_LOCAL_FUNCTION} macro. 0233 } 0234 @EndParams 0235 0236 The @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro should be used to end each one 0237 of the multiple local function declarations as usual (and it will specify a 0238 unique name for each local function). 0239 0240 Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL} 0241 must be used. 0242 0243 @Note This macro can be useful when the local function macros are expanded 0244 within user-defined macros (because macros all expand on the same line). 0245 On some compilers (e.g., MSVC which supports the non-standard 0246 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but 0247 the use of this macro when expanding multiple local function macros on the same 0248 line is always necessary to ensure portability (this is because this library 0249 can only portably use <c>__LINE__</c> to internally generate unique 0250 identifiers). 0251 0252 @See @RefSect{advanced_topics, Advanced Topics} section, 0253 @RefMacro{BOOST_LOCAL_FUNCTION}, @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, 0254 @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL}. 0255 */ 0256 #define BOOST_LOCAL_FUNCTION_ID(id, declarations) 0257 0258 /** 0259 @brief This macro allows to declare multiple local functions on the same line 0260 within templates. 0261 0262 This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION_TPL} when 0263 declaring multiple local functions on the same line within a template. 0264 A part from that, this macro has the exact same syntax as 0265 @RefMacro{BOOST_LOCAL_FUNCTION_TPL} (see @RefMacro{BOOST_LOCAL_FUNCTION_TPL} 0266 for more information). 0267 0268 @Params 0269 @Param{id, 0270 A unique identifier token which can be concatenated by the preprocessor 0271 (<c>__LINE__</c>\, <c>local_function_number_1_on_line_123</c>\, etc). 0272 } 0273 @Param{declarations, 0274 Same as the <c>declarations</c> parameter of the 0275 @RefMacro{BOOST_LOCAL_FUNCTION_TPL} macro. 0276 } 0277 @EndParams 0278 0279 The @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro should be used to end each one 0280 of the multiple local function declarations as usual (and it will specify a 0281 unique name for each local function). 0282 0283 Outside template, the macro @RefMacro{BOOST_LOCAL_FUNCTION_ID} should be used 0284 to declare multiple local functions on the same line. 0285 0286 @Note This macro can be useful when the local function macros are expanded 0287 within user-defined macros (because macros all expand on the same line). 0288 On some compilers (e.g., MSVC which supports the non-standard 0289 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but 0290 the use of this macro when expanding multiple local function macros on the same 0291 line is always necessary to ensure portability (this is because this library 0292 can only portably use <c>__LINE__</c> to internally generate unique 0293 identifiers). 0294 0295 @See @RefSect{advanced_topics, Advanced Topics} section, 0296 @RefMacro{BOOST_LOCAL_FUNCTION_TPL}, @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, 0297 @RefMacro{BOOST_LOCAL_FUNCTION_ID}. 0298 */ 0299 #define BOOST_LOCAL_FUNCTION_ID_TPL(id, declarations) 0300 0301 /** 0302 @brief This macro is used to end a local function declaration specifying its 0303 name. 0304 0305 This macro must follow the local function body code block <c>{ ... }</c>: 0306 @code 0307 { // Some declarative context. 0308 ... 0309 result_type BOOST_LOCAL_FUNCTION(declarations) { 0310 ... // Body code. 0311 } BOOST_LOCAL_FUNCTION_NAME(qualified_name) 0312 ... 0313 } 0314 @endcode 0315 0316 Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_TPL} and 0317 @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used. 0318 0319 @Params 0320 @Param{qualified_name, 0321 The name of the local function optionally qualified as follow: 0322 @code 0323 name: 0324 [inline] [recursive] local_function_name 0325 @endcode 0326 (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or 0327 <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing; 0328 <c>{expression}</c> means the token resulting from the expression.) 0329 } 0330 @EndParams 0331 0332 The local function name can be qualified by prefixing it with the keyword 0333 <c>inline</c> (see the @RefSect{advanced_topics, Advanced Topics} section): 0334 @code 0335 BOOST_LOCAL_FUNCTION_NAME(inline local_function_name) 0336 @endcode 0337 This increases the chances that the compiler will be able to inline the local 0338 function calls (thus reducing run-time). 0339 However, inline local functions cannot be passed as template parameters (e.g., to <c>std::for_each</c>) or assigned to other functors (e.g., to 0340 <c>boost::function</c>). 0341 That is true on C++03 compilers but inline local functions can instead be 0342 passed as template parameters on C++11 compilers. 0343 On C++11 compilers, there is no need to declare a local function lined because 0344 this library will automatically use C++11 specific features to inline the local 0345 function while always allowing to pass it as a template parameter. 0346 This optimization is automatically enabled when the Boost.Config macro 0347 <c>BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</c> is not defined but it also be 0348 forced using @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS}. 0349 0350 The local function name can also be qualified by prefixing it with the 0351 "keyword" <c>recursive</c> (see the 0352 @RefSect{advanced_topics, Advanced Topics} section): 0353 @code 0354 BOOST_LOCAL_FUNCTION_NAME(recursive local_function_name) 0355 @endcode 0356 This allows the local function to recursively call itself from its body (as 0357 usual in C++). 0358 However, recursive local functions should only be called within their 0359 declaration scope (otherwise the result is undefined behaviour). 0360 Finally, compilers have not been observed to be able to inline recursive local 0361 function calls, not even when the recursive local function is also declared 0362 inline: 0363 @code 0364 BOOST_LOCAL_FUNCTION(inline recursive local_function_name) 0365 @endcode 0366 0367 @Note The local function name cannot be the name of an operator 0368 <c>operator...</c> and it cannot be the same name of another local function 0369 declared within the same enclosing scope (but <c>boost::overloaded_function</c> 0370 can be used to overload local functions, see 0371 Boost.Functional/OverloadedFunction and the 0372 @RefSect{advanced_topics, Advanced Topics} section). 0373 0374 @See @RefSect{tutorial, Tutorial} section, 0375 @RefSect{advanced_topics, Advanced Topics} section, 0376 @RefMacro{BOOST_LOCAL_FUNCTION}, 0377 @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL}. 0378 */ 0379 #define BOOST_LOCAL_FUNCTION_NAME(qualified_name) 0380 0381 /** 0382 @brief This macro is used to end a local function declaration specifying its 0383 name within templates. 0384 0385 This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION_NAME} when 0386 declaring a local function within a template. 0387 A part from that, this macro has the exact same syntax a 0388 @RefMacro{BOOST_LOCAL_FUNCTION_NAME} (see @RefMacro{BOOST_LOCAL_FUNCTION_NAME} 0389 for more information): 0390 @code 0391 { // Some declarative context within a template. 0392 ... 0393 result_type BOOST_LOCAL_FUNCTION_TPL(declarations) { 0394 ... // Body code. 0395 } BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name) 0396 ... 0397 } 0398 @endcode 0399 0400 Note that @RefMacro{BOOST_LOCAL_FUNCTION_TPL} must be used with this macro 0401 instead of @RefMacro{BOOST_LOCAL_FUNCTION}. 0402 0403 @Note C++03 does not allow to use <c>typename</c> outside templates. 0404 This library internally manipulates types, these operations require 0405 <c>typename</c> but only within templates. 0406 This macro is used to indicate to the library when the enclosing scope is a 0407 template so the library can correctly use <c>typename</c>. 0408 0409 @See @RefSect{tutorial, Tutorial} section, 0410 @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, @RefMacro{BOOST_LOCAL_FUNCTION_TPL}. 0411 */ 0412 #define BOOST_LOCAL_FUNCTION_NAME_TPL(name) 0413 0414 /** 0415 @brief This macro expands to the type of the specified bound variable. 0416 0417 This macro can be used within the local functions body to refer to the bound 0418 variable types so to declare local variables, check concepts (using 0419 Boost.ConceptCheck), etc (see the @RefSect{advanced_topics, Advanced Topics} 0420 section). 0421 This way the local function can be programmed entirely without explicitly 0422 specifying the bound variable types thus facilitating maintenance (e.g., if 0423 the type of a bound variable changes in the enclosing scope, the local function 0424 code does not have to change). 0425 0426 @Params 0427 @Param{bound_variable_name, 0428 The name of one of the local function's bound variables. 0429 } 0430 @EndParams 0431 0432 The type returned by the macro is fully qualified in that it contains the extra 0433 constant and reference qualifiers when the specified variable is bound by 0434 constant and by reference. 0435 For example, if a variable named <c>t</c> of type <c>T</c> is: 0436 @li Bound by value using <c>bind t</c> then 0437 <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>T</c>. 0438 @li Bound by constant value using <c>const bind t</c> then 0439 <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>const T</c>. 0440 @li Bound by reference using <c>bind& t</c> then 0441 <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>T&</c>. 0442 @li Bound by constant reference using <c>const bind& t</c> then 0443 <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>const T&</c>. 0444 0445 This macro must be prefixed by <c>typename</c> when used within templates. 0446 0447 @Note It is best to use this macro instead of Boost.Typeof so to reduce the 0448 number of times Boost.Typeof is used to deduce types (see the 0449 @RefSect{advanced_topics, Advanced Topics} section). 0450 0451 @See @RefSect{advanced_topics, Advanced Topics} section, 0452 @RefMacro{BOOST_LOCAL_FUNCTION}. 0453 */ 0454 #define BOOST_LOCAL_FUNCTION_TYPEOF(bound_variable_name) 0455 0456 #endif // DOXYGEN 0457 0458 #endif // #include guard 0459
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |