| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 | 
							
- // Copyright (C) 2009-2012 Lorenzo Caminiti
 
- // Distributed under the Boost Software License, Version 1.0
 
- // (see accompanying file LICENSE_1_0.txt or a copy at
 
- // http://www.boost.org/LICENSE_1_0.txt)
 
- // Home at http://www.boost.org/libs/local_function
 
- #ifndef BOOST_LOCAL_FUNCTION_HPP_
 
- #define BOOST_LOCAL_FUNCTION_HPP_
 
- #ifndef DOXYGEN
 
- #include <boost/local_function/aux_/macro/decl.hpp>
 
- #include <boost/local_function/aux_/macro/name.hpp>
 
- #include <boost/local_function/aux_/macro/typeof.hpp>
 
- #include <boost/local_function/aux_/preprocessor/traits/decl.hpp>
 
- #include <boost/local_function/detail/preprocessor/line_counter.hpp>
 
- #include <boost/local_function/detail/preprocessor/void_list.hpp>
 
- #include <boost/config.hpp>
 
- // PUBLIC //
 
- #ifdef BOOST_NO_CXX11_VARIADIC_MACROS
 
- #   define BOOST_LOCAL_FUNCTION_ID(id, declarations) \
 
-         BOOST_LOCAL_FUNCTION_AUX_DECL(id, 0 /* not within template */, \
 
-                 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \
 
-                         BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST( \
 
-                                 declarations)))
 
- #   define BOOST_LOCAL_FUNCTION(declarations) \
 
-         BOOST_LOCAL_FUNCTION_ID( \
 
-                 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, declarations)
 
- #   define BOOST_LOCAL_FUNCTION_ID_TPL(id, declarations) \
 
-         BOOST_LOCAL_FUNCTION_AUX_DECL(id, 1 /* within template */, \
 
-                 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \
 
-                         BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST( \
 
-                                 declarations)))
 
- #   define BOOST_LOCAL_FUNCTION_TPL(declarations) \
 
-         BOOST_LOCAL_FUNCTION_ID_TPL( \
 
-                 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, declarations)
 
- #else // VARIADIC
 
- #   define BOOST_LOCAL_FUNCTION_ID(id, ...) \
 
-         BOOST_LOCAL_FUNCTION_AUX_DECL(id, 0 /* not within template */, \
 
-                 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \
 
-                         BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__)))
 
- #   define BOOST_LOCAL_FUNCTION(...) \
 
-         BOOST_LOCAL_FUNCTION_ID( \
 
-                 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, __VA_ARGS__)
 
- #   define BOOST_LOCAL_FUNCTION_ID_TPL(id, ...) \
 
-         BOOST_LOCAL_FUNCTION_AUX_DECL(id, 1 /* within template */, \
 
-                 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS( \
 
-                         BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__)))
 
- #   define BOOST_LOCAL_FUNCTION_TPL(...) \
 
-         BOOST_LOCAL_FUNCTION_ID_TPL( \
 
-                 BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, __VA_ARGS__)
 
- #endif // VARIADIC
 
- #define BOOST_LOCAL_FUNCTION_NAME(qualified_name) \
 
-     BOOST_LOCAL_FUNCTION_AUX_NAME(0 /* not within template */, qualified_name)
 
- #define BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name) \
 
-     BOOST_LOCAL_FUNCTION_AUX_NAME(1 /* within template */, qualified_name)
 
- #define BOOST_LOCAL_FUNCTION_TYPEOF(bound_variable_name) \
 
-     BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE(bound_variable_name)
 
- // DOCUMENTATION //
 
- #else // DOXYGEN
 
- /** @file
 
- @brief Local functions allow to program functions locally, within other
 
- functions, and directly within the scope where they are needed.
 
- */
 
