parameters.hpp

来自「support vector clustering for vc++」· HPP 代码 · 共 932 行 · 第 1/2 页

HPP
932
字号
      >::type tagged;

      // We build the arg_list incrementally as we go, prepending new
      // nodes.

      typedef typename mpl::if_<
          mpl::and_<
              is_same<Error, void_>
            , is_same<tagged, void_>
          >
        , parameter_::unmatched_argument<argument>
        , void_
      >::type error;

      typedef typename mpl::if_<
          is_same<tagged, void_>
        , ArgumentPack
        , arg_list<tagged, ArgumentPack>
      >::type argument_pack;

      typedef typename make_arg_list_aux<
          typename List::tail
        , DeducedArgs
        , TagFn
        , positional
        , typename deduced_data::second
        , argument_pack
        , error
      >::type type;
  };

#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  template <
      class List
    , class DeducedArgs
    , class TagFn
    , class Positional
    , class UsedArgs
    , class ArgumentPack
    , class Error
  >
  struct make_arg_list0
  {
      typedef typename mpl::eval_if<
          typename List::is_arg_const
        , make_arg_list00<
              List
            , DeducedArgs
            , TagFn
            , Positional
            , UsedArgs
            , ArgumentPack
            , typename List::arg const
            , Error
          >
        , make_arg_list00<
              List
            , DeducedArgs
            , TagFn
            , Positional
            , UsedArgs
            , ArgumentPack
            , typename List::arg
            , Error
          >
      >::type type;
  };
#endif

  // Returns an ArgumentPack where the list of arguments has
  // been tagged with keyword tags.
  //
  //   List: A specialization of item<> (see below). Contains
  //         both the ordered ParameterSpecs, and the given arguments.
  //
  //   DeducedArgs: A specialization of deduced_item<> (see below).
  //                A list containing only the deduced ParameterSpecs.
  //
  //   TagFn: A metafunction class used to tag positional or deduced
  //          arguments with a keyword tag.
  //
  //   Position: An mpl::bool_<> specialization indicating if positional
  //             matching is to be performed.
  //
  //   DeducedSet: An mpl::set<> containing the keyword tags used so far.
  //
  //   ArgumentPack: The ArgumentPack built so far. This is initially an
  //                 empty_arg_list and is built incrementally.
  //

  template <
      class List
    , class DeducedArgs
    , class TagFn
    , class Positional
    , class DeducedSet
    , class ArgumentPack
    , class Error
  >
  struct make_arg_list_aux
  {
      typedef typename mpl::eval_if<
          is_same<List, void_>
        , mpl::identity<mpl::pair<ArgumentPack, Error> >
        , make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error>
      >::type type;
  };

  // VC6.5 was choking on the default parameters for make_arg_list_aux, so
  // this just forwards to that adding in the defaults.
  template <
      class List
    , class DeducedArgs
    , class TagFn
    , class EmitErrors = mpl::true_
  >
  struct make_arg_list
  {
      typedef typename make_arg_list_aux<
          List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_
      >::type type;
  };

  // A parameter spec item typelist.
  template <class Spec, class Arg, class Tail = void_>
  struct item
  {
      typedef Spec spec;

#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
      typedef is_const<Arg> is_arg_const;
#endif

      typedef Arg arg;
      typedef Tail tail;
  };

  template <class Spec, class Arg, class Tail>
  struct make_item
  {
      typedef item<Spec, Arg, typename Tail::type> type;
  };

  // Creates a item typelist.
  template <class Spec, class Arg, class Tail>
  struct make_items
  {
      typedef typename mpl::eval_if<
          is_same<Arg, void_>
        , mpl::identity<void_>
        , make_item<Spec, Arg, Tail>
      >::type type;
  };

  // A typelist that stored deduced parameter specs.
  template <class ParameterSpec, class Tail = void_>
  struct deduced_item
  {
      typedef ParameterSpec spec;
      typedef Tail tail;
  };

  // Evaluate Tail and construct deduced_item list.
  template <class Spec, class Tail>
  struct make_deduced_item
  {
      typedef deduced_item<Spec, typename Tail::type> type;
  };

  template <class Spec, class Tail>
  struct make_deduced_items
  {
      typedef typename mpl::eval_if<
          is_same<Spec, void_>
        , mpl::identity<void_>
        , mpl::eval_if<
              is_deduced<Spec>
            , make_deduced_item<Spec, Tail>
            , Tail
          >
      >::type type;
  };

  // Generates:
  //
  //   make<
  //       parameter_spec#0, argument_type#0
  //     , make<
  //           parameter_spec#1, argument_type#1
  //         , ... mpl::identity<aux::empty_arg_list>
  //    ...>
  //   >
#define BOOST_PARAMETER_make_arg_list(z, n, names)      \
      BOOST_PP_SEQ_ELEM(0,names)<                       \
          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),  \
          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), 

#define BOOST_PARAMETER_right_angle(z, n, text) >

#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type)      \
  BOOST_PP_REPEAT(                                                                  \
      n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type))      \
      mpl::identity<void_>                                                          \
  BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)

#define BOOST_PARAMETER_make_deduced_list(z, n, names)  \
      BOOST_PP_SEQ_ELEM(0,names)<                       \
          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),

#define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec)                 \
  BOOST_PP_REPEAT(                                                                  \
      n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec))                 \
  mpl::identity<void_>                                                              \
  BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)

  struct tag_keyword_arg
  {
      template <class K, class T>
      struct apply
        : tag<K,T>
      {};
  };

  struct tag_template_keyword_arg
  {
      template <class K, class T>
      struct apply
      {
          typedef template_keyword<K,T> type;
      };
  };

} // namespace aux

