preprocessor.hpp
来自「support vector clustering for vc++」· HPP 代码 · 共 1,170 行 · 第 1/3 页
HPP
1,170 行
// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_PREPROCESSOR_060206_HPP
# define BOOST_PARAMETER_PREPROCESSOR_060206_HPP
# include <boost/parameter/parameters.hpp>
# include <boost/parameter/binding.hpp>
# include <boost/parameter/match.hpp>
# include <boost/parameter/aux_/parenthesized_type.hpp>
# include <boost/parameter/aux_/cast.hpp>
# include <boost/parameter/aux_/preprocessor/flatten.hpp>
# include <boost/preprocessor/repetition/repeat_from_to.hpp>
# include <boost/preprocessor/control/if.hpp>
# include <boost/preprocessor/control/expr_if.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/preprocessor/repetition/enum_trailing.hpp>
# include <boost/preprocessor/seq/first_n.hpp>
# include <boost/preprocessor/seq/for_each_product.hpp>
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/seq/fold_left.hpp>
# include <boost/preprocessor/seq/size.hpp>
# include <boost/preprocessor/seq/enum.hpp>
# include <boost/preprocessor/detail/is_nullary.hpp>
# include <boost/mpl/always.hpp>
# include <boost/mpl/apply_wrap.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# include <boost/type.hpp>
# endif
namespace boost { namespace parameter { namespace aux {
# ifndef BOOST_NO_SFINAE
// Given Match, which is "void x" where x is an argument matching
// criterion, extract a corresponding MPL predicate.
template <class Match>
struct unwrap_predicate;
// Match anything
template <>
struct unwrap_predicate<void*>
{
typedef mpl::always<mpl::true_> type;
};
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
typedef void* voidstar;
// A matching predicate is explicitly specified
template <class Predicate>
struct unwrap_predicate<voidstar (Predicate)>
{
typedef Predicate type;
};
#else
// A matching predicate is explicitly specified
template <class Predicate>
struct unwrap_predicate<void *(Predicate)>
{
typedef Predicate type;
};
#endif
// A type to which the argument is supposed to be convertible is
// specified
template <class Target>
struct unwrap_predicate<void (Target)>
{
typedef is_convertible<mpl::_, Target> type;
};
// Recast the ParameterSpec's nested match metafunction as a free metafunction
template <
class Parameters
, BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
)
>
struct match
: Parameters::template match<
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, A)
>
{};
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
// Function template argument deduction does many of the same things
// as type matching during partial specialization, so we call a
// function template to "store" T into the type memory addressed by
// void(*)(T).
template <class T>
msvc_store_type<T,void*(*)(void**(T))>
msvc_store_predicate_type(void*(*)(void**(T)));
template <class T>
msvc_store_type<boost::is_convertible<mpl::_,T>,void*(*)(void*(T))>
msvc_store_predicate_type(void*(*)(void*(T)));
template <class FunctionType>
struct unwrap_predicate
{
static FunctionType f;
// We don't want the function to be evaluated, just instantiated,
// so protect it inside of sizeof.
enum { dummy = sizeof(msvc_store_predicate_type(f)) };
// Now pull the type out of the instantiated base class
typedef typename msvc_type_memory<FunctionType>::storage::type type;
};
template <>
struct unwrap_predicate<void*(*)(void**)>
{
typedef mpl::always<mpl::true_> type;
};
# endif
# undef false_
template <
class Parameters
, BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
)
>
struct argument_pack
{
typedef typename make_arg_list<
typename BOOST_PARAMETER_build_arg_list(
BOOST_PARAMETER_MAX_ARITY, make_items, typename Parameters::parameter_spec, A
)::type
, typename Parameters::deduced_list
, tag_keyword_arg
, mpl::false_
>::type type;
};
# if 1 //BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Works around VC6 problem where it won't accept rvalues.
template <class T>
T& as_lvalue(T& value, long)
{
return value;
}
template <class T>
T const& as_lvalue(T const& value, int)
{
return value;
}
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Predicate, class T, class Args>
struct apply_predicate
{
BOOST_MPL_ASSERT((
mpl::and_<mpl::false_,T>
));
typedef typename mpl::if_<
typename mpl::apply2<Predicate,T,Args>::type
, char
, int
>::type type;
};
template <class P>
struct funptr_predicate
{
static P p;
template <class T, class Args, class P0>
static typename apply_predicate<P0,T,Args>::type
check_predicate(type<T>, Args*, void**(*)(P0));
template <class T, class Args, class P0>
static typename mpl::if_<
is_convertible<T,P0>
, char
, int
>::type check_predicate(type<T>, Args*, void*(*)(P0));
template <class T, class Args>
struct apply
{
BOOST_STATIC_CONSTANT(bool, result =
sizeof(check_predicate(boost::type<T>(), (Args*)0, &p)) == 1
);
typedef mpl::bool_<apply<T,Args>::result> type;
};
};
template <>
struct funptr_predicate<void**>
: mpl::always<mpl::true_>
{};
# endif
}}} // namespace boost::parameter::aux
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// From Paul Mensonides
# define BOOST_PARAMETER_IS_NULLARY(x) \
BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_NULLARY_C x BOOST_PP_COMMA() 0) \
/**/
# define BOOST_PARAMETER_IS_NULLARY_C() \
~, 1 BOOST_PP_RPAREN() \
BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \
/**/
# else
# define BOOST_PARAMETER_IS_NULLARY(x) BOOST_PP_IS_NULLARY(x)
# endif
# define BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_static ()
# define BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
BOOST_PARAMETER_IS_NULLARY( \
BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_,name) \
)
# if !defined(BOOST_MSVC)
# define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static
# define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \
BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name)
# else
// Workaround for MSVC preprocessor.
//
// When stripping static from "static f", msvc will produce
// " f". The leading whitespace doesn't go away when pasting
// the token with something else, so this thing is a hack to
// strip the whitespace.
# define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static (
# define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \
BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name))
# define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \
BOOST_PP_SEQ_HEAD( \
BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \
)
# endif
# define BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
BOOST_PP_EXPR_IF( \
BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
, static \
)
# define BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \
BOOST_PP_IF( \
BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
, BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC \
, name BOOST_PP_TUPLE_EAT(1) \
)(name)
// Calculates [begin, end) arity range.
# define BOOST_PARAMETER_ARITY_RANGE_M_optional(state) state
# define BOOST_PARAMETER_ARITY_RANGE_M_deduced_optional(state) state
# define BOOST_PARAMETER_ARITY_RANGE_M_required(state) BOOST_PP_INC(state)
# define BOOST_PARAMETER_ARITY_RANGE_M_deduced_required(state) BOOST_PP_INC(state)
# define BOOST_PARAMETER_ARITY_RANGE_M(s, state, x) \
BOOST_PP_CAT( \
BOOST_PARAMETER_ARITY_RANGE_M_ \
, BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
)(state)
/**/
# define BOOST_PARAMETER_ARITY_RANGE(args) \
( \
BOOST_PP_SEQ_FOLD_LEFT(BOOST_PARAMETER_ARITY_RANGE_M, 0, args) \
, BOOST_PP_INC(BOOST_PP_SEQ_SIZE(args)) \
)
/**/
// Accessor macros for the argument specs tuple.
# define BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
BOOST_PP_TUPLE_ELEM(4,0,x)
/**/
# define BOOST_PARAMETER_FN_ARG_NAME(x) \
BOOST_PP_TUPLE_ELEM(4,1,x)
/**/
# define BOOST_PARAMETER_FN_ARG_PRED(x) \
BOOST_PP_TUPLE_ELEM(4,2,x)
/**/
# define BOOST_PARAMETER_FN_ARG_DEFAULT(x) \
BOOST_PP_TUPLE_ELEM(4,3,x)
/**/
# define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_out(x)
# define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_in_out(x)
// Returns 1 if x is either "out(k)" or "in_out(k)".
# define BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
BOOST_PP_IS_EMPTY( \
BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_, x) \
) \
/**/
# define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_out(x) x
# define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_in_out(x) x
# define BOOST_PARAMETER_FUNCTION_KEYWORD_GET(x) \
BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_, x)
/**/
// Returns the keyword of x, where x is either a keyword qualifier
// or a keyword.
//
// k => k
// out(k) => k
// in_out(k) => k
//
# define BOOST_PARAMETER_FUNCTION_KEYWORD(x) \
BOOST_PP_IF( \
BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
, BOOST_PARAMETER_FUNCTION_KEYWORD_GET \
, x BOOST_PP_TUPLE_EAT(1) \
)(x)
/**/
# define BOOST_PARAMETER_FN_ARG_KEYWORD(x) \
BOOST_PARAMETER_FUNCTION_KEYWORD( \
BOOST_PARAMETER_FN_ARG_NAME(x) \
)
// Builds forwarding functions.
# define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z(z, n) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, class ParameterArgumentType)>
/**/
# ifndef BOOST_NO_SFINAE
# define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n) \
, typename boost::parameter::aux::match< \
parameters, BOOST_PP_ENUM_PARAMS(n, ParameterArgumentType) \
>::type boost_parameter_enabler_argument = parameters()
# else
# define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n)
# endif
/**/
# define BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(base) \
BOOST_PP_CAT( \
boost_param_parameters_ \
, BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
)
// Produce a name for a result type metafunction for the function
// named base
# define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base) \
BOOST_PP_CAT( \
boost_param_result_ \
, BOOST_PP_CAT(__LINE__,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
)
// Can't do boost_param_impl_ ## basee because base might start with an underscore
// daniel: what? how is that relevant? the reason for using CAT() is to make sure
// base is expanded. i'm not sure we need to here, but it's more stable to do it.
# define BOOST_PARAMETER_IMPL(base) \
BOOST_PP_CAT(boost_param_impl,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base))
# define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00(z, n, r, data, elem) \
BOOST_PP_IF( \
n \
, BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \
)(z,n) \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?