⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 composite.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 4 页
字号:
/*=============================================================================
    Phoenix V1.2.1
    Copyright (c) 2001-2002 Joel de Guzman

    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 PHOENIX_COMPOSITE_HPP
#define PHOENIX_COMPOSITE_HPP

///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/phoenix/actor.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace phoenix {

///////////////////////////////////////////////////////////////////////////////
//
//  composite class
//
//      A composite is an actor base class composed of zero or more
//      actors (see actor.hpp) and an operation. A composite is itself
//      an actor superclass and conforms to its conceptual interface.
//      Its eval member function un-funnels the tupled actual arguments
//      from the tuple by invoking each of the actors' eval member
//      function. The results of each are then passed on as arguments to
//      the operation. Specializations are provided to handle different
//      numbers of actors.
//
//      Schematically:
//
//          actor0.eval(tupled_args) --> arg0 --> |
//          actor1.eval(tupled_args) --> arg1 --> |
//          actor2.eval(tupled_args) --> arg3 --> | --> operation(arg0...argN)
//            ...                                 |
//          actorN.eval(tupled_args) --> argN --> |
//
//      The operation can be any suitable functor that can accept the
//      arguments passed in by the composite. The operation is expected
//      to have a member operator() that carries out the actual
//      operation. There should be a one to one correspondence between
//      actors of the composite and the arguments of the operation's
//      member operator().
//
//      The operation is also expected to have a nested template class
//      result<T0...TN>. The nested template class result should have a
//      typedef 'type' that reflects the return type of its member
//      operator(). This is essentially a type computer that answers the
//      metaprogramming question "Given arguments of type T0...TN, what
//      will be its operator()'s return type?".
//
//      There is a special case for operations that accept no arguments.
//      Such nullary operations are only required to define a typedef
//      result_type that reflects the return type of its operator().
//
//      Here's an example of a simple operation that squares a number:
//
//          struct square {
//
//              template <typename ArgT>
//              struct result { typedef ArgT type; };
//
//              template <typename ArgT>
//              ArgT operator()(ArgT n) const { return n * n; }
//          };
//
//      As can be seen, operations can be polymorphic. Its arguments and
//      return type are not fixed to a particular type. The example
//      above for example, can handle any ArgT type as long as it has a
//      multiplication operator.
//
//      Composites are not created directly. Instead, there are meta-
//      programs provided that indirectly create composites. See
//      operators.hpp, binders.hpp and functions.hpp for examples.
//
///////////////////////////////////////////////////////////////////////////////
template <
    typename OperationT
    ,   typename A = nil_t
    ,   typename B = nil_t
    ,   typename C = nil_t

#if PHOENIX_LIMIT > 3
    ,   typename D = nil_t
    ,   typename E = nil_t
    ,   typename F = nil_t

#if PHOENIX_LIMIT > 6
    ,   typename G = nil_t
    ,   typename H = nil_t
    ,   typename I = nil_t

#if PHOENIX_LIMIT > 9
    ,   typename J = nil_t
    ,   typename K = nil_t
    ,   typename L = nil_t

#if PHOENIX_LIMIT > 12
    ,   typename M = nil_t
    ,   typename N = nil_t
    ,   typename O = nil_t

#endif
#endif
#endif
#endif

    ,   typename NU = nil_t  // Not used
>
struct composite;

///////////////////////////////////////////////////////////////////////////////
//
//  composite <0 actor> class
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT, typename TupleT>
struct composite0_result {

    typedef typename OperationT::result_type type;
};

//////////////////////////////////
template <typename OperationT>
struct composite<OperationT,
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 3
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 6
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 9
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 12
    nil_t, nil_t, nil_t,
#endif
#endif
#endif
#endif
    nil_t   //  Unused
> {

    typedef composite<OperationT> self_t;

    template <typename TupleT>
    struct result {

        typedef typename composite0_result<
            OperationT, TupleT
        >::type type;
    };

    composite(OperationT const& op_)
    :   op(op_) {}

    template <typename TupleT>
    typename OperationT::result_type
    eval(TupleT const& /*args*/) const
    {
        return op();
    }

    mutable OperationT op; //  operation
};

///////////////////////////////////////////////////////////////////////////////
//
//  composite <1 actor> class
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT, typename TupleT,
    typename A>
