📄 composite.hpp
字号:
/*=============================================================================
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 + -