diff options
Diffstat (limited to 'boost/local_function')
49 files changed, 4292 insertions, 0 deletions
diff --git a/boost/local_function/aux_/add_pointed_const.hpp b/boost/local_function/aux_/add_pointed_const.hpp new file mode 100644 index 0000000000..9cd7aa6375 --- /dev/null +++ b/boost/local_function/aux_/add_pointed_const.hpp @@ -0,0 +1,33 @@ + +// 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_AUX_ADD_POINTED_CONST_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_ADD_POINTED_CONST_HPP_ + +namespace boost { namespace local_function { namespace aux { + +// Metafunction to add const to pointed type `T` (i.e. converts +// `T* [const]` to `T const* [const]`). `boost::add_const<>` cannot be used +// instead because only adds outer const. + +template<typename T> struct add_pointed_const { typedef T type; }; + +template<typename T> struct add_pointed_const<T*> { typedef T const* type; }; + +template<typename T> struct add_pointed_const<T const*> + { typedef T const* type; }; + +template<typename T> struct add_pointed_const<T* const> + { typedef T const* const type; }; + +template<typename T> struct add_pointed_const<T const* const> + { typedef T const* const type; }; + +} } } // namespace + +#endif //#include guard + diff --git a/boost/local_function/aux_/function.hpp b/boost/local_function/aux_/function.hpp new file mode 100644 index 0000000000..e6de939743 --- /dev/null +++ b/boost/local_function/aux_/function.hpp @@ -0,0 +1,330 @@ + +// 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 + +#if !BOOST_PP_IS_ITERATING +# ifndef BOOST_LOCAL_FUNCTION_AUX_FUNCTION_HPP_ +# define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_HPP_ + +# include <boost/local_function/config.hpp> +# include <boost/local_function/aux_/member.hpp> +# include <boost/call_traits.hpp> +# include <boost/typeof/typeof.hpp> +# include <boost/config.hpp> +# include <boost/preprocessor/iteration/iterate.hpp> +# include <boost/preprocessor/repetition/repeat.hpp> +# include <boost/preprocessor/repetition/enum.hpp> +# include <boost/preprocessor/punctuation/comma_if.hpp> +# include <boost/preprocessor/arithmetic/add.hpp> +# include <boost/preprocessor/arithmetic/sub.hpp> +# include <boost/preprocessor/arithmetic/inc.hpp> +# include <boost/preprocessor/control/iif.hpp> +# include <boost/preprocessor/cat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_ \ + "boost/local_function/aux_/function.hpp" + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_call) ) + +#define BOOST_LOCAL_FUNCTION_AUX_typename_seq(z, n, unused) \ + (typename) + +#define BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, unused) \ + BOOST_PP_CAT(Arg, arg_n) + +#define BOOST_LOCAL_FUNCTION_AUX_arg_typedef(z, arg_n, unused) \ + typedef \ + BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~) \ + /* name must follow Boost.FunctionTraits arg1_type, arg2_type, ... */ \ + BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(arg_n)), _type) \ + ; + +#define BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam(z, arg_n, unused) \ + , typename BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_arg_param_type(z, arg_n, comma01) \ + BOOST_PP_COMMA_IF(comma01) \ + typename ::boost::call_traits< \ + BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~) \ + >::param_type + +#define BOOST_LOCAL_FUNCTION_AUX_arg_name(z, arg_n, comma01) \ + BOOST_PP_COMMA_IF(comma01) \ + BOOST_PP_CAT(arg, arg_n) + +#define BOOST_LOCAL_FUNCTION_AUX_arg_param_decl(z, arg_n, unused) \ + BOOST_LOCAL_FUNCTION_AUX_arg_param_type(z, arg_n, 0 /* no leading comma */)\ + BOOST_LOCAL_FUNCTION_AUX_arg_name(z, arg_n, 0 /* no leading comma */) + +#define BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, unused) \ + BOOST_PP_CAT(Bind, bind_n) + +#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_type(z, bind_n, unused) \ + , BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref(z, bind_n, unused) \ + , BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) & + +#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam(z, bind_n, unused) \ + , typename BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, unused) \ + BOOST_PP_CAT(bing, bind_n) + +#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl(z, bind_n, unused) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) & \ + BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, unsued) \ + BOOST_PP_CAT(BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~), _) + +#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref(z, bind_n, unsued) \ + , member_deref< BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) >( \ + BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~)) + +#define BOOST_LOCAL_FUNCTION_AUX_bind_member_init(z, bind_n, unused) \ + BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~) = member_addr( \ + BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~)); + +#define BOOST_LOCAL_FUNCTION_AUX_bind_member_decl(z, bind_n, unused) \ + /* must be ptr (not ref) so can use default constr */ \ + typename member_type< \ + BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) \ + >::pointer BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~) ; + +#define BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, unused) \ + BOOST_PP_CAT(call_ptr, n) + +#define BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, unused) \ + BOOST_PP_CAT(call, n) + +#define BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, unused) \ + BOOST_PP_CAT(BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, unused), _) + +#define BOOST_LOCAL_FUNCTION_AUX_call_typedef(z, n, arity) \ + typedef R (*BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~))( \ + object_ptr \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \ + BOOST_PP_TUPLE_EAT(3) \ + , \ + BOOST_PP_REPEAT_ ## z \ + )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref, ~) \ + BOOST_PP_REPEAT_ ## z(BOOST_PP_SUB(arity, n), \ + BOOST_LOCAL_FUNCTION_AUX_arg_param_type, 1 /* leading comma */)\ + ); + +#define BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl(z, n, unused) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~) \ + BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_call_decl(z, n, unused) \ + BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~) \ + BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, ~); + +#define BOOST_LOCAL_FUNCTION_AUX_call_init(z, n, unused) \ + BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, ~) = \ + BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, ~); + +#define BOOST_LOCAL_FUNCTION_AUX_operator_call(z, defaults_n, arity) \ + /* precondition: object_ && call_function_ */ \ + inline R operator()( \ + BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \ + BOOST_LOCAL_FUNCTION_AUX_arg_param_decl, ~) \ + ) /* cannot be const because of binds (same as for local ftor) */ { \ + /* run-time: do not assert preconditions here for efficiency */ \ + /* run-time: this function call is done via a function pointer */ \ + /* so unfortunately does not allow for compiler inlining */ \ + /* optimizations (an alternative using virtual function was also */ \ + /* investigated but also virtual functions cannot be optimized */ \ + /* plus they require virtual table lookups to the alternative */ \ + /* performed worst) */ \ + return BOOST_LOCAL_FUNCTION_AUX_call_member(z, defaults_n, ~)( \ + object_ \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\ + BOOST_PP_TUPLE_EAT(3) \ + , \ + BOOST_PP_REPEAT_ ## z \ + )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref, ~) \ + BOOST_PP_REPEAT_ ## z(BOOST_PP_SUB(arity, defaults_n), \ + BOOST_LOCAL_FUNCTION_AUX_arg_name, 1 /* leading comma */) \ + ); \ + } + +namespace boost { namespace local_function { namespace aux { + +template< + typename F + , size_t defaults +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam, ~) +#endif +> +class function {}; // Empty template, only use its specializations. + +// Iterate within namespace. +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_LOCAL_FUNCTION_CONFIG_FUNCTION_ARITY_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_)) +# include BOOST_PP_ITERATE() // Iterate over function arity. + +} } } // namespace + +// Register type for type-of emu (NAME use TYPEOF to deduce this fctor type). +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::local_function::aux::function, + (typename) // For `F` tparam. + (size_t) // For `defaults` tparam. + // MSVC error if using #if instead of PP_IIF here. + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, + BOOST_PP_TUPLE_EAT(3) // Nothing. + , + BOOST_PP_REPEAT // For bind tparams. + )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_typename_seq, ~) +) + +#undef BOOST_LOCAL_FUNCTION_AUX_typename_seq +#undef BOOST_LOCAL_FUNCTION_AUX_arg_type +#undef BOOST_LOCAL_FUNCTION_AUX_arg_typedef +#undef BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam +#undef BOOST_LOCAL_FUNCTION_AUX_arg_param_type +#undef BOOST_LOCAL_FUNCTION_AUX_arg_name +#undef BOOST_LOCAL_FUNCTION_AUX_arg_param_decl +#undef BOOST_LOCAL_FUNCTION_AUX_bind_type +#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_type +#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref +#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam +#undef BOOST_LOCAL_FUNCTION_AUX_bind_name +#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl +#undef BOOST_LOCAL_FUNCTION_AUX_bind_member +#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref +#undef BOOST_LOCAL_FUNCTION_AUX_bind_member_init +#undef BOOST_LOCAL_FUNCTION_AUX_bind_member_decl +#undef BOOST_LOCAL_FUNCTION_AUX_call_ptr +#undef BOOST_LOCAL_FUNCTION_AUX_call_name +#undef BOOST_LOCAL_FUNCTION_AUX_call_member +#undef BOOST_LOCAL_FUNCTION_AUX_call_typedef +#undef BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl +#undef BOOST_LOCAL_FUNCTION_AUX_call_decl +#undef BOOST_LOCAL_FUNCTION_AUX_call_init +#undef BOOST_LOCAL_FUNCTION_AUX_operator_call + +# endif // #include guard + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +# define BOOST_LOCAL_FUNCTION_AUX_arity BOOST_PP_FRAME_ITERATION(1) +# define BOOST_PP_ITERATION_PARAMS_2 \ + (3, (0, BOOST_LOCAL_FUNCTION_AUX_arity, \ + BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_)) +# include BOOST_PP_ITERATE() // Iterate over default params count. +# undef BOOST_LOCAL_FUNCTION_AUX_arity + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# define BOOST_LOCAL_FUNCTION_AUX_defaults BOOST_PP_FRAME_ITERATION(2) + +template< + typename R + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_AUX_arity, + BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam, ~) +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam, ~) +#endif +> +class function< + R ( + BOOST_PP_ENUM(BOOST_LOCAL_FUNCTION_AUX_arity, + BOOST_LOCAL_FUNCTION_AUX_arg_type, ~) + ) + , BOOST_LOCAL_FUNCTION_AUX_defaults +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_comma_bind_type, ~) +#endif +> { + // The object type will actually be a local class which cannot be passed as + // a template parameter so a generic `void*` pointer is used to hold the + // object (this pointer will then be cased by the call-function implemented + // by the local class itself). This is the trick used to pass a local + // function as a template parameter. This trick uses function pointers for + // the call-functions and function pointers cannot always be optimized by + // the compiler (they cannot be inlined) thus this trick increased run-time + // (another trick using virtual functions for the local class was also + // investigated but also virtual functions cannot be inlined plus they + // require virtual tables lookups so the virtual functions trick measured + // worst run-time performance than the function pointer trick). + typedef void* object_ptr; + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults), + BOOST_LOCAL_FUNCTION_AUX_call_typedef, // INC for no defaults. + BOOST_LOCAL_FUNCTION_AUX_arity) + +public: + // Provide public type interface following Boost.Function names + // (traits must be defined in both this and the local functor). + BOOST_STATIC_CONSTANT(size_t, arity = BOOST_LOCAL_FUNCTION_AUX_arity); + typedef R result_type; + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_AUX_arity, + BOOST_LOCAL_FUNCTION_AUX_arg_typedef, ~) + + // NOTE: Must have default constructor for init without function name in + // function macro expansion. + + // Cannot be private but it should never be used by programmers directly + // so used internal symbol. + inline void BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( + object_ptr object +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl, ~) +#endif + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults), + BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl, ~) + ) { + object_ = object; +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_bind_member_init, ~) +#endif + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults), + BOOST_LOCAL_FUNCTION_AUX_call_init, ~) // INC for no defaults. + unused_ = 0; // To avoid a GCC uninitialized warning. + } + + // Result operator(Arg1, ..., ArgN-1, ArgN) -- iff defaults >= 0 + // Result operator(Arg1, ..., ArgN-1) -- iff defaults >= 1 + // ... -- etc + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults), + BOOST_LOCAL_FUNCTION_AUX_operator_call, // INC for no defaults. + BOOST_LOCAL_FUNCTION_AUX_arity) + +private: + object_ptr object_; +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, + BOOST_LOCAL_FUNCTION_AUX_bind_member_decl, ~) +#endif + BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults), + BOOST_LOCAL_FUNCTION_AUX_call_decl, ~) // INC for no defaults. + + // run-time: this unused void* member variable allows for compiler + // optimizations (at least on MSVC it reduces invocation time of about 50%) + void* unused_; +}; + +# undef BOOST_LOCAL_FUNCTION_AUX_defaults +#endif // iteration + diff --git a/boost/local_function/aux_/macro/code_/bind.hpp b/boost/local_function/aux_/macro/code_/bind.hpp new file mode 100644 index 0000000000..b235e7384b --- /dev/null +++ b/boost/local_function/aux_/macro/code_/bind.hpp @@ -0,0 +1,252 @@ + +// 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_AUX_CODE_BIND_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_HPP_ + +#include <boost/local_function/aux_/symbol.hpp> +#include <boost/local_function/aux_/macro/decl.hpp> +#include <boost/local_function/aux_/preprocessor/traits/bind.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp> +#include <boost/utility/identity_type.hpp> +#include <boost/scope_exit.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/function_traits.hpp> +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/facilities/identity.hpp> +#include <boost/preprocessor/logical/bitand.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/list/for_each_i.hpp> +#include <boost/preprocessor/list/append.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAMS_VAR_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (params)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_TAG_DECL_(r, id, i, bind_traits) \ + BOOST_SCOPE_EXIT_DETAIL_TAG_DECL(r, id, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_TYPED_( \ + r, id, typename01, i, bind_traits) \ + typedef BOOST_PP_EXPR_IIF(typename01, typename) \ + /* remove ref because typed var can have & prefix */ \ + ::boost::remove_reference< BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::function_traits< \ + /* instead of using Boost.Typeof, get bind type as 1st */ \ + /* argument type of func type `void (type_ [&] var_)` */ \ + void ( BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITH_TYPE( \ + bind_traits) ) \ + >::arg1_type \ + >::type \ + BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(id, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) \ + ; /* close typedef */ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_DEDUCED_( \ + r, id, typename01, i, bind_traits) \ + BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, \ + ( \ + id \ + , \ + /* ScopeExit expects typename or EMPTY() here */ \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ), \ + i, BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_( \ + r, id_typename, i, bind_traits) \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITH_TYPE(bind_traits)), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_DEDUCED_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_TYPED_ \ + )(r, BOOST_PP_TUPLE_ELEM(2, 0, id_typename), \ + BOOST_PP_TUPLE_ELEM(2, 1, id_typename), i, bind_traits) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAM_DECL_( \ + r, id_typename, i, bind_traits) \ + BOOST_SCOPE_EXIT_DETAIL_PARAM_DECL(r, \ + ( \ + BOOST_PP_TUPLE_ELEM(2, 0, id_typename) \ + , \ + /* ScopeExit expects typename or EMPTY() here */ \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(2, 1, id_typename), \ + typename \ + ) \ + ), \ + i, BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_MEMBER_DECL_VAR_( \ + r, id, typename01, i, var) \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_IDENTITY_TYPE(( /* must use IDENTITY because of tparam comma */ \ + ::boost::scope_exit::detail::member< \ + BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var) \ + , BOOST_SCOPE_EXIT_DETAIL_TAG(id, i) \ + > \ + )) \ + BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var); + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_MEMBER_DECL_( \ + r, id_typename, i, bind_traits) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_MEMBER_DECL_VAR_(r, \ + BOOST_PP_TUPLE_ELEM(2, 0, id_typename), \ + BOOST_PP_TUPLE_ELEM(2, 1, id_typename), \ + i, BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAM_INIT_(r, id, i, bind_traits) \ + BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT(r, id, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_CAPTURE_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (this_capture_type)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (this_type)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_DEDUCED_( \ + id, typename01, all_bind_this_types) \ + BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, \ + BOOST_PP_EXPR_IIF(typename01, typename), /* otherwise EMPTY() */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_CAPTURE_TYPE_(id)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_TYPED_( \ + id, typename01, all_bind_this_types) \ + typedef \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_THIS_TYPE(BOOST_PP_LIST_FIRST( \ + all_bind_this_types)) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_CAPTURE_TYPE_(id) \ + ; + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_( \ + id, typename01, all_bind_this_types) \ + /* typedef type_ */ \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \ + /* all_bind_this_type is list with 1 elem (possibly PP_EMPTY), */ \ + /* otherwise got a pp-parsing error before getting here */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_THIS_TYPE( \ + BOOST_PP_LIST_FIRST(all_bind_this_types))), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_DEDUCED_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_TYPED_ \ + )(id, typename01, all_bind_this_types) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_ALL_( \ + all_binds, all_bind_this_types, id, typename01) \ + /* binding tags */ \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(all_bind_this_types), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPEDEF_ \ + , \ + BOOST_PP_TUPLE_EAT(3) \ + )(id, typename01, all_bind_this_types) \ + BOOST_PP_LIST_FOR_EACH_I(BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_TAG_DECL_, id, \ + all_binds) \ + BOOST_PP_LIST_FOR_EACH_I(BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_CAPTURE_DECL_, \ + (id, typename01), all_binds) \ + /* binding class */ \ + struct BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id) { \ + /* interim capture types to workaround internal error on old GCC */ \ + BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(all_bind_this_types), \ + typedef BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_CAPTURE_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE_(id) ; \ + ) \ + BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(all_bind_this_types), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_VAR; \ + ) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAM_DECL_, \ + (id, typename01), all_binds) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_MEMBER_DECL_, \ + (id, typename01), all_binds) \ + } BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAMS_VAR_(id) = \ + /* NOTE: there is no way to wrap member initializer commas within */ \ + /* parenthesis so you must handle these commas manually if expanding */ \ + /* this macro within another macro */ \ + { \ + /* initialize the struct with param values to bind */ \ + BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(all_bind_this_types), \ + this) /* here name `this` access object at enclosing scope */ \ + BOOST_PP_COMMA_IF(BOOST_PP_BITAND( \ + BOOST_PP_LIST_IS_CONS(all_bind_this_types) \ + , BOOST_PP_LIST_IS_CONS(all_binds) \ + )) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAM_INIT_, id, all_binds) \ + }; + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_(id, typename01, decl_traits) \ + /* IMPORTANT: the order of these appends is important, it must follow */ \ + /* the indexing order used by the functor code which starts */ \ + /* enumerating const binds and then non-const binds */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_ALL_( \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS( \ + decl_traits),\ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS( \ + decl_traits)), \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES(decl_traits), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES( \ + decl_traits)), \ + id, typename01) + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id):: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE_(id) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_VAR \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (this_var) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_BIND(id, typename01, decl_traits) \ + /* the binding data structures must be declared and initialized (to */ \ + /* empty structs, so hopefully the compiler will optimize away the */ \ + /* no-op code) even when there is no bound param because these structs */ \ + /* are used to init `...args.value` which is always used by the `END` */ \ + /* macro later because this macro does not know if there are bound */ \ + /* params or not */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_(id, typename01, decl_traits) \ + /* this code takes advantage of the template argument list/comparison */ \ + /* operator ambiguity to declare a variable iff it hasn't already been */ \ + /* declared in that scope; the second occurrence is parsed as: */ \ + /* (declared<(resolve<sizeof(boost_local_auxXargs)>::cmp1<0)>::cmp2> */ \ + /* ...Xargs); */ \ + /* which is a no-op */ \ + ::boost::scope_exit::detail::declared< boost::scope_exit::detail::resolve< \ + /* cannot prefix with `::` as in `sizeof(:: ...` because the name */ \ + /* must refer to the local variable name to allow multiple local */ \ + /* functions (and exits) within the same scope (however this */ \ + /* does not allow for nesting because local variables cannot be */ \ + /* used in nested code blocks) */ \ + sizeof(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR) \ + >::cmp1<0>::cmp2 > BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR; \ + /* stores bound types/values into `...args` variable (args variable */ \ + /* can be accessed by `NAME` macro because doesn't use __LINE__ id) */ \ + BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value = \ + &BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_PARAMS_VAR_(id); + +#endif // #include guard + diff --git a/boost/local_function/aux_/macro/code_/functor.hpp b/boost/local_function/aux_/macro/code_/functor.hpp new file mode 100644 index 0000000000..cc34946260 --- /dev/null +++ b/boost/local_function/aux_/macro/code_/functor.hpp @@ -0,0 +1,892 @@ + +// 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_AUX_CODE_FUNCTOR_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_HPP_ + +#include <boost/local_function/config.hpp> +#include <boost/local_function/aux_/symbol.hpp> +#include <boost/local_function/aux_/function.hpp> +#include <boost/local_function/aux_/add_pointed_const.hpp> +#include <boost/local_function/aux_/member.hpp> +#include <boost/local_function/aux_/nobind.hpp> +#include <boost/local_function/aux_/macro/decl.hpp> +#include <boost/local_function/aux_/macro/typeof.hpp> +#include <boost/local_function/aux_/macro/code_/result.hpp> +#include <boost/local_function/aux_/macro/code_/bind.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_params.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp> +#include <boost/local_function/detail/preprocessor/keyword/auto.hpp> +#include <boost/local_function/detail/preprocessor/keyword/register.hpp> +#include <boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp> +#include <boost/utility/identity_type.hpp> +#include <boost/scope_exit.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/expand.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/facilities/identity.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/repeat.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/arithmetic/sub.hpp> +#include <boost/preprocessor/arithmetic/add.hpp> +#include <boost/preprocessor/logical/bitor.hpp> +#include <boost/preprocessor/logical/bitand.hpp> +#include <boost/preprocessor/logical/compl.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/tuple/rem.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/list/size.hpp> +#include <boost/preprocessor/list/for_each_i.hpp> +#include <boost/preprocessor/list/first_n.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (functor)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (function_type) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (body) ) + +// Unbind parameters. + +// i: 1 for 1st param, 2 for 2nd, ... (start from 1 not 0). +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(i) \ + /* this must be a generic parameter name because type and name */ \ + /* are not separate tokens in the macro syntax so name is not available */ \ + /* separately from its type */ \ + BOOST_PP_CAT(arg, i) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_( \ + r, unused, i, param_traits) \ + BOOST_PP_COMMA_IF(i) /* enumeration commas */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(BOOST_PP_INC(i)) + +// i: 1 for 1st param, 2 for 2nd, ... (start from 1 not 0). +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, i) \ + /* the parameter type must be accessed using function traits from */ \ + /* function type because it is not available to the macro syntax */ \ + /* separately from the parameter name */ \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::function_traits< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \ + >::BOOST_PP_CAT(BOOST_PP_CAT(arg, i), _type) \ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_ARG_TYPEDEF_( \ + r, typename01, i, param_traits) \ + typedef \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, \ + BOOST_PP_INC(i)) \ + /* name must follow Boost.FunctionTraits arg1_type, arg2_type, ... */ \ + BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(i)), _type) \ + ; + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_( \ + r, typename01, i, param_traits) \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::call_traits< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, \ + BOOST_PP_INC(i)) \ + >::param_type \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(BOOST_PP_INC(i)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_ENUM_( \ + r, typename01, i, param_traits) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_(r, typename01, i, \ + param_traits) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_PARAM_ARG_DECL_( \ + r, typename01, i, param_traits) \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_(r, typename01, i, \ + param_traits) + +// Precondition: !EMPTY(DEFAULT(param_traits)) +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DEFAULT_ASSIGNMENT_( \ + param_traits) \ + = BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_( \ + r, default01, i, param_traits) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_BACK( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_BACK( \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DECL(param_traits) \ + )) \ + BOOST_PP_IIF(BOOST_PP_COMPL(default01), \ + BOOST_PP_TUPLE_EAT(1) /* without default */ \ + , BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits)), \ + BOOST_PP_TUPLE_EAT(1) /* has no default */ \ + , /* else, with default and has default */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DEFAULT_ASSIGNMENT_ \ + ))(param_traits) + +// Bound parameters. + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_ \ + bind_params /* constructor void* param */ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_(i) \ + /* named `bind0`, `bind1`, ... */ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (bind)(i) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (bind_this) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BIND_MEMBER_THIS_( \ + id) \ + , static_cast< BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)* >( \ + object)->BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPE_( \ + id, typename01, offset, i, bind_var_without_type) \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id):: \ + BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, BOOST_PP_ADD(i, offset), \ + bind_var_without_type) \ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_( \ + r, offset, i, bind_traits) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \ + BOOST_PP_ADD(offset, i)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \ + r, id_typename_offset_const, i, bind_var_without_type) \ + /* IMPORTANT: here can't use `PP_KEYWORD_IS_THISUNDERSCORE_FRONT()` */ \ + /* because some `param_name` might start with non-alphanumeric symbol */ \ + /* `&` (but that is never the case for `this`) */ \ + BOOST_PP_IIF(BOOST_PP_COMPL(BOOST_PP_TUPLE_ELEM(4, 3, \ + id_typename_offset_const)), \ + BOOST_PP_EMPTY \ + , BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK( \ + bind_var_without_type), \ + /* pointed obj const */ \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \ + typename \ + ) \ + BOOST_PP_IDENTITY( ::boost::local_function::aux::add_pointed_const< ) \ + , \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \ + typename \ + ) \ + BOOST_PP_IDENTITY( ::boost::add_const< ) /* outer type const */ \ + ))() \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPE_( \ + BOOST_PP_TUPLE_ELEM(4, 0, id_typename_offset_const), \ + BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \ + BOOST_PP_TUPLE_ELEM(4, 2, id_typename_offset_const), \ + i, bind_var_without_type) \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 3, id_typename_offset_const), \ + >::type \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \ + r, id_typename_offset_const, i, bind_var_without_type) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \ + r, id_typename_offset_const, i, bind_var_without_type) \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK( \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_var_without_type)), \ + this_ BOOST_PP_TUPLE_EAT(1) \ + , \ + BOOST_PP_TUPLE_REM(1) \ + )(bind_var_without_type) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_( \ + r, id_typename_offset_const, i, bind_traits) \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \ + r, id_typename_offset_const, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_( \ + offset, i) \ + BOOST_PP_CAT(bind, BOOST_PP_ADD(offset, i)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_( \ + r, offset, i, bind_traits) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_(offset, i) + +#define \ +BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_( \ + r, id_typename_offset_const, i, bind_traits) \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \ + r, id_typename_offset_const, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) & \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_( \ + BOOST_PP_TUPLE_ELEM(4, 2, id_typename_offset_const), i) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_TYPE_( \ + id, typename01) \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_ \ + bind_this + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_PARAM_DECL_( \ + id, typename01) \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) & \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_(z, n, unused) \ + , ::boost::local_function::aux::nobind + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_TYPE_(z, n, unused) \ + , ::boost::local_function::aux::nobind_t + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_PARAM_DECL_( \ + z, n, unused) \ + , ::boost::local_function::aux::nobind_t & \ + /* param name not needed here because no bind param not used */ + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_( \ + r, id_typename_offset_const, i, bind_traits) \ + BOOST_PP_COMMA_IF(i) /* enumeration commas */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \ + r, id_typename_offset_const, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_( \ + r, id_typename_offset_const, i, bind_traits) \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \ + typename \ + ) \ + ::boost::local_function::aux::member_type< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \ + r, id_typename_offset_const, i, bind_var_without_type) \ + >::reference \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \ + BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(4, 2, \ + id_typename_offset_const))) \ + ; /* end member variable declaration */ + +#define \ +BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_( \ + r, id_typename_offset_const, i, bind_traits) \ + , static_cast< BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_( \ + BOOST_PP_TUPLE_ELEM(4, 0, id_typename_offset_const))* >(object)-> \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \ + BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(4, 2, \ + id_typename_offset_const))) + +#define \ +BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_( \ + r, id_offset, i, bind_traits) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \ + BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset))) \ + ( /* member variable initialization */ \ + static_cast< \ + BOOST_SCOPE_EXIT_DETAIL_PARAMS_T( \ + BOOST_PP_TUPLE_ELEM(2, 0, id_offset))* \ + >(BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_)-> \ + BOOST_SCOPE_EXIT_DETAIL_PARAM( \ + BOOST_PP_TUPLE_ELEM(2, 0, id_offset) \ + , BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset)) \ + , BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits) \ + ).value \ + ) + +// Typeof type-definitions. + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_( \ + r, id_typename_offset_const, i, bind_traits) \ + typedef /* the type with the special typeof name */ \ + BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \ + r, id_typename_offset_const, i, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \ + bind_traits)) \ + ) \ + ; /* end typedef */ + +// Expand to the function type `R (A1, ...)`. +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_( \ + id, typename01, decl_traits, has_type, function_type) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + BOOST_PP_EXPR_IIF(has_type, (function_type) ) \ + ( \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_, \ + 0, /* without defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits)) \ + ) + +// Functor call operations. + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01, \ + const_bind_macro, bind_macro, const_bind_this_macro, bind_this_macro, \ + param_macro, params, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_( \ + BOOST_PP_LIST_FOR_EACH_I(const_bind_macro, \ + 0 /* no offset */, const_binds) \ + /* pass plain binds */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + ) \ + BOOST_PP_LIST_FOR_EACH_I(bind_macro, \ + /* offset index of # const-binds (could be 0) */ \ + BOOST_PP_LIST_SIZE(const_binds), binds) \ + /* pass bind `this` */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \ + ) \ + ) \ + BOOST_PP_EXPR_IIF(has_const_bind_this, const_bind_this_macro) \ + BOOST_PP_EXPR_IIF(has_bind_this, bind_this_macro) \ + /* pass params */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_BITOR( \ + BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \ + ) \ + , BOOST_PP_LIST_IS_CONS(params) \ + ) \ + ) \ + BOOST_PP_LIST_FOR_EACH_I(param_macro, ~, params) \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_(z, defaults_n, \ + id, typename01, decl_traits, params, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + inline BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + operator()( \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_ENUM_, \ + typename01, params) \ + ) /* cannot be const because of binds (same as for global fctor) */ { \ + /* just forward call to member function with local func name */ \ + return BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01,\ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, \ + params, const_binds, has_const_bind_this, binds, \ + has_bind_this); \ + } + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_( \ + z, defaults_n, unused) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (call)(defaults_n) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_FUNC_ADDR_( \ + z, defaults_n, unused) \ + , &BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_(z, defaults_n, ~) + +// Precondition: NO_LOCAL_TYPES_AS_TEMPLATE_PARAMS. +#define \ +BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_BIND_PARAM_DECLS_( \ + id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_, \ + ( id, typename01, 0 /* no offset */, 1 /* const */ ), const_binds) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_, \ + /* offset of # of const-binds */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ),\ + binds) \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \ + has_const_bind_this), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_PARAM_DECL_ \ + , \ + BOOST_PP_TUPLE_EAT(2) \ + )(id, typename01) \ + /* fill with nobind_t (if no local-types as tparams) */ \ + BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \ + has_const_bind_this), \ + BOOST_PP_INC \ + , \ + BOOST_PP_TUPLE_REM(1) \ + )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, \ + binds)))), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_PARAM_DECL_, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_OPERATOR_( \ + id, typename01, \ + params, const_binds, has_const_bind_this, binds, has_bind_this) \ + operator()( \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, ~, \ + params) \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_BODY_( \ + id, typename01, \ + params, const_binds, has_const_bind_this, binds, has_bind_this) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, \ + params, const_binds, has_const_bind_this, binds, has_bind_this) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_(z, defaults_n, \ + id, typename01, decl_traits, params, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + inline static BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_(z, defaults_n, ~)( \ + void* object \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \ + BOOST_PP_TUPLE_EAT(6) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_BIND_PARAM_DECLS_ \ + )(id, typename01, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_PARAM_ARG_DECL_, \ + typename01, params) \ + ) { \ + /* run-time: casting object to this class type and forward call to */ \ + /* `operator()` (this performs better than doing multiple casting */ \ + /* or using a casted object local variable here to call body */ \ + /* directly from here without passing via `operator()`) */ \ + /* compliance: passing local class type to `static_cast` is fully */ \ + /* C++03 compliant because `static_cast` is not a template (even */ \ + /* if its syntax resembles a function template call) in fact even */ \ + /* in C is legal to cast to a local struct (using C-style casting) */ \ + return \ + static_cast< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)* \ + >(object)-> \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_OPERATOR_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_BODY_ \ + )(id, typename01, params, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + ; \ + } + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_(z, defaults_n, \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + BOOST_PP_EXPAND( \ + BOOST_PP_TUPLE_ELEM(9, 0, \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + ( z, defaults_n \ + , BOOST_PP_TUPLE_ELEM(9, 1, /* id */\ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_TUPLE_ELEM(9, 2, /* typename01 */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_TUPLE_ELEM(9, 3, /* decl_traits */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_LIST_FIRST_N( /* remove last n default params */ \ + BOOST_PP_SUB(BOOST_PP_LIST_SIZE(BOOST_PP_TUPLE_ELEM(9, 4, \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis)),\ + defaults_n) \ + , BOOST_PP_TUPLE_ELEM(9, 4, \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + ) \ + , BOOST_PP_TUPLE_ELEM(9, 5, /* const_binds */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_TUPLE_ELEM(9, 6, /* has_const_bind_this */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_TUPLE_ELEM(9, 7, /* binds */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + , BOOST_PP_TUPLE_ELEM(9, 8, /* has_bind_this */ \ + op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \ + ) /* end `op_macro(...)` */ \ + ) /* end expand */ + +// Functor binds. + +// Precondition: NO_LOCAL_TYPES_AS_TEMPLATE_PARAMS. +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_TYPES_( \ + id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_, \ + ( id, typename01, 0 /* no offset */, 1 /* const */ ), \ + const_binds) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_, \ + /* offset of # of const-binds */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ),\ + binds) \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \ + has_const_bind_this), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_TYPE_ \ + , \ + BOOST_PP_TUPLE_EAT(2) \ + )(id, typename01) \ + /* fill with nobind_t (if no local-types as tparams) */ \ + BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \ + BOOST_PP_INC \ + , \ + BOOST_PP_TUPLE_REM(1) \ + )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, binds)))), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_TYPE_, ~) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPEOF_TYPEDEFS_( \ + id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\ + /* typeof types -- these types are qualified with extra eventual */ \ + /* const and/or & if their variables are bound by const and/or & */ \ + /* (this is because it is not possible to strip the eventual & */ \ + /* given that the var name is always attached to the & symbol plus */ \ + /* programmers can always remove const& using type traits) */ \ + /* const bind typeof types */ \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_,\ + (id, typename01, 0 /* no offset */, 1 /* const-bind */ ), \ + const_binds) \ + /* bind typeof types */ \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_, \ + /* offset index with # of preceding const-binds (if any) */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \ + 0 /* not const-bind */ ), binds) \ + /* const this... */ \ + BOOST_PP_EXPR_IIF(has_const_bind_this, \ + typedef BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::local_function::aux::add_pointed_const< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \ + >::type \ + this_ \ + ) ; /* close typedef */ \ + ) \ + /* ... or, non-const this */ \ + BOOST_PP_EXPR_IIF(has_bind_this, \ + typedef BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \ + this_ \ + ) ; /* close typedef */ \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_DECLS_( \ + id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\ + /* run-time: it is faster if call `operator()` just accesses member */ \ + /* references to the ScopeExit struct instead of accessing the bind */ \ + /* struct at each call (these mem refs are init by the constructor) */ \ + BOOST_PP_LIST_FOR_EACH_I( /* const bind member references */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_,\ + ( id, typename01, 0 /* no offset */, 1 /* const */ ), \ + const_binds) \ + BOOST_PP_LIST_FOR_EACH_I( /* bind member references */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_,\ + /* offset index of # of const-binds (could be 0) */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \ + 0 /* no const */ ), binds) \ + /* bind this const or not (pointed-const is not added here because */ \ + /* this is a reference, it is added to the this_ body param instead */ \ + BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \ + /* this is * so no & */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_ \ + ; /* end member variable declaration */ \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BINDS_( \ + id, typename01, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_, \ + ( id, typename01, 0 /* no offset */, 1 /* const */ ), const_binds) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_, \ + /* offset of # of const-binds */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ), \ + binds) \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \ + has_const_bind_this), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BIND_MEMBER_THIS_ \ + , \ + BOOST_PP_TUPLE_EAT(1) \ + )(id) \ + /* fill with nobind_t (if no local-types as tparams) */ \ + BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \ + BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \ + BOOST_PP_INC \ + , \ + BOOST_PP_TUPLE_REM(1) \ + )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, binds)))), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_, ~) + +// Functor inits. + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MEMBER_INITS_(id, typename01, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(BOOST_PP_BITOR(BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds), BOOST_PP_LIST_IS_CONS(binds)), \ + has_bind_this), has_const_bind_this), \ + : \ + ) \ + /* init const binds */ \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_, \ + ( id, 0 /* no offset */ ), const_binds) \ + /* init plain binds */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + ) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_, \ + /* offset index of # of const-binds (could be 0) */ \ + ( id, BOOST_PP_LIST_SIZE(const_binds) ), binds) \ + /* init `this` bind (const or not) */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \ + ) \ + ) \ + BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_const_bind_this, has_bind_this), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_( \ + static_cast< BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)* >( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_)-> \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_VAR \ + ) \ + ) + +// Functor class. + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_( \ + id, typename01, decl_traits, params, \ + default_count, const_binds, has_const_bind_this, binds, has_bind_this) \ + typedef class BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \ + /* run-time: do not use base class to allow for compiler optimizations */ \ + { \ + /* function type */ \ + private: \ + typedef \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_(id, typename01, \ + decl_traits, 1 /* has type */, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_) \ + ; \ + /* functor type -- this type cannot have ID postfix because it is */ \ + /* used the `NAME` macro (this symbol is within functor class so */ \ + /* it does not have to have ID postfix), must be public so it */ \ + /* can be accessed by `NAME` macro from outside this class */ \ + public: \ + typedef BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_IDENTITY_TYPE(( /* IDENTITY for template param comma */ \ + ::boost::local_function::aux::function< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \ + , default_count \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\ + BOOST_PP_TUPLE_EAT(6) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_TYPES_\ + )(id, typename01, const_binds, has_const_bind_this, \ + binds, has_bind_this) \ + > \ + )) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \ + ; \ + private: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPEOF_TYPEDEFS_( \ + id, typename01, \ + const_binds, has_const_bind_this, binds, has_bind_this) \ + public: \ + /* public trait interface following Boost.FunctionTraits names */ \ + /* (traits must be defined in both this and the global functor) */ \ + enum { arity = ::boost::function_traits< /* can't use static data */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ >::arity }; \ + typedef BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + result_type; \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_ARG_TYPEDEF_, \ + typename01, params) \ + /* constructor */ \ + inline explicit BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)( \ + void* BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_) \ + /* NOTE: there is no way to wrap member initializer commas */ \ + /* within paren so you must handle these commas manually if */ \ + /* expanding this macro within another macro */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MEMBER_INITS_(id, typename01,\ + const_binds, has_const_bind_this, binds, has_bind_this) \ + { /* do nothing */ } \ + /* run-time: implement `operator()` (and for all default params) so */ \ + /* this obj can be used directly as a functor for C++03 extensions */ \ + /* and optimized macros */ \ + BOOST_PP_REPEAT( \ + /* PP_INC to handle no dflt (EXPAND for MVSC) */ \ + BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\ + ( BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_, id, typename01 \ + , decl_traits, params, const_binds, has_const_bind_this, binds \ + , has_bind_this ) ) \ + /* compliance: trick to pass this local class as a template param */ \ + /* on pure C++03 without non C++03 extension */ \ + /* performance: this trick introduced _one_ indirect function call */ \ + /* via a function pointer that is usually not inlined by compliers */ \ + /* thus increasing run-time (also another trick using a base */ \ + /* interface class was investigated but virtual calls also cannot */ \ + /* inlined plus they require virtual table lookups to the "virtual */ \ + /* call trick" measured longer run-times than this "static call */ \ + /* trick") */ \ + BOOST_PP_REPEAT( \ + /* PP_INC to handle no dflt (EXPAND for MVSC) */ \ + BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\ + ( BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_, id \ + , typename01, decl_traits, params, const_binds \ + , has_const_bind_this, binds, has_bind_this ) ) \ + inline static void BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \ + void* object \ + , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor \ + ) { \ + functor.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \ + object \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\ + BOOST_PP_TUPLE_EAT(6) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BINDS_ \ + )(id, typename01, const_binds, has_const_bind_this, \ + binds, has_bind_this) \ + BOOST_PP_REPEAT( /* INC to handle no dflt (EXPAND for MVSC) */ \ + BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_FUNC_ADDR_, \ + ~) \ + ); \ + } \ + private: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_DECLS_(id, \ + typename01, const_binds, has_const_bind_this, binds, \ + has_bind_this) \ + /* this decl allows for nesting (local functions, etc) as */ \ + /* it makes the args variable visible within the body code (which */ \ + /* cannot be static); this is for compilation only as the args */ \ + /* variable is actually declared by the 1st enclosing local func */ \ + boost::scope_exit::detail::undeclared \ + BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR; \ + /* body function (unfortunately, cannot be static to allow access */ \ + /* to member var with local function name for recursion but doing */ \ + /* so also allows the body to misuse `this` instead of `this_`) */ \ + inline BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_( \ + /* const binds */ \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_, \ + ( id, typename01, 0 /* no offset */, 1 /* const */ ), \ + const_binds) \ + /* plain binds */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + ) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_, \ + /* offset index of # of const-binds (could be 0) */ \ + ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \ + 0 /* not const-bind */ ), binds) \ + /* `this` bind */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \ + ) \ + ) \ + /* const pointer to const object */ \ + BOOST_PP_EXPR_IIF(has_const_bind_this, \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::local_function::aux::add_pointed_const< \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, \ + typename01) \ + >::type \ + const this_ /* special name to access object this */ \ + ) \ + /* const pointer to non-const object */ \ + BOOST_PP_EXPR_IIF(has_bind_this, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, \ + typename01) \ + const this_ /* special name to access object this */ \ + ) \ + /* params (last because they can have defaults) */ \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_BITAND( \ + BOOST_PP_BITOR( \ + BOOST_PP_BITOR( \ + BOOST_PP_LIST_IS_CONS(const_binds) \ + , BOOST_PP_LIST_IS_CONS(binds) \ + ) \ + , BOOST_PP_BITOR(has_const_bind_this, \ + has_bind_this) \ + ) \ + , BOOST_PP_LIST_IS_CONS(params) \ + ) \ + ) \ + BOOST_PP_LIST_FOR_EACH_I( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_, \ + 1 /* with defaults */, params) \ + ) /* end body function params */ \ + /* cannot be const because recursive functor is non const member */\ + /* user local function definition `{ ... }` will follow here */ \ + /* `END` macro will close function class decl `};` here */ + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (functor_type) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR(id, typename01, decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_(id, typename01, decl_traits \ + /* params (might have defaults) */ \ + , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_COUNT( \ + decl_traits) \ + /* const bind vars (`this` excluded) */ \ + , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + /* if const bind `this` is present */ \ + , BOOST_PP_LIST_IS_CONS( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits)) \ + /* bind (non-const) vars (`this` excluded) */ \ + , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + /* if (non-const) bind `this` is present */ \ + , BOOST_PP_LIST_IS_CONS( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES( \ + decl_traits)) \ + ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/macro/code_/result.hpp b/boost/local_function/aux_/macro/code_/result.hpp new file mode 100644 index 0000000000..84334e7996 --- /dev/null +++ b/boost/local_function/aux_/macro/code_/result.hpp @@ -0,0 +1,107 @@ + +// 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_AUX_CODE_RESULT_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_HPP_ + +#include <boost/local_function/aux_/symbol.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_returns.hpp> +#include <boost/scope_exit.hpp> +#include <boost/typeof/typeof.hpp> +#include <boost/type_traits/remove_pointer.hpp> +#include <boost/type_traits/function_traits.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/cat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id) \ + /* symbol (not internal) also gives error if missing result type */ \ + BOOST_PP_CAT( \ + ERROR_missing_result_type_before_the_local_function_parameter_macro_id, \ + id) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (deduce_result_params)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (result_type)(id) ) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_ \ + /* this does not have to be an integral index because ScopeExit uses */ \ + /* just as a symbol to concatenate go generate unique symbols (but */ \ + /* if it'd ever needed to became integral, the number of function */ \ + /* params + 1 as in the macro CONFIG_ARITY_MAX could be used) */ \ + result + +// User did not explicitly specified result type, deduce it (using Typeof). +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DEDUCE_( \ + id, typename01, decl_traits) \ + /* user specified result type here */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DECL(id) \ + /* tagging, wrapping, etc as from ScopeExit type deduction are */ \ + /* necessary within templates (at least on GCC) to work around an */ \ + /* compiler internal errors) */ \ + BOOST_SCOPE_EXIT_DETAIL_TAG_DECL(0, /* no recursive step r */ \ + id, BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \ + BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(0, /* no recursive step r */ \ + ( id, BOOST_PP_EXPR_IIF(typename01, typename) ), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \ + /* extra struct to workaround GCC and other compiler's issues */ \ + struct BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) { \ + typedef \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::function_traits< \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + ::boost::remove_pointer< \ + BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(id, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \ + >::type \ + >::result_type \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \ + ; \ + }; + +// Use result type as explicitly specified by user (no type deduction needed). +// Precondition: RETURNS(decl_traits) != NIL +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPED_( \ + id, typename01, decl_traits) \ + /* user specified result type here */ \ + struct BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) { \ + typedef \ + BOOST_PP_LIST_FIRST( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS( \ + decl_traits)) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \ + ; \ + }; + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) :: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DECL(id) \ + /* result type here */ (*BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id))(); + +#define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT(id, typename01, decl_traits) \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits)), \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPED_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DEDUCE_ \ + )(id, typename01, decl_traits) + +#endif // #include guard + diff --git a/boost/local_function/aux_/macro/decl.hpp b/boost/local_function/aux_/macro/decl.hpp new file mode 100644 index 0000000000..e5c76dc5e4 --- /dev/null +++ b/boost/local_function/aux_/macro/decl.hpp @@ -0,0 +1,65 @@ + +// 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_AUX_DECL_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_DECL_HPP_ + +#include <boost/local_function/aux_/macro/code_/result.hpp> +#include <boost/local_function/aux_/macro/code_/bind.hpp> +#include <boost/local_function/aux_/macro/code_/functor.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_error.hpp> +#include <boost/scope_exit.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_DECL_OK_(id, typename01, decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT(id, typename01, decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_BIND(id, typename01, decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR(id, typename01, decl_traits) + +#define BOOST_LOCAL_FUNCTION_AUX_DECL_ERROR_(id, typename01, decl_traits) \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits)), \ + /* return specified, so no result type before this macro expansion */ \ + BOOST_PP_TUPLE_EAT(1) \ + , \ + /* even if error, must declare result type to prevent additional */ \ + /* error due to result type appearing before this macro expansion */ \ + BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DECL \ + )(id) \ + ; /* close eventual previous statements, otherwise it has no effect */ \ + BOOST_MPL_ASSERT_MSG(false, /* always fails (there's an error) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR_MSG(decl_traits), ())\ + ; /* must close ASSERT macro for eventual use within class scope */ + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (args) ) + +// Undefine local function bound args global variable. Actual declaration of +// this variable is made using SFINAE mechanisms by each local function macro. +extern boost::scope_exit::detail::undeclared + BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR; + +// sign_params: parsed parenthesized params. +#define BOOST_LOCAL_FUNCTION_AUX_DECL(id, typename01, decl_traits) \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR_MSG(decl_traits)), \ + BOOST_LOCAL_FUNCTION_AUX_DECL_OK_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_DECL_ERROR_ \ + )(id, typename01, decl_traits) + +#endif // #include guard + diff --git a/boost/local_function/aux_/macro/name.hpp b/boost/local_function/aux_/macro/name.hpp new file mode 100644 index 0000000000..7f6dc6a55d --- /dev/null +++ b/boost/local_function/aux_/macro/name.hpp @@ -0,0 +1,201 @@ + +// 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_AUX_NAME_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_ + +#include <boost/local_function/config.hpp> +#include <boost/local_function/aux_/macro/decl.hpp> +#include <boost/local_function/aux_/macro/code_/functor.hpp> +#include <boost/local_function/detail/preprocessor/keyword/recursive.hpp> +#include <boost/local_function/detail/preprocessor/keyword/inline.hpp> +#include <boost/local_function/aux_/function.hpp> +#include <boost/local_function/aux_/symbol.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/logical/bitor.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_type)(local_function_name) ) + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_recursion) ) + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_( \ + is_recursive, local_function_name) \ + BOOST_PP_IIF(is_recursive, \ + local_function_name \ + , \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (nonrecursive_local_function_name) ) \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \ + local_function_name, is_recursive, \ + local_functor_name, nonlocal_functor_name) \ + /* FUNCTION macro expanded to: typedef class functor ## __LINE__ { ... */ \ + BOOST_PP_EXPR_IIF(is_recursive, \ + /* member var with function name for recursive calls; it cannot be */ \ + /* `const` because it is init after construction (because */ \ + /* constructor doesn't know local function name) */ \ + /* run-time: even when optimizing, recursive calls cannot be */ \ + /* optimized (i.e., they must be via the non-local functor) */ \ + /* because this cannot be a mem ref because its name is not known */ \ + /* by the constructor so it cannot be set by the mem init list */ \ + private: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \ + BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(is_recursive, \ + local_function_name); \ + /* run-time: the `init_recursion()` function cannot be called */ \ + /* by the constructor to allow for compiler optimization */ \ + /* (inlining) so it must be public to be called (see below) */ \ + public: \ + inline void BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor) { \ + local_function_name = functor; \ + } \ + ) \ + } BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name); \ + /* local functor can be passed as tparam only on C++11 (faster) */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \ + local_functor_name(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value); \ + /* non-local functor can always be passed as tparam (but slower) */ \ + BOOST_PP_EXPR_IIF(typename01, typename) \ + BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name):: \ + BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \ + nonlocal_functor_name; /* functor variable */ \ + /* the order of the following 2 function calls cannot be changed */ \ + /* because init_recursion uses the local_functor so the local_functor */ \ + /* must be init first */ \ + local_functor_name.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \ + &local_functor_name, nonlocal_functor_name); \ + BOOST_PP_EXPR_IIF(is_recursive, \ + /* init recursion causes MSVC to not optimize local function not */ \ + /* even when local functor is used as template parameter so no */ \ + /* recursion unless all inlining optimizations are specified off */ \ + local_functor_name.BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \ + nonlocal_functor_name); \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name) \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_function_name) ) + +// This can always be passed as a template parameters (on all compilers). +// However, it is slower because it cannot be inlined. +// Passed at tparam: Yes (on all C++). Inlineable: No. Recursive: No. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_(typename01, local_function_name) \ + BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \ + local_function_name, \ + /* local function is not recursive (because recursion and its */ \ + /* initialization cannot be inlined even on C++11, */ \ + /* so this allows optimization at least on C++11) */ \ + 0 /* not recursive */ , \ + /* local functor */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \ + /* local function declared as non-local functor -- but it can */ \ + /* be inlined only by C++11 and it cannot be recursive */ \ + local_function_name) + +// This is faster on some compilers but not all (e.g., it is faster on GCC +// because its optimization inlines it but not on MSVC). However, it cannot be +// passed as a template parameter on non C++11 compilers. +// Passed at tparam: Only on C++11. Inlineable: Yes. Recursive: No. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_(typename01, local_function_name) \ + BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \ + local_function_name, \ + /* inlined local function is never recursive (because recursion */ \ + /* and its initialization cannot be inlined)*/ \ + 0 /* not recursive */ , \ + /* inlined local function declared as local functor (maybe */ \ + /* inlined even by non C++11 -- but it can be passed as */ \ + /* template parameter only on C++11 */ \ + local_function_name, \ + /* non-local functor */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name)) + +// This is slower on all compilers (C++11 and non) because recursion and its +// initialization can never be inlined. +// Passed at tparam: Yes. Inlineable: No. Recursive: Yes. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_( \ + typename01, local_function_name) \ + BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \ + local_function_name, \ + /* recursive local function -- but it cannot be inlined */ \ + 1 /* recursive */ , \ + /* local functor */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \ + /* local function declared as non-local functor -- but it can */ \ + /* be inlined only by C++11 */ \ + local_function_name) + +// Inlined local functions are specified by `..._NAME(inline name)`. +// They have more chances to be inlined for faster run-times by some compilers +// (for example by GCC but not by MSVC). C++11 compilers can always inline +// local functions even if they are not explicitly specified inline. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_( \ + typename01, qualified_name) \ + BOOST_PP_IIF(BOOST_PP_BITOR( \ + BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT( \ + qualified_name)), \ + /* on C++11 always use inlining because compilers might optimize */ \ + /* it to be faster and it can also be passed as tparam */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_ \ + , \ + /* on non C++11 don't use liniling unless explicitly specified by */ \ + /* programmers `inline name` the inlined local function cannot be */ \ + /* passed as tparam */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_ \ + )(typename01, BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \ + qualified_name)) + +// Expand to 1 iff `recursive name` or `recursive inline name` or +// `inline recursive name`. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \ + qualified_name \ + )) + +// Revmoes `recursive`, `inline recursive`, and `recursive inline` from front. +#define BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_( \ + qualified_name) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \ + qualified_name \ + ))) + +#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \ + BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_ \ + , \ + qualified_name /* might be `name` or `inline name` */ \ + BOOST_PP_TUPLE_EAT(1) \ + )(qualified_name) + +// Recursive local function are specified by `..._NAME(recursive name)`. +// They can never be inlined for faster run-time (not even by C++11 compilers). +#define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_( \ + typename01, qualified_name) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \ + /* recursion can never be inlined (not even on C++11) */ \ + BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_ \ + )(typename01, \ + BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name)) + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_NAME(typename01, qualified_name) \ + BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_(typename01, qualified_name) + +#endif // #include guard + diff --git a/boost/local_function/aux_/macro/typeof.hpp b/boost/local_function/aux_/macro/typeof.hpp new file mode 100644 index 0000000000..65ad5975eb --- /dev/null +++ b/boost/local_function/aux_/macro/typeof.hpp @@ -0,0 +1,22 @@ + +// 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_AUX_TYPEOF_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_TYPEOF_HPP_ + +#include <boost/local_function/aux_/symbol.hpp> + +// PUBLIC // + +// Actual type-name for specified symbol name. +#define BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE(name) \ + /* cannot prefix in front of name because it could start with non */ \ + /* alphanumeric symbols (e.g., & for binding by reference) */ \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL_POSTFIX( (name)(typeof_type) ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/member.hpp b/boost/local_function/aux_/member.hpp new file mode 100644 index 0000000000..27d2973294 --- /dev/null +++ b/boost/local_function/aux_/member.hpp @@ -0,0 +1,51 @@ + +// 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_AUX_MEMBER_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_MEMBER_HPP_ + +namespace boost { namespace local_function { namespace aux { + +// Metafunctions to manipulate data members. + +template<typename T> struct member_type { + typedef T& reference; + typedef T* pointer; +}; + +template<typename T> struct member_type<T*> { + typedef T*& reference; + typedef T* pointer; +}; + +template<typename T> struct member_type<T* const> { + typedef T* const& reference; + typedef T* pointer; +}; + +template<typename T> struct member_type<T const*> { + typedef T const*& reference; + typedef T const* pointer; +}; + +template<typename T> struct member_type<T const* const> { + typedef T const* const& reference; + typedef T const* pointer; +}; + +// NOTE: Do not add specializations for T const[&/*] (ambiguous on VACPP). +template<typename T> T* member_addr(T& data) { return &data; } +template<typename T> T* member_addr(T* data) { return data; } + +// NOTE: Do not add specializations for T const[&/*] (ambiguous on VACPP). +template<typename T> T& member_deref(T& data) { return data; } +template<typename T> T& member_deref(T* data) { return *data; } + +} } } // namespace + +#endif // #include guard + diff --git a/boost/local_function/aux_/nobind.hpp b/boost/local_function/aux_/nobind.hpp new file mode 100644 index 0000000000..73afc6fd58 --- /dev/null +++ b/boost/local_function/aux_/nobind.hpp @@ -0,0 +1,32 @@ + +// 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_AUX_NOBIND_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_NOBIND_HPP_ + +#include <boost/local_function/config.hpp> + +// NOTE: The current implementation needs no-bind placeholders only when +// local types cannot be passed as template parameters. +#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + +namespace boost { namespace local_function { namespace aux { + +typedef int nobind_t; // Tag no-bind type. + +static nobind_t nobind; // Global variable so all no-binds can reference it. + +// NOTE: Used only to get rid of unused static variable `nobind` (this function +// is never actually called so it does not need to be defined). +void no_unused_nobind_warning_(nobind_t* ptr = &nobind); + +} } } // namespace + +#endif // locals as tparams + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/bind.hpp b/boost/local_function/aux_/preprocessor/traits/bind.hpp new file mode 100644 index 0000000000..601f36f8a1 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/bind.hpp @@ -0,0 +1,46 @@ + +// 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_AUX_PP_BIND_TRAITS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_HPP_ + +#include <boost/preprocessor/tuple/elem.hpp> + +// PRIVATE // + +// Non-this bind is 2-tuple `(name_without_type, name_with_type)`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_WITHOUT_TYPE_ 0 +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_WITH_TYPE_ 1 +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_MAX_ 2 + +// This bind is 1-typle `([type_] EMPTY)`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_THIS_TRAITS_INDEX_TYPE_ 0 +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_THIS_TRAITS_INDEX_MAX_ 1 + +// PUBLIC // + +// Expand: `[&] var_`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE(bind_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_MAX_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_WITHOUT_TYPE_, \ + bind_traits) + +// Expand: `[type_ [&] var_]` (EMPTY if no type_ specified). +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITH_TYPE(bind_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_MAX_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_INDEX_WITH_TYPE_, \ + bind_traits)(/* expand EMPTY */) + +// Expand: `[type_]` (EMPTY if no type_ specified). +#define BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_THIS_TYPE(bind_this_traits) \ + BOOST_PP_TUPLE_ELEM( \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_THIS_TRAITS_INDEX_MAX_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_BIND_THIS_TRAITS_INDEX_TYPE_, \ + bind_this_traits)(/* expand EMPTY */) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl.hpp b/boost/local_function/aux_/preprocessor/traits/decl.hpp new file mode 100644 index 0000000000..8f6a6f78fd --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl.hpp @@ -0,0 +1,29 @@ + +// 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_AUX_PP_DECL_TRAITS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_sign_/sign.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/nil.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/list/adt.hpp> + +// PUBLIC // + +// Expand: decl_traits (see DECL_TRAITS macros to inspect these traits). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS(declarations) \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_NIL(declarations), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_NIL \ + BOOST_PP_TUPLE_EAT(1) \ + , \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN \ + )(declarations) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/append.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/append.hpp new file mode 100644 index 0000000000..b810c66aac --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/append.hpp @@ -0,0 +1,212 @@ + +// 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_AUX_PP_DECL_TRAITS_APPEND_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_returns.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_params.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_error.hpp> +#include <boost/local_function/aux_/preprocessor/traits/param.hpp> +#include <boost/local_function/detail/preprocessor/keyword/return.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/arithmetic/dec.hpp> +#include <boost/preprocessor/list/append.hpp> +#include <boost/preprocessor/list/size.hpp> +#include <boost/preprocessor/list/at.hpp> +#include <boost/preprocessor/list/first_n.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM_DEFAULT_( \ + params, default_value) \ + /* `DEC` ok because precondition that unbinds are not nil-list */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_PP_LIST_FIRST_N(BOOST_PP_DEC(BOOST_PP_LIST_SIZE(params)), \ + params) \ + , \ + ( /* list 2-tuple */ \ + ( /* (param_decl, default) 2-tuple */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DECL( \ + BOOST_PP_LIST_AT(params, BOOST_PP_DEC( \ + BOOST_PP_LIST_SIZE(params)))) \ + , \ + default_value BOOST_PP_EMPTY \ + ) \ + , \ + BOOST_PP_NIL \ + ) \ + ) + +// PUBLIC // + +// return_type: `return result_type`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_RETURN( \ + decl_traits, return_type) \ + ( /* returns */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits), \ + ( BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_FRONT( \ + return_type), BOOST_PP_NIL ) ) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + + +// param_decl: `[auto | register] type_ name_`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM( \ + decl_traits, param_decl) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits), \ + /* append param (with no default -- EMPTY) */ \ + ( (param_decl, BOOST_PP_EMPTY), BOOST_PP_NIL ) ) \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +// default_value: a valid parameter default value (`-1`, etc). +// Precondition: already added unbinds are not nil-list. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM_DEFAULT( \ + decl_traits, default_value) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* unbind params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM_DEFAULT_( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits), \ + default_value) /* append default to last added param */ \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +// var_without_type: `[&] var_` (var_ != this). +// var_with_type: `PP_EMPTY | type [&] var_` (var_ != this). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_BIND( \ + decl_traits, var_without_type, var_with_type) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits), \ + ( (var_without_type, var_with_type), BOOST_PP_NIL ) ) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +// this_type: `PP_EMPTY | type`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_BIND_THIS_TYPE( \ + decl_traits, this_type) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES( \ + decl_traits), \ + ( (this_type), BOOST_PP_NIL ) ) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +// var_without_type: `[&] var_` (var_ != this). +// var_with_type: `BOOST_PP_EMPTY | type_ [&] name_` (var_ != this). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_CONST_BIND( \ + decl_traits, var_without_type, var_with_type) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind vars */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS( \ + decl_traits), \ + ( (var_without_type, var_with_type), BOOST_PP_NIL ) ) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +// this_type: `PP_EMPTY | type`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_CONST_BIND_THIS_TYPE( \ + decl_traits, this_type) \ + ( /* returns */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits), \ + ( (this_type), BOOST_PP_NIL ) ) \ + , /* bind vars */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/index.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/index.hpp new file mode 100644 index 0000000000..1d62693825 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/index.hpp @@ -0,0 +1,21 @@ + +// 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_AUX_PP_DECL_TRAITS_INDEX_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_HPP_ + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_RETURNS 0 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_PARAMS 1 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_CONST_BINDS 2 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_CONST_BIND_THIS_TYPES 3 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_BINDS 4 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_BIND_THIS_TYPES 5 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_ERROR 6 +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX 7 + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/nil.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/nil.hpp new file mode 100644 index 0000000000..0684dc518f --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/nil.hpp @@ -0,0 +1,39 @@ + +// 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_AUX_PP_DECL_TRAITS_NIL_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_NIL_HPP_ + +#include <boost/preprocessor/facilities/empty.hpp> + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_NIL \ + ( \ + /* returns: list of `return result_type` */ \ + BOOST_PP_NIL /* nil list */ \ + , \ + /* params: list of 2-tuples (param_decl, param_default) */ \ + BOOST_PP_NIL /* nil list */ \ + , \ + /* const-binds: list of 2-tuple `(var_untyped, var_typed)` */ \ + BOOST_PP_NIL /* nil list */ \ + , \ + /* const-bind this: list of 1-tuple `(type)` */ \ + BOOST_PP_NIL \ + /* number of const-bind `this` */ \ + , \ + /* binds: list of 2-tuple `(var_untyped, var_typed)` */ \ + BOOST_PP_NIL /* nil list */ \ + , \ + /* bind this: list of 1-type `(type)` */ \ + BOOST_PP_NIL \ + , \ + /* error: `[ERROR_message_text] EMPTY` */ \ + BOOST_PP_EMPTY /* no error */ \ + ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp new file mode 100644 index 0000000000..b3ec1b3fa7 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp @@ -0,0 +1,38 @@ + +// 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_AUX_PP_DECL_TRAITS_SET_ERROR_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SET_ERROR_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_returns.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_params.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp> + +// PUBLIC // + +// error: `[ERROR_message_text] EMPTY`, no ERROR_message_text if no error. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SET_ERROR(decl_traits, error) \ + ( /* return types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + , /* params and defaults */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + , /* const-bind names */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + , /* const-bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + , /* bind names */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + , /* bind `this` types */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + , /* error message (if any) */ \ + error \ + ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/validate.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/validate.hpp new file mode 100644 index 0000000000..aab7f8866c --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/validate.hpp @@ -0,0 +1,24 @@ + +// 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_AUX_PP_DECL_TRAITS_VALIDATE_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/validate_/this_count.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/validate_/return_count.hpp> + +// PUBLIC // + +// Validate params after they have been parsed. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE(decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_THIS_COUNT( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_RETURN_COUNT( \ + decl_traits \ + )) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/validate_/return_count.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/validate_/return_count.hpp new file mode 100644 index 0000000000..4d337d900b --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/validate_/return_count.hpp @@ -0,0 +1,32 @@ + +// 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_AUX_PP_DECL_TRAITS_VALIDATE_RETURN_COUNT_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_RETURN_COUNT_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_returns.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/comparison/greater.hpp> +#include <boost/preprocessor/list/size.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_RETURN_COUNT( \ + decl_traits) \ + BOOST_PP_IIF(BOOST_PP_GREATER(BOOST_PP_LIST_SIZE( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits)), 1), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SET_ERROR \ + , /* else do nothing (keeping previous error, if any) */ \ + decl_traits BOOST_PP_TUPLE_EAT(2) \ + )(decl_traits, /* trailing `EMPTY` because error might not be present */ \ + ERROR_cannot_specify_more_than_one_return_type BOOST_PP_EMPTY) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_/validate_/this_count.hpp b/boost/local_function/aux_/preprocessor/traits/decl_/validate_/this_count.hpp new file mode 100644 index 0000000000..034e8e69b4 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_/validate_/this_count.hpp @@ -0,0 +1,38 @@ + +// 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_AUX_PP_DECL_TRAITS_VALIDATE_THIS_COUNT_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_THIS_COUNT_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/comparison/greater.hpp> +#include <boost/preprocessor/list/append.hpp> +#include <boost/preprocessor/list/size.hpp> + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE_THIS_COUNT( \ + decl_traits) \ + BOOST_PP_IIF(BOOST_PP_GREATER(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES( \ + decl_traits))), \ + 1), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SET_ERROR \ + , /* do nothing (keeping previous error, if any) */ \ + decl_traits BOOST_PP_TUPLE_EAT(2) \ + )(decl_traits, /* trailing `EMPTY` because error might not be present */ \ + ERROR_cannot_bind_object_this_multiple_times BOOST_PP_EMPTY) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_binds.hpp b/boost/local_function/aux_/preprocessor/traits/decl_binds.hpp new file mode 100644 index 0000000000..0d4f18276c --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_binds.hpp @@ -0,0 +1,35 @@ + +// 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_AUX_PP_DECL_TRAITS_BINDS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/index.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/list/transform.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_APPLY_( \ + d, bind_macro, bind_traits) \ + bind_macro(bind_traits) + +// PUBLIC // + +// Expand: pp-list of non-const bind-traits. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_BINDS, decl_traits) + +// Expand: pp-list non-const bind-this-traits (size <= 1 after validation). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_BIND_THIS_TYPES, \ + decl_traits) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp b/boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp new file mode 100644 index 0000000000..0ea40cf6df --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp @@ -0,0 +1,40 @@ + +// 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_AUX_PP_DECL_TRAITS_CONST_BINDS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/bind.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/index.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/list/transform.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_APPLY_( \ + d, bind_macro, bind_traits) \ + bind_macro(bind_traits) + +// PUBLIC // + +// Expand: pp-list of const bind-traits. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_CONST_BINDS, \ + decl_traits) + +// Expand: pp-list of const bind-this-traits (size <= 1 after validation). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \ + decl_traits) \ + BOOST_PP_TUPLE_ELEM( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX \ + , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_CONST_BIND_THIS_TYPES \ + , decl_traits \ + ) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_error.hpp b/boost/local_function/aux_/preprocessor/traits/decl_error.hpp new file mode 100644 index 0000000000..a95fc7b760 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_error.hpp @@ -0,0 +1,27 @@ + +// 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_AUX_PP_DECL_TRAITS_ERROR_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/index.hpp> +#include <boost/preprocessor/tuple/elem.hpp> + +// PUBLIC // + +// Expand: `[ERROR_message_text] EMPTY`, EMPTY iff no pp-parsing error. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_ERROR, decl_traits) + +// Expand: `[ERROR_message_text]`, EMPTY iff no pp-parsing error. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR_MSG(decl_traits) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_ERROR(decl_traits) \ + (/* expand EMPTY */) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_params.hpp b/boost/local_function/aux_/preprocessor/traits/decl_params.hpp new file mode 100644 index 0000000000..ae5a34f776 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_params.hpp @@ -0,0 +1,59 @@ + +// 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_AUX_PP_DECL_TRAITS_PARAMS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/index.hpp> +#include <boost/local_function/aux_/preprocessor/traits/param.hpp> +#include <boost/local_function/detail/preprocessor/keyword/default.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/tuple/rem.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/logical/compl.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/list/fold_left.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_OP_(s, \ + default_count, param_traits) \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits)), \ + BOOST_PP_TUPLE_REM(1) \ + , \ + BOOST_PP_INC \ + )(default_count) + +// Precondition: params is a pp-list which is not nil. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_COUNT_(params) \ + BOOST_PP_LIST_FOLD_LEFT( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_OP_, \ + 0 /* start with defaults_count to 0 */, params) + +// PUBLIC // + +// Expand: pp-list of param-traits (no bound variables). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_PARAMS, decl_traits) + +// Expand: number of parameters with default values (0 if no default). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_COUNT( \ + decl_traits) \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits)), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_COUNT_ \ + , \ + 0 BOOST_PP_TUPLE_EAT(1) \ + )(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits)) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_returns.hpp b/boost/local_function/aux_/preprocessor/traits/decl_returns.hpp new file mode 100644 index 0000000000..941358a6d5 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_returns.hpp @@ -0,0 +1,22 @@ + +// 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_AUX_PP_DECL_TRAITS_RETURNS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_/index.hpp> +#include <boost/preprocessor/tuple/elem.hpp> + +// PUBLIC // + +// Expand: pp-list of result types (size <= 1 after validation). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_MAX, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_INDEX_RETURNS, decl_traits) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_sign_/any_bind_type.hpp b/boost/local_function/aux_/preprocessor/traits/decl_sign_/any_bind_type.hpp new file mode 100644 index 0000000000..a39964228a --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_sign_/any_bind_type.hpp @@ -0,0 +1,88 @@ + +// 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_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_TYPE_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_TYPE_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/const_bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/this.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/facilities/expand.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/tuple/rem.hpp> +#include <boost/preprocessor/detail/is_unary.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE_(sign) \ + /* using PP_EXPAND here does not work on MSVC */ \ + BOOST_PP_TUPLE_REM(1) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT(sign) \ + BOOST_PP_EMPTY /* always trail EMPTY because bind type is optional */ + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE_( \ + sign) \ + /* using PP_EXPAND here does not work on MSVC */ \ + BOOST_PP_TUPLE_EAT(1) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT(sign) + +#define this_BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_REMOVE_THIS_ \ + /* must expand to nothing */ + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_THIS_TYPE_(sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE( \ + /* can't use `THISUNDERSCIRE_REMOVE_BACK` because `sign` contains */ \ + /* multiple tokens (and not just one token) so */ \ + /* `IS_THISUNDERSCORE_BACK` does not work (but we know `sign` ends */ \ + /* with this_ if we here so we can manually force the removal using */ \ + BOOST_PP_CAT(sign, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_REMOVE_THIS_) \ + ) \ + /* do not append PP_EMPTY because ANY_BIND_WITH_TYPE macro above */ \ + /* already appends it */ + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_HAS_TYPE(sign) \ + BOOST_PP_IS_UNARY( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT( \ + sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE(sign) \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_HAS_TYPE( \ + sign),\ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE_ \ + , \ + BOOST_PP_EMPTY \ + BOOST_PP_TUPLE_EAT(1) \ + )(sign) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE( \ + sign) \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_HAS_TYPE( \ + sign),\ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE_ \ + , \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT \ + )(sign) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_THIS_TYPE(sign) \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_HAS_TYPE( \ + sign),\ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_THIS_TYPE_ \ + , \ + BOOST_PP_EMPTY \ + BOOST_PP_TUPLE_EAT(1) \ + )(sign) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_sign_/sign.hpp b/boost/local_function/aux_/preprocessor/traits/decl_sign_/sign.hpp new file mode 100644 index 0000000000..7dc4db1238 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_sign_/sign.hpp @@ -0,0 +1,138 @@ + +// 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_AUX_PP_DECL_TRAITS_SIGN_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_sign_/validate.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_sign_/any_bind_type.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/nil.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/set_error.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/validate.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_/append.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const_bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/return.hpp> +#include <boost/local_function/detail/preprocessor/keyword/default.hpp> +#include <boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/list/fold_left.hpp> + +// PRIVATE // + +// Parse const binds. + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_THIS_( \ + decl_traits, sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_CONST_BIND_THIS_TYPE( \ + decl_traits, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_THIS_TYPE( \ + sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_VAR_( \ + decl_traits, sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_CONST_BIND(decl_traits, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE(\ + sign), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE( \ + sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_( \ + decl_traits, sign) \ + /* check from back because non `this` bounds might have `&` in front */ \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK(\ + /* remove all leading symbols `[const] bind [(type)] ...` */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE(\ + sign)),\ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_THIS_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_VAR_ \ + )(decl_traits, sign) + +// Parse binds. + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_THIS_( \ + decl_traits, sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_BIND_THIS_TYPE(decl_traits, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_THIS_TYPE( \ + sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_VAR_( \ + decl_traits, sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_BIND(decl_traits, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE(\ + sign), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITH_TYPE( \ + sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_( \ + decl_traits, sign) \ + /* check from back because non `this` bounds might have `&` in front */ \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK(\ + /* remove all leading symbols `[const] bind [(type)] ...` */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ANY_BIND_WITHOUT_TYPE(\ + sign)), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_THIS_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_VAR_ \ + )(decl_traits, sign) + +// Parse all elements. + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_( \ + s, decl_traits, sign) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_FRONT(sign), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_RETURN \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT(sign), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_BIND_ \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT( \ + sign), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_CONST_BIND_ \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT( \ + sign), \ + /* elem is `default ...` where leading default is kept because */ \ + /* default value might not be alphanumeric (so it fails later CAT */ \ + /* for checks), leading default will be removed later when getting */ \ + /* the default value */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM_DEFAULT \ + , /* else, it is a function parameter */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_APPEND_PARAM \ + ))))(decl_traits, sign) + +// Parse params after following precondition has been validated by caller. +// Precondition: If list contains a default param value `..., default, ...`, +// the default value element is never 1st (it always has a previous elem) and +// its previous element is a unbind param (no const-bind and no bind). +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID(sign) \ + BOOST_PP_LIST_FOLD_LEFT( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_NIL, sign) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_OK_(sign, unused) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_VALIDATE( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALID(sign)) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ERR_(unused, error) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SET_ERROR( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_NIL, error) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_(sign, defaults_error) \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY(defaults_error (/* expand EMPTY */)), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_OK_ \ + , \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_ERR_ \ + )(sign, defaults_error) + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN(sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_(sign, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE(sign)) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate.hpp b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate.hpp new file mode 100644 index 0000000000..ef49610004 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate.hpp @@ -0,0 +1,32 @@ + +// 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_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_HPP_ + +#include <boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/defaults.hpp> +#include <boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/this.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_1_(sign, error) \ + BOOST_PP_IIF(BOOST_PP_IS_EMPTY(error(/* expand empty */)), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS \ + , \ + error BOOST_PP_TUPLE_EAT(1) \ + )(sign) + +// PUBLIC // + +// Validate params before starting to parse it. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE(sign) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_1_(sign, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS(sign)) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/defaults.hpp b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/defaults.hpp new file mode 100644 index 0000000000..28f1efa392 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/defaults.hpp @@ -0,0 +1,125 @@ + +// 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_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/const_bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/default.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/while.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/control/if.hpp> +#include <boost/preprocessor/facilities/expand.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/facilities/is_empty.hpp> +#include <boost/preprocessor/logical/bitand.hpp> +#include <boost/preprocessor/logical/bitor.hpp> +#include <boost/preprocessor/logical/not.hpp> +#include <boost/preprocessor/comparison/less.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/arithmetic/dec.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/list/size.hpp> +#include <boost/preprocessor/list/at.hpp> + +// PRIVATE // + +#define \ +BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_IS_UNBIND_( \ + sign) \ + /* PP_OR/PP_BITOR (instead of IIF) don't expand on MSVC */ \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT(sign),\ + 0 \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT( \ + sign), \ + 0 \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT(sign), \ + 0 \ + , \ + 1 \ + ))) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PREV_( \ + sign, index, error) \ + BOOST_PP_IIF( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_IS_UNBIND_( \ + BOOST_PP_LIST_AT(sign, BOOST_PP_DEC(index))), \ + error /* no err, fwd existing one if any */ \ + , \ + BOOST_PP_CAT(BOOST_PP_CAT(ERROR_default_value_at_element_, \ + BOOST_PP_INC(index)), _must_follow_an_unbound_parameter) \ + BOOST_PP_EMPTY /* because error might not be present */ \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_INDEX_( \ + sign, index, error) \ + BOOST_PP_IF(index, /* can't use IIF because index can be any number */ \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PREV_ \ + , \ + ERROR_default_value_cannot_be_specified_as_the_first_element \ + BOOST_PP_EMPTY /* because error might not be present */ \ + BOOST_PP_TUPLE_EAT(3) \ + )(sign, index, error) + +// While's operation. + +#define \ +BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_OP_DATA_( \ + sign, index, error) \ + ( \ + sign \ + , \ + BOOST_PP_INC(index) \ + , \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT( \ + BOOST_PP_LIST_AT(sign, index)), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_INDEX_ \ + , \ + error BOOST_PP_TUPLE_EAT(3) /* no err, fwd existing one if any */\ + )(sign, index, error) \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_OP_(d, \ + sign_index_error) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_OP_DATA_( \ + BOOST_PP_TUPLE_ELEM(3, 0, sign_index_error), \ + BOOST_PP_TUPLE_ELEM(3, 1, sign_index_error), \ + BOOST_PP_TUPLE_ELEM(3, 2, sign_index_error)) + +// While predicate. + +#define \ +BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PRED_DATA_( \ + sign, index, error) \ + BOOST_PP_BITAND( \ + BOOST_PP_IS_EMPTY(error (/* expand empty */) ) \ + , BOOST_PP_LESS(index, BOOST_PP_LIST_SIZE(sign)) \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PRED_( \ + d, sign_index_error) \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PRED_DATA_( \ + BOOST_PP_TUPLE_ELEM(3, 0, sign_index_error), \ + BOOST_PP_TUPLE_ELEM(3, 1, sign_index_error), \ + BOOST_PP_TUPLE_ELEM(3, 2, sign_index_error)) + +// PUBLIC // + +// Validate parameters default values: `default ...` cannot be 1st element and +// it must follow an unbind param. Expand to `EMPTY` if no error, or +// `ERROR_message EMPTY` if error. +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS(sign) \ + BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_WHILE( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_PRED_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_DEFAULTS_OP_,\ + (sign, 0, BOOST_PP_EMPTY))) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/this.hpp b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/this.hpp new file mode 100644 index 0000000000..8a924bdab3 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/decl_sign_/validate_/this.hpp @@ -0,0 +1,66 @@ + +// 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_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/this.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const.hpp> +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const_bind.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/list/fold_left.hpp> + +// PRIVATE // + +#define \ +BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_TYPED_EAT_(elem) \ + /* must be in separate macro to delay expansion */ \ + BOOST_PP_TUPLE_EAT(1) elem + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_TYPED_( \ + elem) \ + BOOST_PP_IIF(BOOST_PP_IS_UNARY(elem), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_TYPED_EAT_ \ + , \ + BOOST_PP_TUPLE_REM(1) \ + )(elem) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_VAR_( \ + s, error, elem) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_BACK( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_TYPED_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_FRONT( \ + elem)))), \ + ERROR_use_this_underscore_instead_of_this BOOST_PP_EMPTY \ + , \ + error \ + ) + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_( \ + s, error, elem) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT(elem), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_VAR_ \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT( \ + elem), \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_VAR_ \ + , \ + error BOOST_PP_TUPLE_EAT(3) \ + ))(s, error, elem) + +// PUBLIC // + +#define BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS(sign) \ + BOOST_PP_LIST_FOLD_LEFT( \ + BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_SIGN_VALIDATE_THIS_, \ + BOOST_PP_EMPTY, sign) + +#endif // #include guard + diff --git a/boost/local_function/aux_/preprocessor/traits/param.hpp b/boost/local_function/aux_/preprocessor/traits/param.hpp new file mode 100644 index 0000000000..641cd81766 --- /dev/null +++ b/boost/local_function/aux_/preprocessor/traits/param.hpp @@ -0,0 +1,36 @@ + +// 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_AUX_PP_PARAM_TRAITS_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_HPP_ + +#include <boost/preprocessor/tuple/elem.hpp> + +// PRIVATE // + +// Param 2-tuple `([auto | register] type name, default_value)`. +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_DECL_ 0 +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_DEFAULT_ 1 +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_MAX_ 2 + +// PUBLIC // + +// Expand: `[auto | register] type_ name_` (parameter declaration). +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DECL(param_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_MAX_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_DECL_, param_traits) + +// Expand: `default ... EMPTY()` if default value, `EMPTY()` otherwise. +// Leading default is kept because default value might not be alphanumeric +// (e.g., -123) so failing `CAT` for `IS_EMPTY` check. +#define BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits) \ + BOOST_PP_TUPLE_ELEM(BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_MAX_, \ + BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_INDEX_DEFAULT_, \ + param_traits)(/* expand EMPTY */) + +#endif // #include guard + diff --git a/boost/local_function/aux_/symbol.hpp b/boost/local_function/aux_/symbol.hpp new file mode 100644 index 0000000000..859fed6501 --- /dev/null +++ b/boost/local_function/aux_/symbol.hpp @@ -0,0 +1,50 @@ + +// 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_AUX_SYMBOL_HPP_ +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL_HPP_ + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/seq/cat.hpp> +#include <boost/preprocessor/seq/transform.hpp> + +// PRIVATE // + +// NOTE: INFIX is used to separate symbols concatenated together. Some of these +// symbols are user-defined so they can be anything. Because they can contain +// underscore `_` and/or start with capital letters, it is NOT safe for the +// INFIX to be the underscore `_` character because that could lead to library +// defined symbols containing double underscores `__` or a leading underscore +// (followed or not by a capital letter) in the global namespace. All these +// symbols are reserved by the C++ standard: (1) "each name that contains a +// double underscore (_ _) or begins with an underscore followed by an +// uppercase letter is reserved to the implementation" and (2) "each name that +// begins with an underscore is reserved to the implementation for use as a +// name in the global namespace". +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL_INFIX_ X // `X` used as separator. + +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL_PREFIX_ boost_local_function_aux + +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL_POSTFIX_(s, unused, tokens) \ + BOOST_PP_CAT(tokens, BOOST_LOCAL_FUNCTION_AUX_SYMBOL_INFIX_) + +// PUBLIC // + +// Prefixes this library reserved symbol. +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL(seq) \ + BOOST_PP_SEQ_CAT(BOOST_PP_SEQ_TRANSFORM( \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL_POSTFIX_, \ + ~, (BOOST_LOCAL_FUNCTION_AUX_SYMBOL_PREFIX_) seq )) + +// Postfixes this library reserved symbol. +#define BOOST_LOCAL_FUNCTION_AUX_SYMBOL_POSTFIX(seq) \ + BOOST_PP_SEQ_CAT(BOOST_PP_SEQ_TRANSFORM( \ + BOOST_LOCAL_FUNCTION_AUX_SYMBOL_POSTFIX_, \ + ~, seq (BOOST_LOCAL_FUNCTION_AUX_SYMBOL_PREFIX_) )) + +#endif // #include guard + diff --git a/boost/local_function/config.hpp b/boost/local_function/config.hpp new file mode 100644 index 0000000000..bab295378d --- /dev/null +++ b/boost/local_function/config.hpp @@ -0,0 +1,114 @@ + +// 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_CONFIG_HPP_ +#define BOOST_LOCAL_FUNCTION_CONFIG_HPP_ + +#ifndef DOXYGEN + +#include <boost/config.hpp> + +#ifndef BOOST_LOCAL_FUNCTION_CONFIG_FUNCTION_ARITY_MAX +# define BOOST_LOCAL_FUNCTION_CONFIG_FUNCTION_ARITY_MAX 5 +#endif + +#ifndef BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX +# define BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX 10 +#endif + +#ifndef BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS +# ifdef BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS 0 +# else +# define BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS 1 +# endif +#elif BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS // If true, force it to 1. +# undef BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS +# define BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS 1 +#endif + +#else // DOXYGEN + +/** @file +@brief Configuration macros allow to change the behaviour of this library at +compile-time. +*/ + +/** +@brief Maximum number of parameters supported by local functions. + +If programmers leave this configuration macro undefined, its default +value is <c>5</c> (increasing this number might increase compilation time). +When defined by programmers, this macro must be a non-negative integer number. + +@Note This macro specifies the maximum number of local function parameters +excluding bound variables (which are instead specified by +@RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX}). + +@See @RefSect{tutorial, Tutorial} section, +@RefSect{getting_started, Getting Started} section, +@RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX}. +*/ +#define BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX + +/** +@brief Maximum number of bound variables supported by local functions. + +If programmers leave this configuration macro undefined, its default +value is <c>10</c> (increasing this number might increase compilation time). +When defined by programmers, this macro must be a non-negative integer number. + +@Note This macro specifies the maximum number of bound variables excluding +local function parameters (which are instead specified by +@RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX}). + +@See @RefSect{tutorial, Tutorial} section, +@RefSect{getting_started, Getting Started} section, +@RefMacro{BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX}. +*/ +#define BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX + +/** +@brief Specify when local functions can be passed as template parameters +without introducing any run-time overhead. + +If this macro is defined to <c>1</c>, this library will assume that the +compiler allows to pass local classes as template parameters: +@code + template<typename T> void f(void) {} + + int main(void) { + struct local_class {}; + f<local_class>(); + return 0; + } +@endcode +This is the case for C++11 compilers and some C++03 compilers (e.g., MSVC), but +it is not the case in general for most C++03 compilers (including GCC). +This will allow the library to pass local functions as template parameters +without introducing any run-time overhead (specifically without preventing the +compiler from optimizing local function calls by inlining their assembly code). + +If this macro is defined to <c>0</c> instead, this library will introduce +a run-time overhead associated to resolving a function pointer call in order to +still allow to pass the local functions as template parameters. + +It is recommended to leave this macro undefined. +In this case, the library will automatically define this macro to <c>0</c> if +the Boost.Config macro <c>BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS</c> is +defined for the specific compiler, and to <c>1</c> otherwise. + +@See @RefSect{getting_started, Getting Started} section, +@RefSect{advanced_topics, Advanced Topics} section, +@RefMacro{BOOST_LOCAL_FUNCTION_NAME}. +*/ +#define BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS + +#endif // DOXYGEN + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/auto.hpp b/boost/local_function/detail/preprocessor/keyword/auto.hpp new file mode 100644 index 0000000000..f554de9219 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/auto.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_AUTO_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_IS_auto (1) /* unary */ +#define auto_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_auto /* nothing */ +#define auto_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_FRONT, auto) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_AUTO_BACK, auto) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/bind.hpp b/boost/local_function/detail/preprocessor/keyword/bind.hpp new file mode 100644 index 0000000000..44b8c23073 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/bind.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_BIND_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS_bind (1) /* unary */ +#define bind_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_bind /* nothing */ +#define bind_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(tokens, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT, bind) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_BACK, bind) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/const.hpp b/boost/local_function/detail/preprocessor/keyword/const.hpp new file mode 100644 index 0000000000..c15bfabdc5 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/const.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_CONST_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_IS_const (1) /* unary */ +#define const_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_const /* nothing */ +#define const_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_FRONT, const) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BACK, const) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/const_bind.hpp b/boost/local_function/detail/preprocessor/keyword/const_bind.hpp new file mode 100644 index 0000000000..6e886e1a63 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/const_bind.hpp @@ -0,0 +1,74 @@ + +// 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_DETAIL_PP_KEYWORD_CONST_BIND_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS_bind (1) /* unary */ +#define bind_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_bind /* nothing */ +#define bind_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT_(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_FRONT(tokens)) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT(tokens) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_FRONT(tokens),\ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT_ \ + , \ + 0 BOOST_PP_TUPLE_EAT(1) \ + )(tokens) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_BACK_(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BACK( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_BACK(tokens)) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONDT_BIND_BACK(tokens) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_BACK_ \ + , \ + 0 BOOST_PP_TUPLE_EAT(1) \ + )(tokens) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_FRONT(tokens)) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_BACK( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_BACK(tokens)) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT, \ + const bind) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_BACK, \ + const bind) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/default.hpp b/boost/local_function/detail/preprocessor/keyword/default.hpp new file mode 100644 index 0000000000..042f50745f --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/default.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_DEFAULT_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_IS_default (1)/* unary */ +#define default_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_IS (1)/* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_default/*nothing*/ +#define default_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE/*nothing*/ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_FRONT, default) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_DEFAULT_BACK, default) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/facility/add.hpp b/boost/local_function/detail/preprocessor/keyword/facility/add.hpp new file mode 100644 index 0000000000..13f5699085 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/facility/add.hpp @@ -0,0 +1,25 @@ + +// 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_DETAIL_PP_KEYWORD_FACILITY_ADD_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_HPP_ + +#include <boost/preprocessor/control/expr_iif.hpp> +#include <boost/preprocessor/logical/compl.hpp> + +// `is_front_macro(tokens)` is 1 if `tokens` start w/ `keyword` to add, else 0. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT( \ + tokens, is_front_macro, keyword) \ + BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(is_front_macro(tokens)), keyword) tokens + +// `is_back_macro(tokens)` is 1 if `tokens` end with `keyword` to add, else 0. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK( \ + tokens, is_back_macro, keyword) \ + tokens BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(is_back_macro(tokens)), keyword) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/facility/is.hpp b/boost/local_function/detail/preprocessor/keyword/facility/is.hpp new file mode 100644 index 0000000000..a5a1151a61 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/facility/is.hpp @@ -0,0 +1,51 @@ + +// 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_DETAIL_PP_KEYWORD_FACILITY_IS_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_HPP_ + +// Boost.Preprocessor author P. Mensodines confirmed on an Boost email thread +// (subject ``check if a token is a keyword (was "BOOST_PP_IS_UNARY()")'') +// that it is OK to used `PP_IS_UNARY()` to check if tokens match predefined +// "keyword" as it is done by the macros below (even if `PP_IS_UNARY()` is +// technically only part of Boost.Preprocessor private API). +#include <boost/preprocessor/detail/is_unary.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/tuple/eat.hpp> + +// PRIVATE // + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_(a, b) \ + BOOST_PP_IS_UNARY(BOOST_PP_CAT(a, b)) + +// PUBLIC // + +// `checking_prefix ## tokens` expand to unary (e.g., `(1)`) iff `tokens` start +// with keyword to check. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT( \ + tokens, checking_prefix) \ + BOOST_PP_IIF(BOOST_PP_IS_UNARY(tokens), \ + /* on MSVC this check works even if tokens already unary but on */ \ + /* C++03 (including GCC) this check on non-unary tokens gives */ \ + /* a concatenation error -- so return false is tokens is not unary */ \ + 0 BOOST_PP_TUPLE_EAT(2) \ + , \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_ \ + )(checking_prefix, tokens) + +// `token ## checking_postfix` expand to unary (e.g., `(1)`) iff `token` is the +// keyword to check. This check only works if `token` is a single token, it +// will always expand to 0 if token is multiple tokens (e.g., `const *this`). +// This check will expand to 0 with no error if `token` starts with a +// non-alphanumeric symbol (e.g., `*this`). +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK( \ + token, checking_postfix) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_(token, checking_postfix) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/facility/remove.hpp b/boost/local_function/detail/preprocessor/keyword/facility/remove.hpp new file mode 100644 index 0000000000..e2d2daa930 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/facility/remove.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_FACILITY_REMOVE_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_HPP_ + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/config/config.hpp> +#include <boost/preprocessor/cat.hpp> + +// PRIVATE // + +// From PP_EXPAND (my own reentrant version). +#if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() && \ + ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC() +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_(x) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_I_(x) +#else +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_(x) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_OO_((x)) +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_OO_( \ + par) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_I_ ## par +#endif +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_I_(x) x + +// PUBLIC // + +// `is_front_macro(tokens)` is 1 if `tokens` start with keyword to remove. +// `removing_prefix ## <keyword-to-remove>` must expand to nothing, else 0. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT( \ + tokens, is_front_macro, removing_prefix) \ + /* without EXPAND doesn't expand on MSVC */ \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_EXPAND_( \ + BOOST_PP_IIF(is_front_macro(tokens), \ + BOOST_PP_CAT \ + , \ + tokens BOOST_PP_TUPLE_EAT(2) \ + )(removing_prefix, tokens) \ + ) + +// `is_back_macro(tokens)` is 1 iff `tokens` end with keyword to remove. +// `<keyword-to-remove> ## removing_postfix` must expand to nothing, else 0. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK( \ + tokens, is_back_macro, removing_prefix) \ + BOOST_PP_IIF(is_back_macro(tokens), \ + BOOST_PP_CAT \ + , \ + tokens BOOST_PP_TUPLE_EAT(2) \ + )(tokens, removing_postfix) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/inline.hpp b/boost/local_function/detail/preprocessor/keyword/inline.hpp new file mode 100644 index 0000000000..59f8c499ec --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/inline.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_INLINE_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_IS_inline (1) /* unary */ +#define inline_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_inline/* nothing */ +#define inline_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE/* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT, inline) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_BACK, inline) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/recursive.hpp b/boost/local_function/detail/preprocessor/keyword/recursive.hpp new file mode 100644 index 0000000000..b299d46614 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/recursive.hpp @@ -0,0 +1,60 @@ + +// 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_DETAIL_PP_KEYWORD_RECURSIVE_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_IS_recursive (1) +#define recursive_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_IS (1) +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_recursive +#define recursive_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(tokens, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT, \ + recursive) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_BACK, \ + recursive) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/register.hpp b/boost/local_function/detail/preprocessor/keyword/register.hpp new file mode 100644 index 0000000000..881bad3bee --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/register.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_REGISTER_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_IS_register (1)/*unary*/ +#define register_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_IS (1)/*unary*/ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_register +#define register_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_FRONT, register) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_REGISTER_BACK, register) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/return.hpp b/boost/local_function/detail/preprocessor/keyword/return.hpp new file mode 100644 index 0000000000..c52ec78c58 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/return.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_RETURN_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_IS_return (1) /* unary */ +#define return_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_return /*nothing*/ +#define return_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE /*nothing*/ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_FRONT, return) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_BACK, return) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/this.hpp b/boost/local_function/detail/preprocessor/keyword/this.hpp new file mode 100644 index 0000000000..06d3486f26 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/this.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_THIS_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_IS_this (1) /* unary */ +#define this_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE_this /* nothing */ +#define this_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_FRONT, this) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THIS_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THIS_BACK, this) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp b/boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp new file mode 100644 index 0000000000..9bf543b261 --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp @@ -0,0 +1,63 @@ + +// 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_DETAIL_PP_KEYWORD_THISUNDERSCORE_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_ISthis_ (1) +#define this_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_IS (1) +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVEthis_ +#define this_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVE + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_IS) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVE_FRONT( \ + tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVE) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVE_BACK( \ + tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_ADD_FRONT( \ + tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_FRONT, \ + this_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_THISUNDERSCORE_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK, \ + this_) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/keyword/void.hpp b/boost/local_function/detail/preprocessor/keyword/void.hpp new file mode 100644 index 0000000000..14d4669bab --- /dev/null +++ b/boost/local_function/detail/preprocessor/keyword/void.hpp @@ -0,0 +1,58 @@ + +// 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_DETAIL_PP_KEYWORD_VOID_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/facility/is.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/add.hpp> +#include <boost/local_function/detail/preprocessor/keyword/facility/remove.hpp> + +// PRIVATE // + +// These are not local macros -- DO NOT #UNDEF. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_IS_void (1) /* unary */ +#define void_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_IS (1) /* unary */ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE_void /* nothing */ +#define void_BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE /* nothing */ + +// PUBLIC // + +// Is. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_IS_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_BACK(token) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_IS_BACK(token, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_IS) + +// Remove. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_FRONT, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE_) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_REMOVE_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_BACK, \ + _BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_REMOVE) + +// Add. + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_ADD_FRONT(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_FRONT(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_FRONT, void) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_VOID_ADD_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_FACILITY_ADD_BACK(tokens, \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_BACK, void) + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/line_counter.hpp b/boost/local_function/detail/preprocessor/line_counter.hpp new file mode 100644 index 0000000000..ffb90a65df --- /dev/null +++ b/boost/local_function/detail/preprocessor/line_counter.hpp @@ -0,0 +1,23 @@ + +// 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_DETAIL_PP_LINE_COUNTER_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER_HPP_ + +#include <boost/config.hpp> + +// PUBLIC // + +// MSVC has problems expanding __LINE__ so use (the non standard) __COUNTER__. +#ifdef BOOST_MSVC +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER __COUNTER__ +#else +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER __LINE__ +#endif + +#endif // #include guard + diff --git a/boost/local_function/detail/preprocessor/void_list.hpp b/boost/local_function/detail/preprocessor/void_list.hpp new file mode 100644 index 0000000000..2a302c6ea3 --- /dev/null +++ b/boost/local_function/detail/preprocessor/void_list.hpp @@ -0,0 +1,120 @@ + +// 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_DETAIL_PP_VOID_LIST_HPP_ +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HPP_ + +#include <boost/local_function/detail/preprocessor/keyword/void.hpp> +#include <boost/config.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/comparison/equal.hpp> +#include <boost/preprocessor/tuple/to_list.hpp> +#include <boost/preprocessor/seq/size.hpp> +#include <boost/preprocessor/seq/to_tuple.hpp> + +// PRIVATE // + +// Argument: (token1)... +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_FROM_SEQ_(unused, seq) \ + BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq)) + +// Token: void | token1 +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HANDLE_VOID_( \ + is_void_macro, token) \ + BOOST_PP_IIF(is_void_macro(token), \ + BOOST_PP_NIL \ + , \ + (token, BOOST_PP_NIL) \ + ) + +// Token: (a)(b)... | empty | void | token +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HANDLE_SEQ_( \ + is_void_macro, token) \ + BOOST_PP_IIF(BOOST_PP_IS_UNARY(token), /* unary paren (a)... */ \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_FROM_SEQ_ \ + , \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HANDLE_VOID_ \ + )(is_void_macro, token) + +#ifdef BOOST_NO_VARIADIC_MACROS + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_(is_void_macro, seq) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HANDLE_SEQ_(is_void_macro, seq) + +#else // VARIADICS + +// FUTURE: Replace this with BOOST_PP_VARIADIC_SIZE when and if +// BOOST_PP_VARIAIDCS detection will match !BOOST_NO_VARIADIC_MACROS (for now +// Boost.Preprocessor and Boost.Config disagree on detecting compiler variadic +// support while this VARIADIC_SIZE works on compilers not detected by PP). +#if BOOST_MSVC +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_(...) \ + BOOST_PP_CAT(BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_I_(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),) +#else // MSVC +# define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_(...) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_I_(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,) +#endif // MSVC +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_I_(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size + +// Argument: token1, ... +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_FROM_VARIADIC_(unused, ...) \ + BOOST_PP_TUPLE_TO_LIST( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_( \ + __VA_ARGS__), (__VA_ARGS__)) + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_(is_void_macro, ...) \ + BOOST_PP_IIF(BOOST_PP_EQUAL( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_VARIADIC_SIZE_( \ + __VA_ARGS__), 1), \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_HANDLE_SEQ_ \ + , \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_FROM_VARIADIC_ \ + )(is_void_macro, __VA_ARGS__) + +#endif // VARIADICS + +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_NEVER_(tokens) \ + 0 /* void check always returns false */ + +// PUBLIC // + +// NOTE: Empty list must always be represented is void (which is also a way to +// specify no function parameter) and it can never be empty because (1) +// IS_EMPTY(&var) fails (because of the leading non alphanumeric symbol) and +// (2) some compilers (MSVC) fail to correctly pass empty macro parameters +// even if they support variadic macros. Therefore, always using void to +// represent is more portable. + +#ifdef BOOST_NO_VARIADIC_MACROS + +// Expand `void | (a)(b)...` to pp-list `NIL | (a, (b, NIL))`. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(sign) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_BACK, sign) + +// Expand `(a)(b)...` to pp-list `(a, (b, NIL))`. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_NON_VOID_LIST(seq) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_NEVER_, seq) + +#else // VARIADICS + +// Expand `void | (a)(b)... | a, b, ...` to pp-list `NIL | (a, (b, NIL))`. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(...) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_VOID_BACK, __VA_ARGS__) + +// Expand `(a)(b)... | a, b, ...` to pp-list `(a, (b, NIL))`. +#define BOOST_LOCAL_FUNCTION_DETAIL_PP_NON_VOID_LIST(...) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST_NEVER_, __VA_ARGS__) + +#endif // VARIADICS + +#endif // #include guard + |