#define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \
    typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i);

#define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \
    BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest))


#define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_

template<
     class PS0
   , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _)
>
struct parameters
{
#undef BOOST_PARAMETER_TEMPLATE_ARGS

    typedef typename BOOST_PARAMETER_build_deduced_list(
        BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS
    )::type deduced_list;

    // if the elements of NamedList match the criteria of overload
    // resolution, returns a type which can be constructed from
    // parameters.  Otherwise, this is not a valid metafunction (no nested
    // ::type).


#ifndef BOOST_NO_SFINAE
    // If NamedList satisfies the PS0, PS1, ..., this is a
    // metafunction returning parameters.  Otherwise it 
    // has no nested ::type.
    template <class ArgumentPackAndError>
    struct match_base
      : mpl::if_<
            // mpl::and_<
            //    aux::satisfies_requirements_of<NamedList,PS0>
            //  , mpl::and_<
            //       aux::satisfies_requirements_of<NamedList,PS1>...
            //           ..., mpl::true_
            // ...> >
            
# define BOOST_PARAMETER_satisfies(z, n, text)                                      \
            mpl::and_<                                                              \
                aux::satisfies_requirements_of<                                     \
                    typename mpl::first<ArgumentPackAndError>::type                 \
                  , BOOST_PP_CAT(PS, n)>                                            \
                  ,
            mpl::and_<
                is_same<typename mpl::second<ArgumentPackAndError>::type, void_>
              , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
                mpl::true_
                BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
            >

# undef BOOST_PARAMETER_satisfies

          , mpl::identity<parameters>
          , void_
        >
    {};
#endif
    
    // Specializations are to be used as an optional argument to
    // eliminate overloads via SFINAE
    template<
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
        // Borland simply can't handle default arguments in member
        // class templates.  People wishing to write portable code can
        // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
#else 
        BOOST_PP_ENUM_BINARY_PARAMS(
            BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
        )
#endif
    >
    struct match
# ifndef BOOST_NO_SFINAE
      : match_base<
            typename aux::make_arg_list<
                typename BOOST_PARAMETER_build_arg_list(
                    BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
                )::type
              , deduced_list
              , aux::tag_keyword_arg
              , mpl::false_ // Don't emit errors when doing SFINAE
            >::type
        >::type
    {};
# else
    { 
        typedef parameters<
            BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)
        > type; 
    };
# endif

    // Metafunction that returns an ArgumentPack.

    // TODO, bind has to instantiate the error type in the result
    // of make_arg_list.

    template <
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
        // Borland simply can't handle default arguments in member
        // class templates.  People wishing to write portable code can
        // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
#else 
        BOOST_PP_ENUM_BINARY_PARAMS(
            BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
        )
#endif            
    >
    struct bind
    {
        typedef typename aux::make_arg_list<
            typename BOOST_PARAMETER_build_arg_list(
                BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
            )::type
          , deduced_list
          , aux::tag_template_keyword_arg
        >::type result;

        typedef typename mpl::first<result>::type type;
    };

    BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec)

    //
    // The function call operator is used to build an arg_list that
    // labels the positional parameters and maintains whatever other
    // tags may have been specified by the caller.
    //
    // !!!NOTE!!!
    //
    // The make_arg_list<> produces a reversed arg_list, so
    // we need to pass the arguments to it's constructor
    // reversed.
    //
    aux::empty_arg_list operator()() const
    {
       return aux::empty_arg_list();
    }

    template<class A0>
    typename mpl::first<
        typename aux::make_arg_list<
            aux::item<
                PS0,A0
            >
          , deduced_list
          , aux::tag_keyword_arg
        >::type
    >::type
    operator()(A0& a0) const
    {
        typedef typename aux::make_arg_list<
            aux::item<
                PS0,A0
            >
          , deduced_list
          , aux::tag_keyword_arg
        >::type result;

        typedef typename mpl::first<result>::type result_type;
        typedef typename mpl::second<result>::type error;
        error();

        return result_type(
            a0
            // , void_(), void_(), void_() ...
            BOOST_PP_ENUM_TRAILING_PARAMS(
                BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
              , aux::void_reference() BOOST_PP_INTERCEPT)
        );
    }

    template<class A0, class A1>
    typename mpl::first<
        typename aux::make_arg_list<
            aux::item<
                PS0,A0
              , aux::item<
                    PS1,A1
                >
            >
          , deduced_list
          , aux::tag_keyword_arg
        >::type
    >::type
    operator()(A0& a0, A1& a1) const
    {
        typedef typename aux::make_arg_list<
            aux::item<
                PS0,A0
              , aux::item<
                    PS1,A1
                >
            >
          , deduced_list
          , aux::tag_keyword_arg
        >::type result;

        typedef typename mpl::first<result>::type result_type;
        typedef typename mpl::second<result>::type error;
        error();

        return result_type(
            a1,a0
            // , void_(), void_() ...
            BOOST_PP_ENUM_TRAILING_PARAMS(
                BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
              , aux::void_reference() BOOST_PP_INTERCEPT)
        );
    }

    // Higher arities are handled by the preprocessor
#define BOOST_PP_ITERATION_PARAMS_1 (3,( \
        3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \
    ))
#include BOOST_PP_ITERATE()

};

} // namespace parameter

} // namespace boost

#endif // BOOST_PARAMETERS_031014_HPP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?