stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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