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 + -
显示快捷键?