struct composite1_result {

    typedef typename OperationT::template result<
        typename actor_result<A, TupleT>::plain_type
    >::type type;
};

//////////////////////////////////
template <typename OperationT,
    typename A>
struct composite<OperationT,
    A, nil_t, nil_t,
#if PHOENIX_LIMIT > 3
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 6
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 9
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 12
    nil_t, nil_t, nil_t,
#endif
#endif
#endif
#endif
    nil_t   //  Unused
> {

    typedef composite<OperationT, A> self_t;

    template <typename TupleT>
    struct result {

        typedef typename composite1_result<
            OperationT, TupleT, A
        >::type type;
    };

    composite(OperationT const& op_,
        A const& a_)
    :   op(op_), a(a_) {}

    template <typename TupleT>
    typename actor_result<self_t, TupleT>::type
    eval(TupleT const& args) const
    {
        typename actor_result<A, TupleT>::type ra = a.eval(args);
        return op(ra);
    }

    mutable OperationT op; //  operation
    A a; //  actors
};

///////////////////////////////////////////////////////////////////////////////
//
//  composite <2 actors> class
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT, typename TupleT,
    typename A, typename B>
struct composite2_result {

    typedef typename OperationT::template result<
        typename actor_result<A, TupleT>::plain_type,
        typename actor_result<B, TupleT>::plain_type
    >::type type;
};

//////////////////////////////////
template <typename OperationT,
    typename A, typename B>
struct composite<OperationT,
    A, B, nil_t,
#if PHOENIX_LIMIT > 3
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 6
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 9
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 12
    nil_t, nil_t, nil_t,
#endif
#endif
#endif
#endif
    nil_t   //  Unused
> {

    typedef composite<OperationT, A, B> self_t;

    template <typename TupleT>
    struct result {

        typedef typename composite2_result<
            OperationT, TupleT, A, B
        >::type type;
    };

    composite(OperationT const& op_,
        A const& a_, B const& b_)
    :   op(op_), a(a_), b(b_) {}

    template <typename TupleT>
    typename actor_result<self_t, TupleT>::type
    eval(TupleT const& args) const
    {
        typename actor_result<A, TupleT>::type ra = a.eval(args);
        typename actor_result<B, TupleT>::type rb = b.eval(args);
        return op(ra, rb);
    }

    mutable OperationT op; //  operation
    A a; B b; //  actors
};

///////////////////////////////////////////////////////////////////////////////
//
//  composite <3 actors> class
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT, typename TupleT,
    typename A, typename B, typename C>
struct composite3_result {

    typedef typename OperationT::template result<
        typename actor_result<A, TupleT>::plain_type,
        typename actor_result<B, TupleT>::plain_type,
        typename actor_result<C, TupleT>::plain_type
    >::type type;
};

//////////////////////////////////
template <typename OperationT,
    typename A, typename B, typename C>
struct composite<OperationT,
    A, B, C,
#if PHOENIX_LIMIT > 3
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 6
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 9
    nil_t, nil_t, nil_t,
#if PHOENIX_LIMIT > 12
    nil_t, nil_t, nil_t,
#endif
#endif
#endif
#endif
    nil_t   //  Unused
> {

    typedef composite<OperationT, A, B, C> self_t;

    template <typename TupleT>
    struct result {

        typedef typename composite3_result<
            OperationT, TupleT, A, B, C
        >::type type;
    };

    composite(OperationT const& op_,
        A const& a_, B const& b_, C const& c_)
    :   op(op_), a(a_), b(b_), c(c_) {}

    template <typename TupleT>
    typename actor_result<self_t, TupleT>::type
    eval(TupleT const& args) const
    {
        typename actor_result<A, TupleT>::type ra = a.eval(args);
        typename actor_result<B, TupleT>::type rb = b.eval(args);
        typename actor_result<C, TupleT>::type rc = c.eval(args);
        return op(ra, rb, rc);
    }

    mutable OperationT op; //  operation
    A a; B b; C c; //  actors
};

#if PHOENIX_LIMIT > 3
///////////////////////////////////////////////////////////////////////////////
//
//  composite <4 actors> class
//

⌨️ 快捷键说明

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