- /**
 
- @brief This macro is used to start a local function declaration.
 
- This macro must be used within a declarative context, it must follow the local
 
- function result type, it must be followed by the local function body code, and
 
- then by the @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro (see the
 
- @RefSect{tutorial, Tutorial} and @RefSect{advanced_topics, Advanced Topics}
 
- sections):
 
- @code
 
- { // Some declarative context.
 
-     ...
 
-     result_type BOOST_LOCAL_FUNCTION(declarations) {
 
-         ... // Body code.
 
-     } BOOST_LOCAL_FUNCTION_NAME(qualified_name)
 
-     ...
 
- }
 
- @endcode
 
- As usual, exceptions specifications can be optionally programmed just after the
 
- macro and before the body code block <c>{ ... }</c> (but the exception
 
- specifications will only apply to the body code and not to the library code
 
- automatically generated by the macro expansion, see the
 
- @RefSect{advanced_topics, Advanced Topics} section).
 
- Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_TPL}
 
- and @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used.
 
- @Params
 
- @Param{declarations,
 
- On compilers that support variadic macros\, the parameter declarations are
 
- defined by the following grammar:
 
- @code
 
-     declarations:
 
-             void | declaration_tuple | declaration_sequence
 
-     declaration_tuple:
 
-             declaration\, declaration\, ...
 
-     declaration_sequence:
 
-             (declaration) (declaration) ...
 
-     declaration:
 
-             bound_variable | parameter | default_value | result_type
 
-     bound_variable:
 
-             [const] bind [(variable_type)] [&] variable_name
 
-     parameter:
 
-             [auto | register] parameter_type parameter_name
 
-     default_value:
 
-             default parameter_default_value
 
-     result_type:
 
-             return function_result_type
 
- @endcode
 
- On compilers that do not support variadic macros\, <c>declaration_tuple</c>
 
- cannot be used:
 
- @code
 
-     declarations:
 
-             void | declaration_sequence
 
- @endcode
 
- (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
 
- <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
 
- <c>{expression}</c> means the token resulting from the expression.)
 
- }
 
- @EndParams
 
-  
 
- Note that on compilers that support variadic macros, commas can be used to
 
- separate the declarations resembling more closely the usual C++ function
 
- declaration syntax (this is the preferred syntax).
 
- However, for portability, on all C++ compilers (with and without variadic
 
- macros) the same library macros also accept parameter declarations specified as
 
- a Boost.Preprocessor sequence separated by round parenthesis <c>()</c>.
 
- When binding the object <c>this</c>, the special symbol <c>this_</c> needs to
 
- be used instead of <c>this</c> as the name of the variable to bind and also
 
- within the local function body to access the object.
 
- (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.)
 
- The result type must either be specified just before the macro or within the
 
- macro declarations prefixed by <c>return</c> (but not in both places).
 
- 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.
 
- The bound variable types can be accessed using @RefMacro{BOOST_LOCAL_FUNCTION_TYPEOF}.
 
- This macro cannot be portably expanded multiple times on the same line.
 
- In these cases, use the @RefMacro{BOOST_LOCAL_FUNCTION_ID} macro instead.
 
- The maximum number of local function parameters (excluding bound variables) is
 
- specified by the configuration macro
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX}.
 
- The maximum number of bound variables is specified by the configuration macro
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX}.
 
- The configuration macro
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS} can be used to force
 
- optimizations that reduce the local function call run-time overhead.
 
- @Note Local functions are functors so they can be assigned to other functors
 
- like <c>boost::function</c> (see Boost.Function).
 
- @See @RefSect{tutorial, Tutorial} section,
 
- @RefSect{advanced_topics, Advanced Topics} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, @RefMacro{BOOST_LOCAL_FUNCTION_TPL},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_TYPEOF}, @RefMacro{BOOST_LOCAL_FUNCTION_ID},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION(declarations)
 
- /**
 
- @brief This macro is used to start a local function declaration within
 
- templates.
 
- This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION} when
 
- declaring a local function within a template.
 
- A part from that, this macro has the exact same syntax a
 
- @RefMacro{BOOST_LOCAL_FUNCTION} (see @RefMacro{BOOST_LOCAL_FUNCTION} for more
 
- information):
 
- @code
 
- { // Some declarative context within a template.
 
-     ...
 
-     result_type BOOST_LOCAL_FUNCTION_TPL(declarations) {
 
-         ... // Body code.
 
-     } BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name)
 
-     ...
 
- }
 
- @endcode
 
- Note that @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used with this
 
- macro instead of @RefMacro{BOOST_LOCAL_FUNCTION_NAME}.
 
- This macro cannot be portably expanded multiple times on the same line.
 
- In these cases, use the @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL} macro instead.
 
- @Note C++03 does not allow to use <c>typename</c> outside templates.
 
- This library internally manipulates types, these operations require
 
- <c>typename</c> but only within templates.
 
- This macro is used to indicate to the library when the enclosing scope is a
 
- template so the library can correctly use <c>typename</c>.
 
- @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_LOCAL_FUNCTION},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_TPL(declarations)
 
- /**
 
- @brief This macro allows to declare multiple local functions on the same line.
 
- This macro is equivalent to @RefMacro{BOOST_LOCAL_FUNCTION} but it can be
 
- expanded multiple times on the same line if different identifiers <c>id</c> are
 
- provided for each expansion (see the
 
- @RefSect{advanced_topics, Advanced Topics} section).
 
- @Params
 
- @Param{id,
 
- A unique identifier token which can be concatenated by the preprocessor
 
- (<c>__LINE__</c>\, <c>local_function_number_1_on_line_123</c>\, etc).
 
- }
 
- @Param{declarations,
 
- Same as the <c>declarations</c> parameter of the
 
- @RefMacro{BOOST_LOCAL_FUNCTION} macro.
 
- }
 
- @EndParams
 
- The @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro should be used to end each one
 
- of the multiple local function declarations as usual (and it will specify a
 
- unique name for each local function).
 
- Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL}
 
- must be used.
 
- @Note This macro can be useful when the local function macros are expanded
 
- within user-defined macros (because macros all expand on the same line).
 
- On some compilers (e.g., MSVC which supports the non-standard
 
- <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
 
- the use of this macro when expanding multiple local function macros on the same
 
- line is always necessary to ensure portability (this is because this library
 
- can only portably use <c>__LINE__</c> to internally generate unique
 
- identifiers).
 
- @See @RefSect{advanced_topics, Advanced Topics} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION}, @RefMacro{BOOST_LOCAL_FUNCTION_NAME},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_ID_TPL}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_ID(id, declarations)
 
- /**
 
- @brief This macro allows to declare multiple local functions on the same line
 
- within templates.
 
- This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION_TPL} when
 
- declaring multiple local functions on the same line within a template.
 
- A part from that, this macro has the exact same syntax as
 
- @RefMacro{BOOST_LOCAL_FUNCTION_TPL} (see @RefMacro{BOOST_LOCAL_FUNCTION_TPL}
 
- for more information).
 
- @Params
 
- @Param{id,
 
- A unique identifier token which can be concatenated by the preprocessor
 
- (<c>__LINE__</c>\, <c>local_function_number_1_on_line_123</c>\, etc).
 
- }
 
- @Param{declarations,
 
- Same as the <c>declarations</c> parameter of the
 
- @RefMacro{BOOST_LOCAL_FUNCTION_TPL} macro.
 
- }
 
- @EndParams
 
- The @RefMacro{BOOST_LOCAL_FUNCTION_NAME} macro should be used to end each one
 
- of the multiple local function declarations as usual (and it will specify a
 
- unique name for each local function).
 
- Outside template, the macro @RefMacro{BOOST_LOCAL_FUNCTION_ID} should be used
 
- to declare multiple local functions on the same line.
 
- @Note This macro can be useful when the local function macros are expanded
 
- within user-defined macros (because macros all expand on the same line).
 
- On some compilers (e.g., MSVC which supports the non-standard
 
- <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
 
- the use of this macro when expanding multiple local function macros on the same
 
- line is always necessary to ensure portability (this is because this library
 
- can only portably use <c>__LINE__</c> to internally generate unique
 
- identifiers).
 
- @See @RefSect{advanced_topics, Advanced Topics} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION_TPL}, @RefMacro{BOOST_LOCAL_FUNCTION_NAME},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_ID}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_ID_TPL(id, declarations)
 
- /**
 
- @brief This macro is used to end a local function declaration specifying its
 
- name.
 
- This macro must follow the local function body code block <c>{ ... }</c>:
 
- @code
 
- { // Some declarative context.
 
-     ...
 
-     result_type BOOST_LOCAL_FUNCTION(declarations) {
 
-         ... // Body code.
 
-     } BOOST_LOCAL_FUNCTION_NAME(qualified_name)
 
-     ...
 
- }
 
- @endcode
 
- Within templates, the special macros @RefMacro{BOOST_LOCAL_FUNCTION_TPL} and
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL} must be used.
 
- @Params
 
- @Param{qualified_name,
 
- The name of the local function optionally qualified as follow:
 
- @code
 
-     name:
 
-             [inline] [recursive] local_function_name
 
- @endcode
 
- (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
 
- <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
 
- <c>{expression}</c> means the token resulting from the expression.)
 
- }
 
- @EndParams
 
- The local function name can be qualified by prefixing it with the keyword
 
- <c>inline</c> (see the @RefSect{advanced_topics, Advanced Topics} section):
 
- @code
 
-     BOOST_LOCAL_FUNCTION_NAME(inline local_function_name)
 
- @endcode
 
- This increases the chances that the compiler will be able to inline the local
 
- function calls (thus reducing run-time).
 
- 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
 
- <c>boost::function</c>).
 
- That is true on C++03 compilers but inline local functions can instead be
 
- passed as template parameters on C++11 compilers.
 
- On C++11 compilers, there is no need to declare a local function lined because
 
- this library will automatically use C++11 specific features to inline the local
 
- function while always allowing to pass it as a template parameter.
 
- This optimization is automatically enabled when the Boost.Config macro
 
- <c>BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</c> is not defined but it also be
 
- forced using @RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS}.
 
- The local function name can also be qualified by prefixing it with the
 
- "keyword" <c>recursive</c> (see the
 
- @RefSect{advanced_topics, Advanced Topics} section):
 
- @code
 
-     BOOST_LOCAL_FUNCTION_NAME(recursive local_function_name)
 
- @endcode
 
- This allows the local function to recursively call itself from its body (as
 
- usual in C++).
 
- However, recursive local functions should only be called within their
 
- declaration scope (otherwise the result is undefined behaviour).
 
- Finally, compilers have not been observed to be able to inline recursive local
 
- function calls, not even when the recursive local function is also declared
 
- inline:
 
- @code
 
-     BOOST_LOCAL_FUNCTION(inline recursive local_function_name)
 
- @endcode
 
- @Note The local function name cannot be the name of an operator
 
- <c>operator...</c> and it cannot be the same name of another local function
 
- declared within the same enclosing scope (but <c>boost::overloaded_function</c>
 
- can be used to overload local functions, see
 
- Boost.Functional/OverloadedFunction and the
 
- @RefSect{advanced_topics, Advanced Topics} section).
 
- @See @RefSect{tutorial, Tutorial} section,
 
- @RefSect{advanced_topics, Advanced Topics} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION},
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME_TPL}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_NAME(qualified_name)
 
- /**
 
- @brief This macro is used to end a local function declaration specifying its
 
- name within templates.
 
- This macro must be used instead of @RefMacro{BOOST_LOCAL_FUNCTION_NAME} when
 
- declaring a local function within a template.
 
- A part from that, this macro has the exact same syntax a
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME} (see @RefMacro{BOOST_LOCAL_FUNCTION_NAME}
 
- for more information):
 
- @code
 
- { // Some declarative context within a template.
 
-     ...
 
-     result_type BOOST_LOCAL_FUNCTION_TPL(declarations) {
 
-         ... // Body code.
 
-     } BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_name)
 
-     ...
 
- }
 
- @endcode
 
- Note that @RefMacro{BOOST_LOCAL_FUNCTION_TPL} must be used with this macro
 
- instead of @RefMacro{BOOST_LOCAL_FUNCTION}.
 
- @Note C++03 does not allow to use <c>typename</c> outside templates.
 
- This library internally manipulates types, these operations require
 
- <c>typename</c> but only within templates.
 
- This macro is used to indicate to the library when the enclosing scope is a
 
- template so the library can correctly use <c>typename</c>.
 
- @See @RefSect{tutorial, Tutorial} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION_NAME}, @RefMacro{BOOST_LOCAL_FUNCTION_TPL}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_NAME_TPL(name)
 
- /**
 
- @brief This macro expands to the type of the specified bound variable.
 
- This macro can be used within the local functions body to refer to the bound
 
- variable types so to declare local variables, check concepts (using
 
- Boost.ConceptCheck), etc (see the @RefSect{advanced_topics, Advanced Topics}
 
- section).
 
- This way the local function can be programmed entirely without explicitly
 
- specifying the bound variable types thus facilitating maintenance (e.g., if
 
- the type of a bound variable changes in the enclosing scope, the local function
 
- code does not have to change).
 
- @Params
 
- @Param{bound_variable_name,
 
- The name of one of the local function's bound variables.
 
- }
 
- @EndParams
 
- The type returned by the macro is fully qualified in that it contains the extra
 
- constant and reference qualifiers when the specified variable is bound by
 
- constant and by reference.
 
- For example, if a variable named <c>t</c> of type <c>T</c> is:
 
- @li Bound by value using <c>bind t</c> then
 
- <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>T</c>.
 
- @li Bound by constant value using <c>const bind t</c> then
 
- <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>const T</c>.
 
- @li Bound by reference using <c>bind& t</c> then
 
- <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>T&</c>.
 
- @li Bound by constant reference using <c>const bind& t</c> then
 
- <c>BOOST_LOCAL_FUNCTION_TYPEOF(t)</c> is <c>const T&</c>.
 
- This macro must be prefixed by <c>typename</c> when used within templates.
 
- @Note It is best to use this macro instead of Boost.Typeof so to reduce the
 
- number of times Boost.Typeof is used to deduce types (see the
 
- @RefSect{advanced_topics, Advanced Topics} section).
 
- @See @RefSect{advanced_topics, Advanced Topics} section,
 
- @RefMacro{BOOST_LOCAL_FUNCTION}.
 
- */
 
- #define BOOST_LOCAL_FUNCTION_TYPEOF(bound_variable_name)
 
- #endif // DOXYGEN
 
- #endif // #include guard
 
 
  |