stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,604 @@
/*=============================================================================
Phoenix v1.2
Copyright (c) 2001-2002 Joel de Guzman
Distributed under 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_ACTOR_HPP
#define PHOENIX_ACTOR_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
// These are forward declared here because we cannot include impl.hpp
// or operators.hpp yet but the actor's assignment operator and index
// operator are required to be members.
//////////////////////////////////
struct assign_op;
struct index_op;
//////////////////////////////////
namespace impl {
template <typename OperationT, typename BaseT, typename B>
struct make_binary1;
}
///////////////////////////////////////////////////////////////////////////////
//
// unpack_tuple class
//
// This class is used to unpack a supplied tuple such, that the members of
// this tuple will be handled as if they would be supplied separately.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TupleT>
struct unpack_tuple : public TupleT {
typedef TupleT tuple_t;
unpack_tuple() {}
unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
};
///////////////////////////////////////////////////////////////////////////////
//
// actor class
//
// This class is a protocol class for all actors. This class is
// essentially an interface contract. The actor class does not
// really know how how to act on anything but instead relies on the
// template parameter BaseT (from which the actor will derive from)
// to do the actual action.
//
// An actor is a functor that is capable of accepting arguments up
// to a predefined maximum. It is up to the base class to do the
// actual processing or possibly to limit the arity (no. of
// arguments) passed in. Upon invocation of the functor through a
// supplied operator(), the actor funnels the arguments passed in
// by the client into a tuple and calls the base eval member
// function.
//
// Schematically:
//
// arg0 ---------|
// arg1 ---------|
// arg2 ---------|---> tupled_args ---> base.eval
// ... |
// argN ---------|
//
// actor::operator()(arg0, arg1... argN)
// ---> BaseT::eval(tupled_args);
//
// Actor base classes from which this class inherits from are
// expected to have a corresponding member function eval compatible
// with the conceptual Interface:
//
// template <typename TupleT>
// actor_return_type
// eval(TupleT const& args) const;
//
// where args are the actual arguments passed in by the client
// funneled into a tuple (see tuple.hpp for details).
//
// The actor_return_type can be anything. Base classes are free to
// return any type, even argument dependent types (types that are
// deduced from the types of the arguments). After evaluating the
// parameters and doing some computations or actions, the eval
// member function concludes by returning something back to the
// client. To do this, the forwarding function (the actor's
// operator()) needs to know the return type of the eval member
// function that it is calling. For this purpose, actor base
// classes are required to provide a nested template class:
//
// template <typename TupleT>
// struct result;
//
// This auxiliary class provides the result type information
// returned by the eval member function of a base actor class. The
// nested template class result should have a typedef 'type' that
// reflects the return type of its member function eval. It is
// basically a type computer that answers the question "given
// arguments packed into a TupleT type, what will be the result
// type of the eval member function of ActorT?". The template class
// actor_result queries this to extract the return type of an
// actor. Example:
//
// typedef typename actor_result<ActorT, TupleT>::type
// actor_return_type;
//
// where actor_return_type is the actual type returned by ActorT's
// eval member function given some arguments in a TupleT.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ActorT, typename TupleT>
struct actor_result {
typedef typename ActorT::template result<TupleT>::type type;
typedef typename remove_reference<type>::type plain_type;
};
//////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
template <typename BaseT>
struct actor : public BaseT {
actor();
actor(BaseT const& base);
typename actor_result<BaseT, tuple<> >::type
operator()() const;
template <typename A>
typename actor_result<BaseT, tuple<A&> >::type
operator()(A& a) const;
template <typename A, typename B>
typename actor_result<BaseT, tuple<A&, B&> >::type
operator()(A& a, B& b) const;
template <typename A, typename B, typename C>
typename actor_result<BaseT, tuple<A&, B&, C&> >::type
operator()(A& a, B& b, C& c) const;
#if PHOENIX_LIMIT > 3
template <typename A, typename B, typename C, typename D>
typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
operator()(A& a, B& b, C& c, D& d) const;
template <typename A, typename B, typename C, typename D, typename E>
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
operator()(A& a, B& b, C& c, D& d, E& e) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F>
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
#if PHOENIX_LIMIT > 6
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G>
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
>::type
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
>::type
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
#if PHOENIX_LIMIT > 9
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
K& k) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
K& k, L& l) const;
#if PHOENIX_LIMIT > 12
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
K& k, L& l, M& m) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
K& k, L& l, M& m, N& n) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N, typename O>
typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
>::type
operator()(
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
K& k, L& l, M& m, N& n, O& o) const;
#endif
#endif
#endif
#endif
template <typename TupleT>
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
operator()(unpack_tuple<TupleT> const &t) const;
template <typename B>
typename impl::make_binary1<assign_op, BaseT, B>::type
operator=(B const& b) const;
template <typename B>
typename impl::make_binary1<index_op, BaseT, B>::type
operator[](B const& b) const;
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
///////////////////////////////////////////////////////////////////////////
//
// as_actor
//
// as_actor is a meta-program that converts an arbitrary type into
// an actor. All participants in the framework must be first-class
// actors. This meta-program is used all throughout the framework
// whenever an unknown type needs to be converted to an actor.
// as_actor specializations are expected to have a typedef 'type'.
// This is the destination actor type. A static member function
// 'convert' converts an object to this target type.
//
// The meta-program does no conversion if the object to be
// converted is already an actor.
//
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct as_actor;
//////////////////////////////////
template <typename BaseT>
struct as_actor<actor<BaseT> > {
typedef actor<BaseT> type;
static type convert(actor<BaseT> const& x) { return x; }
};
//////////////////////////////////
template <>
struct as_actor<nil_t> {
typedef nil_t type;
static nil_t convert(nil_t /*x*/)
{ return nil_t(); }
};
//////////////////////////////////
template <>
struct as_actor<void> {
typedef void type;
// ERROR!!!
};
///////////////////////////////////////////////////////////////////////////////
//
// actor class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename BaseT>
actor<BaseT>::actor()
: BaseT() {}
//////////////////////////////////
template <typename BaseT>
actor<BaseT>::actor(BaseT const& base)
: BaseT(base) {}
//////////////////////////////////
template <typename BaseT>
inline typename actor_result<BaseT, tuple<> >::type
actor<BaseT>::operator()() const
{
return BaseT::eval(tuple<>());
}
//////////////////////////////////
template <typename BaseT>
template <typename A>
inline typename actor_result<BaseT, tuple<A&> >::type
actor<BaseT>::operator()(A& a_) const
{
return BaseT::eval(tuple<A&>(a_));
}
//////////////////////////////////
template <typename BaseT>
template <typename A, typename B>
inline typename actor_result<BaseT, tuple<A&, B&> >::type
actor<BaseT>::operator()(A& a_, B& b_) const
{
return BaseT::eval(tuple<A&, B&>(a_, b_));
}
//////////////////////////////////
template <typename BaseT>
template <typename A, typename B, typename C>
inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
actor<BaseT>::operator()(A& a_, B& b_, C& c_) const
{
return BaseT::eval(tuple<A&, B&, C&>(a_, b_, c_));
}
#if PHOENIX_LIMIT > 3
//////////////////////////////////
template <typename BaseT>
template <typename A, typename B, typename C, typename D>
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_) const
{
return BaseT::eval(tuple<A&, B&, C&, D&>(a_, b_, c_, d_));
}
//////////////////////////////////
template <typename BaseT>
template <typename A, typename B, typename C, typename D, typename E>
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
actor<BaseT>::operator()(A& a_, B& b_, C& c_, D& d_, E& e_) const
{
return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a_, b_, c_, d_, e_));
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&>
(a_, b_, c_, d_, e_, f_)
);
}
#if PHOENIX_LIMIT > 6
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&>
(a_, b_, c_, d_, e_, f_, g_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
(a_, b_, c_, d_, e_, f_, g_, h_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_)
);
}
#if PHOENIX_LIMIT > 9
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
K& k_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
K& k_, L& l_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_)
);
}
#if PHOENIX_LIMIT > 12
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
K& k_, L& l_, M& m_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
K& k_, L& l_, M& m_, N& n_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_)
);
}
//////////////////////////////////
template <typename BaseT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N, typename O>
inline typename actor_result<BaseT,
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
>::type
actor<BaseT>::operator()(
A& a_, B& b_, C& c_, D& d_, E& e_, F& f_, G& g_, H& h_, I& i_, J& j_,
K& k_, L& l_, M& m_, N& n_, O& o_
) const
{
return BaseT::eval(
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_)
);
}
#endif
#endif
#endif
#endif
//////////////////////////////////
template <typename BaseT>
template <typename TupleT>
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
{
return BaseT::eval(t);
}
///////////////////////////////////////////////////////////////////////////////
} // namespace phoenix
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,450 @@
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
MT code Copyright (c) 2002-2003 Martin Wille
Distributed under 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 CLASSIC_PHOENIX_CLOSURES_HPP
#define CLASSIC_PHOENIX_CLOSURES_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/actor.hpp>
#include <boost/assert.hpp>
#ifdef PHOENIX_THREADSAFE
#include <boost/thread/tss.hpp>
#include <boost/thread/once.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Adaptable closures
//
// The framework will not be complete without some form of closures
// support. Closures encapsulate a stack frame where local
// variables are created upon entering a function and destructed
// upon exiting. Closures provide an environment for local
// variables to reside. Closures can hold heterogeneous types.
//
// Phoenix closures are true hardware stack based closures. At the
// very least, closures enable true reentrancy in lambda functions.
// A closure provides access to a function stack frame where local
// variables reside. Modeled after Pascal nested stack frames,
// closures can be nested just like nested functions where code in
// inner closures may access local variables from in-scope outer
// closures (accessing inner scopes from outer scopes is an error
// and will cause a run-time assertion failure).
//
// There are three (3) interacting classes:
//
// 1) closure:
//
// At the point of declaration, a closure does not yet create a
// stack frame nor instantiate any variables. A closure declaration
// declares the types and names[note] of the local variables. The
// closure class is meant to be subclassed. It is the
// responsibility of a closure subclass to supply the names for
// each of the local variable in the closure. Example:
//
// struct my_closure : closure<int, string, double> {
//
// member1 num; // names the 1st (int) local variable
// member2 message; // names the 2nd (string) local variable
// member3 real; // names the 3rd (double) local variable
// };
//
// my_closure clos;
//
// Now that we have a closure 'clos', its local variables can be
// accessed lazily using the dot notation. Each qualified local
// variable can be used just like any primitive actor (see
// primitives.hpp). Examples:
//
// clos.num = 30
// clos.message = arg1
// clos.real = clos.num * 1e6
//
// The examples above are lazily evaluated. As usual, these
// expressions return composite actors that will be evaluated
// through a second function call invocation (see operators.hpp).
// Each of the members (clos.xxx) is an actor. As such, applying
// the operator() will reveal its identity:
//
// clos.num() // will return the current value of clos.num
//
// *** [note] Acknowledgement: Juan Carlos Arevalo-Baeza (JCAB)
// introduced and initilally implemented the closure member names
// that uses the dot notation.
//
// 2) closure_member
//
// The named local variables of closure 'clos' above are actually
// closure members. The closure_member class is an actor and
// conforms to its conceptual interface. member1..memberN are
// predefined typedefs that correspond to each of the listed types
// in the closure template parameters.
//
// 3) closure_frame
//
// When a closure member is finally evaluated, it should refer to
// an actual instance of the variable in the hardware stack.
// Without doing so, the process is not complete and the evaluated
// member will result to an assertion failure. Remember that the
// closure is just a declaration. The local variables that a
// closure refers to must still be instantiated.
//
// The closure_frame class does the actual instantiation of the
// local variables and links these variables with the closure and
// all its members. There can be multiple instances of
// closure_frames typically situated in the stack inside a
// function. Each closure_frame instance initiates a stack frame
// with a new set of closure local variables. Example:
//
// void foo()
// {
// closure_frame<my_closure> frame(clos);
// /* do something */
// }
//
// where 'clos' is an instance of our closure 'my_closure' above.
// Take note that the usage above precludes locally declared
// classes. If my_closure is a locally declared type, we can still
// use its self_type as a paramater to closure_frame:
//
// closure_frame<my_closure::self_type> frame(clos);
//
// Upon instantiation, the closure_frame links the local variables
// to the closure. The previous link to another closure_frame
// instance created before is saved. Upon destruction, the
// closure_frame unlinks itself from the closure and relinks the
// preceding closure_frame prior to this instance.
//
// The local variables in the closure 'clos' above is default
// constructed in the stack inside function 'foo'. Once 'foo' is
// exited, all of these local variables are destructed. In some
// cases, default construction is not desirable and we need to
// initialize the local closure variables with some values. This
// can be done by passing in the initializers in a compatible
// tuple. A compatible tuple is one with the same number of
// elements as the destination and where each element from the
// destination can be constructed from each corresponding element
// in the source. Example:
//
// tuple<int, char const*, int> init(123, "Hello", 1000);
// closure_frame<my_closure> frame(clos, init);
//
// Here now, our closure_frame's variables are initialized with
// int: 123, char const*: "Hello" and int: 1000.
//
///////////////////////////////////////////////////////////////////////////////
namespace impl
{
///////////////////////////////////////////////////////////////////////
// closure_frame_holder is a simple class that encapsulates the
// storage for a frame pointer. It uses thread specific data in
// case when multithreading is enabled, an ordinary pointer otherwise
//
// it has get() and set() member functions. set() has to be used
// _after_ get(). get() contains intialisation code in the multi
// threading case
//
// closure_frame_holder is used by the closure<> class to store
// the pointer to the current frame.
//
#ifndef PHOENIX_THREADSAFE
template <typename FrameT>
struct closure_frame_holder
{
typedef FrameT frame_t;
typedef frame_t *frame_ptr;
closure_frame_holder() : frame(0) {}
frame_ptr &get() { return frame; }
void set(frame_t *f) { frame = f; }
private:
frame_ptr frame;
// no copies, no assignments
closure_frame_holder(closure_frame_holder const &);
closure_frame_holder &operator=(closure_frame_holder const &);
};
#else
template <typename FrameT>
struct closure_frame_holder
{
typedef FrameT frame_t;
typedef frame_t *frame_ptr;
closure_frame_holder() : tsp_frame() {}
frame_ptr &get()
{
if (!tsp_frame.get())
tsp_frame.reset(new frame_ptr(0));
return *tsp_frame;
}
void set(frame_ptr f)
{
*tsp_frame = f;
}
private:
boost::thread_specific_ptr<frame_ptr> tsp_frame;
// no copies, no assignments
closure_frame_holder(closure_frame_holder const &);
closure_frame_holder &operator=(closure_frame_holder const &);
};
#endif
} // namespace phoenix::impl
///////////////////////////////////////////////////////////////////////////////
//
// closure_frame class
//
///////////////////////////////////////////////////////////////////////////////
template <typename ClosureT>
class closure_frame : public ClosureT::tuple_t {
public:
closure_frame(ClosureT const& clos)
: ClosureT::tuple_t(), save(clos.frame.get()), frame(clos.frame)
{ clos.frame.set(this); }
template <typename TupleT>
closure_frame(ClosureT const& clos, TupleT const& init)
: ClosureT::tuple_t(init), save(clos.frame.get()), frame(clos.frame)
{ clos.frame.set(this); }
~closure_frame()
{ frame.set(save); }
private:
closure_frame(closure_frame const&); // no copy
closure_frame& operator=(closure_frame const&); // no assign
closure_frame* save;
impl::closure_frame_holder<closure_frame>& frame;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure_member class
//
///////////////////////////////////////////////////////////////////////////////
template <int N, typename ClosureT>
class closure_member {
public:
typedef typename ClosureT::tuple_t tuple_t;
closure_member()
: frame(ClosureT::closure_frame_holder_ref()) {}
template <typename TupleT>
struct result {
typedef typename tuple_element<
N, typename ClosureT::tuple_t
>::rtype type;
};
template <typename TupleT>
typename tuple_element<N, typename ClosureT::tuple_t>::rtype
eval(TupleT const& /*args*/) const
{
using namespace std;
BOOST_ASSERT(frame.get() != 0);
return (*frame.get())[tuple_index<N>()];
}
private:
impl::closure_frame_holder<typename ClosureT::closure_frame_t> &frame;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure class
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T0 = nil_t
, typename T1 = nil_t
, typename T2 = nil_t
#if PHOENIX_LIMIT > 3
, typename T3 = nil_t
, typename T4 = nil_t
, typename T5 = nil_t
#if PHOENIX_LIMIT > 6
, typename T6 = nil_t
, typename T7 = nil_t
, typename T8 = nil_t
#if PHOENIX_LIMIT > 9
, typename T9 = nil_t
, typename T10 = nil_t
, typename T11 = nil_t
#if PHOENIX_LIMIT > 12
, typename T12 = nil_t
, typename T13 = nil_t
, typename T14 = nil_t
#endif
#endif
#endif
#endif
>
class closure {
public:
typedef tuple<
T0, T1, T2
#if PHOENIX_LIMIT > 3
, T3, T4, T5
#if PHOENIX_LIMIT > 6
, T6, T7, T8
#if PHOENIX_LIMIT > 9
, T9, T10, T11
#if PHOENIX_LIMIT > 12
, T12, T13, T14
#endif
#endif
#endif
#endif
> tuple_t;
typedef closure<
T0, T1, T2
#if PHOENIX_LIMIT > 3
, T3, T4, T5
#if PHOENIX_LIMIT > 6
, T6, T7, T8
#if PHOENIX_LIMIT > 9
, T9, T10, T11
#if PHOENIX_LIMIT > 12
, T12, T13, T14
#endif
#endif
#endif
#endif
> self_t;
typedef closure_frame<self_t> closure_frame_t;
closure()
: frame() { closure_frame_holder_ref(&frame); }
typedef actor<closure_member<0, self_t> > member1;
typedef actor<closure_member<1, self_t> > member2;
typedef actor<closure_member<2, self_t> > member3;
#if PHOENIX_LIMIT > 3
typedef actor<closure_member<3, self_t> > member4;
typedef actor<closure_member<4, self_t> > member5;
typedef actor<closure_member<5, self_t> > member6;
#if PHOENIX_LIMIT > 6
typedef actor<closure_member<6, self_t> > member7;
typedef actor<closure_member<7, self_t> > member8;
typedef actor<closure_member<8, self_t> > member9;
#if PHOENIX_LIMIT > 9
typedef actor<closure_member<9, self_t> > member10;
typedef actor<closure_member<10, self_t> > member11;
typedef actor<closure_member<11, self_t> > member12;
#if PHOENIX_LIMIT > 12
typedef actor<closure_member<12, self_t> > member13;
typedef actor<closure_member<13, self_t> > member14;
typedef actor<closure_member<14, self_t> > member15;
#endif
#endif
#endif
#endif
#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
private:
#endif
closure(closure const&); // no copy
closure& operator=(closure const&); // no assign
#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
template <int N, typename ClosureT>
friend class closure_member;
template <typename ClosureT>
friend class closure_frame;
#endif
typedef impl::closure_frame_holder<closure_frame_t> holder_t;
#ifdef PHOENIX_THREADSAFE
static boost::thread_specific_ptr<holder_t*> &
tsp_frame_instance()
{
static boost::thread_specific_ptr<holder_t*> the_instance;
return the_instance;
}
static void
tsp_frame_instance_init()
{
tsp_frame_instance();
}
#endif
static holder_t &
closure_frame_holder_ref(holder_t* holder_ = 0)
{
#ifdef PHOENIX_THREADSAFE
#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
static boost::once_flag been_here = BOOST_ONCE_INIT;
#else
static boost::once_flag been_here;
#endif
boost::call_once(been_here, tsp_frame_instance_init);
boost::thread_specific_ptr<holder_t*> &tsp_frame = tsp_frame_instance();
if (!tsp_frame.get())
tsp_frame.reset(new holder_t *(0));
holder_t *& holder = *tsp_frame;
#else
static holder_t* holder = 0;
#endif
if (holder_ != 0)
holder = holder_;
return *holder;
}
mutable holder_t frame;
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
}
// namespace phoenix
#endif
@@ -0,0 +1,760 @@
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
Distributed under 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_FUNCTIONS_HPP
#define PHOENIX_FUNCTIONS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/actor.hpp>
#include <boost/spirit/home/classic/phoenix/composite.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
///////////////////////////////////////////////////////////////////////////////
//
// function class
//
// Lazy functions
//
// This class provides a mechanism for lazily evaluating functions.
// Syntactically, a lazy function looks like an ordinary C/C++
// function. The function call looks the same. However, unlike
// ordinary functions, the actual function execution is deferred.
// (see actor.hpp, primitives.hpp and composite.hpp for an
// overview). For example here are sample factorial function calls:
//
// factorial(4)
// factorial(arg1)
// factorial(arg1 * 6)
//
// These functions are automatically lazily bound unlike ordinary
// function pointers or functor objects that need to be explicitly
// bound through the bind function (see binders.hpp).
//
// A lazy function works in conjunction with a user defined functor
// (as usual with a member operator()). Only special forms of
// functor objects are allowed. This is required to enable true
// polymorphism (STL style monomorphic functors and function
// pointers can still be used through the bind facility in
// binders.hpp).
//
// This special functor is expected to have a nested template class
// result<A...TN> (where N is the number of arguments of its
// member operator()). 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 A...TN, what
// will be the operator()'s return type?".
//
// There is a special case for functors that accept no arguments.
// Such nullary functors are only required to define a typedef
// result_type that reflects the return type of its operator().
//
// Here's an example of a simple functor that computes the
// factorial of a number:
//
// struct factorial_impl {
//
// template <typename Arg>
// struct result { typedef Arg type; };
//
// template <typename Arg>
// Arg operator()(Arg n) const
// { return (n <= 0) ? 1 : n * this->operator()(n-1); }
// };
//
// As can be seen, the functor can be polymorphic. Its arguments
// and return type are not fixed to a particular type. The example
// above for example, can handle any type as long as it can carry
// out the required operations (i.e. <=, * and -).
//
// We can now declare and instantiate a lazy 'factorial' function:
//
// function<factorial_impl> factorial;
//
// Invoking a lazy function 'factorial' does not immediately
// execute the functor factorial_impl. Instead, a composite (see
// composite.hpp) object is created and returned to the caller.
// Example:
//
// factorial(arg1)
//
// does nothing more than return a composite. A second function
// call will invoke the actual factorial function. Example:
//
// int i = 4;
// cout << factorial(arg1)(i);
//
// will print out "24".
//
// Take note that in certain cases (e.g. for functors with state),
// an instance may be passed on to the constructor. Example:
//
// function<factorial_impl> factorial(ftor);
//
// where ftor is an instance of factorial_impl (this is not
// necessary in this case since factorial is a simple stateless
// functor). Take care though when using functors with state
// because the functors are taken in by value. It is best to keep
// the data manipulated by a functor outside the functor itself and
// keep a reference to this data inside the functor. Also, it is
// best to keep functors as small as possible.
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT>
struct function {
function() : op() {}
function(OperationT const& op_) : op(op_) {}
actor<composite<OperationT> >
operator()() const;
template <typename A>
typename impl::make_composite<OperationT, A>::type
operator()(A const& a) const;
template <typename A, typename B>
typename impl::make_composite<OperationT, A, B>::type
operator()(A const& a, B const& b) const;
template <typename A, typename B, typename C>
typename impl::make_composite<OperationT, A, B, C>::type
operator()(A const& a, B const& b, C const& c) const;
#if PHOENIX_LIMIT > 3
template <typename A, typename B, typename C, typename D>
typename impl::make_composite<OperationT, A, B, C, D>::type
operator()(A const& a, B const& b, C const& c, D const& d) const;
template <typename A, typename B, typename C, typename D, typename E>
typename impl::make_composite<
OperationT, A, B, C, D, E
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f
) const;
#if PHOENIX_LIMIT > 6
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i
) const;
#if PHOENIX_LIMIT > 9
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l
) const;
#if PHOENIX_LIMIT > 12
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m, N const& n
) const;
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N, typename O
>
typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
>::type
operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m, N const& n, O const& o
) const;
#endif
#endif
#endif
#endif
OperationT op;
};
///////////////////////////////////////////////////////////////////////////////
//
// function class implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename OperationT>
inline actor<composite<OperationT> >
function<OperationT>::operator()() const
{
return actor<composite<OperationT> >(op);
}
//////////////////////////////////
template <typename OperationT>
template <typename A>
inline typename impl::make_composite<OperationT, A>::type
function<OperationT>::operator()(A const& a) const
{
typedef typename impl::make_composite<OperationT, A>::composite_type ret_t;
return ret_t
(
op,
as_actor<A>::convert(a)
);
}
//////////////////////////////////
template <typename OperationT>
template <typename A, typename B>
inline typename impl::make_composite<OperationT, A, B>::type
function<OperationT>::operator()(A const& a, B const& b) const
{
typedef
typename impl::make_composite<OperationT, A, B>::composite_type
ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b)
);
}
//////////////////////////////////
template <typename OperationT>
template <typename A, typename B, typename C>
inline typename impl::make_composite<OperationT, A, B, C>::type
function<OperationT>::operator()(A const& a, B const& b, C const& c) const
{
typedef
typename impl::make_composite<OperationT, A, B, C>::composite_type
ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c)
);
}
#if PHOENIX_LIMIT > 3
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D
>
inline typename impl::make_composite<
OperationT, A, B, C, D
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f)
);
}
#if PHOENIX_LIMIT > 6
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i)
);
}
#if PHOENIX_LIMIT > 9
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j),
as_actor<K>::convert(k)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j),
as_actor<K>::convert(k),
as_actor<L>::convert(l)
);
}
#if PHOENIX_LIMIT > 12
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j),
as_actor<K>::convert(k),
as_actor<L>::convert(l),
as_actor<M>::convert(m)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m, N const& n
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j),
as_actor<K>::convert(k),
as_actor<L>::convert(l),
as_actor<M>::convert(m),
as_actor<N>::convert(n)
);
}
//////////////////////////////////
template <typename OperationT>
template <
typename A, typename B, typename C, typename D, typename E,
typename F, typename G, typename H, typename I, typename J,
typename K, typename L, typename M, typename N, typename O
>
inline typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
>::type
function<OperationT>::operator()(
A const& a, B const& b, C const& c, D const& d, E const& e,
F const& f, G const& g, H const& h, I const& i, J const& j,
K const& k, L const& l, M const& m, N const& n, O const& o
) const
{
typedef typename impl::make_composite<
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
>::composite_type ret_t;
return ret_t(
op,
as_actor<A>::convert(a),
as_actor<B>::convert(b),
as_actor<C>::convert(c),
as_actor<D>::convert(d),
as_actor<E>::convert(e),
as_actor<F>::convert(f),
as_actor<G>::convert(g),
as_actor<H>::convert(h),
as_actor<I>::convert(i),
as_actor<J>::convert(j),
as_actor<K>::convert(k),
as_actor<L>::convert(l),
as_actor<M>::convert(m),
as_actor<N>::convert(n),
as_actor<O>::convert(o)
);
}
#endif
#endif
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
} // namespace phoenix
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,256 @@
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
Distributed under 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_PRIMITIVES_HPP
#define PHOENIX_PRIMITIVES_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/actor.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
///////////////////////////////////////////////////////////////////////////////
//
// argument class
//
// Lazy arguments
//
// An actor base class that extracts and returns the Nth argument
// from the argument list passed in the 'args' tuple in the eval
// member function (see actor.hpp). There are some predefined
// argument constants that can be used as actors (arg1..argN).
//
// The argument actor is a place-holder for the actual arguments
// passed by the client. For example, wherever arg1 is seen placed
// in a lazy function (see functions.hpp) or lazy operator (see
// operators.hpp), this will be replaced by the actual first
// argument in the actual function evaluation. Argument actors are
// essentially lazy arguments. A lazy argument is a full actor in
// its own right and can be evaluated through the actor's operator().
//
// Example:
//
// char c = 'A';
// int i = 123;
// const char* s = "Hello World";
//
// cout << arg1(c) << ' ';
// cout << arg1(i, s) << ' ';
// cout << arg2(i, s) << ' ';
//
// will print out "A 123 Hello World"
//
///////////////////////////////////////////////////////////////////////////////
template <int N>
struct argument {
template <typename TupleT>
struct result { typedef typename tuple_element<N, TupleT>::type type; };
template <typename TupleT>
typename tuple_element<N, TupleT>::type
eval(TupleT const& args) const
{
return args[tuple_index<N>()];
}
};
//////////////////////////////////
actor<argument<0> > const arg1 = argument<0>();
actor<argument<1> > const arg2 = argument<1>();
actor<argument<2> > const arg3 = argument<2>();
#if PHOENIX_LIMIT > 3
actor<argument<3> > const arg4 = argument<3>();
actor<argument<4> > const arg5 = argument<4>();
actor<argument<5> > const arg6 = argument<5>();
#if PHOENIX_LIMIT > 6
actor<argument<6> > const arg7 = argument<6>();
actor<argument<7> > const arg8 = argument<7>();
actor<argument<8> > const arg9 = argument<8>();
#if PHOENIX_LIMIT > 9
actor<argument<9> > const arg10 = argument<9>();
actor<argument<10> > const arg11 = argument<10>();
actor<argument<11> > const arg12 = argument<11>();
#if PHOENIX_LIMIT > 12
actor<argument<12> > const arg13 = argument<12>();
actor<argument<13> > const arg14 = argument<13>();
actor<argument<14> > const arg15 = argument<14>();
#endif
#endif
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
//
// value class
//
// Lazy values
//
// A bound actual parameter is kept in a value class for deferred
// access later when needed. A value object is immutable. Value
// objects are typically created through the val(x) free function
// which returns a value<T> with T deduced from the type of x. x is
// held in the value<T> object by value.
//
// Lazy values are actors. As such, lazy values can be evaluated
// through the actor's operator(). Such invocation gives the value's
// identity. Example:
//
// cout << val(3)() << val("Hello World")();
//
// prints out "3 Hello World"
//
///////////////////////////////////////////////////////////////////////////////
template <typename T>
struct value {
typedef typename boost::remove_reference<T>::type plain_t;
template <typename TupleT>
struct result { typedef plain_t const type; };
value(plain_t val_)
: val(val_) {}
template <typename TupleT>
plain_t const
eval(TupleT const& /*args*/) const
{
return val;
}
plain_t val;
};
//////////////////////////////////
template <typename T>
inline actor<value<T> > const
val(T v)
{
return value<T>(v);
}
//////////////////////////////////
template <typename BaseT>
void
val(actor<BaseT> const& v); // This is undefined and not allowed.
///////////////////////////////////////////////////////////////////////////
//
// Arbitrary types T are typically converted to a actor<value<T> >
// (see as_actor<T> in actor.hpp). A specialization is also provided
// for arrays. T[N] arrays are converted to actor<value<T const*> >.
//
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct as_actor {
typedef actor<value<T> > type;
static type convert(T const& x)
{ return value<T>(x); }
};
//////////////////////////////////
template <typename T, int N>
struct as_actor<T[N]> {
typedef actor<value<T const*> > type;
static type convert(T const x[N])
{ return value<T const*>(x); }
};
///////////////////////////////////////////////////////////////////////////////
//
// variable class
//
// Lazy variables
//
// A bound actual parameter may also be held by non-const reference
// in a variable class for deferred access later when needed. A
// variable object is mutable, i.e. its referenced variable can be
// modified. Variable objects are typically created through the
// var(x) free function which returns a variable<T> with T deduced
// from the type of x. x is held in the value<T> object by
// reference.
//
// Lazy variables are actors. As such, lazy variables can be
// evaluated through the actor's operator(). Such invocation gives
// the variables's identity. Example:
//
// int i = 3;
// char const* s = "Hello World";
// cout << var(i)() << var(s)();
//
// prints out "3 Hello World"
//
// Another free function const_(x) may also be used. const_(x) creates
// a variable<T const&> object using a constant reference.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
template <typename T>
struct variable {
template <typename TupleT>
struct result { typedef T& type; };
variable(T& var_)
: var(var_) {}
template <typename TupleT>
T&
eval(TupleT const& /*args*/) const
{
return var;
}
T& var;
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
//////////////////////////////////
template <typename T>
inline actor<variable<T> > const
var(T& v)
{
return variable<T>(v);
}
//////////////////////////////////
template <typename T>
inline actor<variable<T const> > const
const_(T const& v)
{
return variable<T const>(v);
}
//////////////////////////////////
template <typename BaseT>
void
var(actor<BaseT> const& v); // This is undefined and not allowed.
//////////////////////////////////
template <typename BaseT>
void
const_(actor<BaseT> const& v); // This is undefined and not allowed.
///////////////////////////////////////////////////////////////////////////////
} // namespace phoenix
#endif
@@ -0,0 +1,285 @@
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
Distributed under 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_SPECIAL_OPS_HPP
#define PHOENIX_SPECIAL_OPS_HPP
#include <boost/config.hpp>
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define PHOENIX_SSTREAM strstream
#else
#include <sstream>
#define PHOENIX_SSTREAM stringstream
#endif
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/operators.hpp>
#include <iosfwd>
///////////////////////////////////////////////////////////////////////////////
#if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE)
#define PHOENIX_STD _STLP_STD
#define PHOENIX_NO_STD_NAMESPACE
#else
#define PHOENIX_STD std
#endif
///////////////////////////////////////////////////////////////////////////////
//#if !defined(PHOENIX_NO_STD_NAMESPACE)
namespace PHOENIX_STD
{
//#endif
template<typename T> class complex;
//#if !defined(PHOENIX_NO_STD_NAMESPACE)
}
//#endif
///////////////////////////////////////////////////////////////////////////////
namespace phoenix
{
///////////////////////////////////////////////////////////////////////////////
//
// The following specializations take into account the C++ standard
// library components. There are a couple of issues that have to be
// dealt with to enable lazy operator overloads for the standard
// library classes.
//
// *iostream (e.g. cout, cin, strstream/ stringstream) uses non-
// canonical shift operator overloads where the lhs is taken in
// by reference.
//
// *I/O manipulators overloads for the RHS of the << and >>
// operators.
//
// *STL iterators can be objects that conform to pointer semantics.
// Some operators need to be specialized for these.
//
// *std::complex is given a rank (see rank class in operators.hpp)
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// specialization for rank<std::complex>
//
///////////////////////////////////////////////////////////////////////////////
template <typename T> struct rank<PHOENIX_STD::complex<T> >
{ static int const value = 170 + rank<T>::value; };
///////////////////////////////////////////////////////////////////////////////
//
// specializations for std::istream
//
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////
template <typename T1>
struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
{
typedef PHOENIX_STD::istream& result_type;
static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
{ return out >> rhs; }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary3
<shift_r_op, variable<PHOENIX_STD::istream>, BaseT>::type
operator>>(PHOENIX_STD::istream& _0, actor<BaseT> const& _1)
{
return impl::make_binary3
<shift_r_op, variable<PHOENIX_STD::istream>, BaseT>
::construct(var(_0), _1);
}
///////////////////////////////////////////////////////////////////////////////
//
// specializations for std::ostream
//
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////
template <typename T1>
struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
{
typedef PHOENIX_STD::ostream& result_type;
static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
{ return out << rhs; }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary3
<shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>::type
operator<<(PHOENIX_STD::ostream& _0, actor<BaseT> const& _1)
{
return impl::make_binary3
<shift_l_op, variable<PHOENIX_STD::ostream>, BaseT>
::construct(var(_0), _1);
}
///////////////////////////////////////////////////////////////////////////////
//
// specializations for std::strstream / stringstream
//
///////////////////////////////////////////////////////////////////////////////
template <typename T1>
struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
{
typedef PHOENIX_STD::istream& result_type;
static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
{ return out >> rhs; }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary3
<shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
{
return impl::make_binary3
<shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
::construct(var(_0), _1);
}
//////////////////////////////////
template <typename T1>
struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
{
typedef PHOENIX_STD::ostream& result_type;
static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
{ return out << rhs; }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary3
<shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
{
return impl::make_binary3
<shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
::construct(var(_0), _1);
}
///////////////////////////////////////////////////////////////////////////////
//
// I/O manipulator specializations
//
///////////////////////////////////////////////////////////////////////////////
typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&);
typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&);
typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&);
#if defined(__BORLANDC__)
///////////////////////////////////////////////////////////////////////////////
//
// Borland does not like i/o manipulators functions such as endl to
// be the rhs of a lazy << operator (Borland incorrectly reports
// ambiguity). To get around the problem, we provide function
// pointer versions of the same name with a single trailing
// underscore.
//
// You can use the same trick for other i/o manipulators.
// Alternatively, you can prefix the manipulator with a '&'
// operator. Example:
//
// cout << arg1 << &endl
//
///////////////////////////////////////////////////////////////////////////////
imanip_t ws_ = &PHOENIX_STD::ws;
iomanip_t dec_ = &PHOENIX_STD::dec;
iomanip_t hex_ = &PHOENIX_STD::hex;
iomanip_t oct_ = &PHOENIX_STD::oct;
omanip_t endl_ = &PHOENIX_STD::endl;
omanip_t ends_ = &PHOENIX_STD::ends;
omanip_t flush_ = &PHOENIX_STD::flush;
#else // __BORLANDC__
///////////////////////////////////////////////////////////////////////////////
//
// The following are overloads for I/O manipulators.
//
///////////////////////////////////////////////////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
operator>>(actor<BaseT> const& _0, imanip_t _1)
{
return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
}
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
operator>>(actor<BaseT> const& _0, iomanip_t _1)
{
return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
}
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
operator<<(actor<BaseT> const& _0, omanip_t _1)
{
return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
}
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
operator<<(actor<BaseT> const& _0, iomanip_t _1)
{
return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
}
#endif // __BORLANDC__
///////////////////////////////////////////////////////////////////////////////
//
// specializations for stl iterators and containers
//
///////////////////////////////////////////////////////////////////////////////
template <typename T>
struct unary_operator<dereference_op, T>
{
typedef typename T::reference result_type;
static result_type eval(T const& iter)
{ return *iter; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<index_op, T0, T1>
{
typedef typename T0::reference result_type;
static result_type eval(T0& container, T1 const& index)
{ return container[index]; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<index_op, T0 const, T1>
{
typedef typename T0::const_reference result_type;
static result_type eval(T0 const& container, T1 const& index)
{ return container[index]; }
};
///////////////////////////////////////////////////////////////////////////////
} // namespace phoenix
#undef PHOENIX_SSTREAM
#undef PHOENIX_STD
#endif
@@ -0,0 +1,443 @@
/*=============================================================================
Phoenix V1.2.1
Copyright (c) 2001-2002 Joel de Guzman
Distributed under 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_STATEMENTS_HPP
#define PHOENIX_STATEMENTS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/composite.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace phoenix {
///////////////////////////////////////////////////////////////////////////////
//
// sequential_composite
//
// Two or more actors separated by the comma generates a
// sequential_composite which is a composite actor. Example:
//
// actor,
// actor,
// actor
//
// The actors are evaluated sequentially. The result type of this
// is void. Note that the last actor should not have a trailing
// comma.
//
///////////////////////////////////////////////////////////////////////////////
template <typename A0, typename A1>
struct sequential_composite {
typedef sequential_composite<A0, A1> self_t;
template <typename TupleT>
struct result { typedef void type; };
sequential_composite(A0 const& _0, A1 const& _1)
: a0(_0), a1(_1) {}
template <typename TupleT>
void
eval(TupleT const& args) const
{
a0.eval(args);
a1.eval(args);
}
A0 a0; A1 a1; // actors
};
//////////////////////////////////
template <typename BaseT0, typename BaseT1>
inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
{
return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
}
///////////////////////////////////////////////////////////////////////////////
//
// if_then_else_composite
//
// This composite has two (2) forms:
//
// if_(condition)
// [
// statement
// ]
//
// and
//
// if_(condition)
// [
// true_statement
// ]
// .else_
// [
// false_statement
// ]
//
// where condition is an actor that evaluates to bool. If condition
// is true, the true_statement (again an actor) is executed
// otherwise, the false_statement (another actor) is executed. The
// result type of this is void. Note the trailing underscore after
// if_ and the leading dot and the trailing underscore before
// and after .else_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename CondT, typename ThenT, typename ElseT>
struct if_then_else_composite {
typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
template <typename TupleT>
struct result {
typedef void type;
};
if_then_else_composite(
CondT const& cond_,
ThenT const& then_,
ElseT const& else__)
: cond(cond_), then(then_), else_(else__) {}
template <typename TupleT>
void eval(TupleT const& args) const
{
if (cond.eval(args))
then.eval(args);
else
else_.eval(args);
}
CondT cond; ThenT then; ElseT else_; // actors
};
//////////////////////////////////
template <typename CondT, typename ThenT>
struct else_gen {
else_gen(CondT const& cond_, ThenT const& then_)
: cond(cond_), then(then_) {}
template <typename ElseT>
actor<if_then_else_composite<CondT, ThenT,
typename as_actor<ElseT>::type> >
operator[](ElseT const& else_)
{
typedef if_then_else_composite<CondT, ThenT,
typename as_actor<ElseT>::type>
result;
return result(cond, then, as_actor<ElseT>::convert(else_));
}
CondT cond; ThenT then;
};
//////////////////////////////////
template <typename CondT, typename ThenT>
struct if_then_composite {
typedef if_then_composite<CondT, ThenT> self_t;
template <typename TupleT>
struct result { typedef void type; };
if_then_composite(CondT const& cond_, ThenT const& then_)
: cond(cond_), then(then_), else_(cond, then) {}
template <typename TupleT>
void eval(TupleT const& args) const
{
if (cond.eval(args))
then.eval(args);
}
CondT cond; ThenT then; // actors
else_gen<CondT, ThenT> else_;
};
//////////////////////////////////
template <typename CondT>
struct if_gen {
if_gen(CondT const& cond_)
: cond(cond_) {}
template <typename ThenT>
actor<if_then_composite<
typename as_actor<CondT>::type,
typename as_actor<ThenT>::type> >
operator[](ThenT const& then) const
{
typedef if_then_composite<
typename as_actor<CondT>::type,
typename as_actor<ThenT>::type>
result;
return result(
as_actor<CondT>::convert(cond),
as_actor<ThenT>::convert(then));
}
CondT cond;
};
//////////////////////////////////
template <typename CondT>
inline if_gen<CondT>
if_(CondT const& cond)
{
return if_gen<CondT>(cond);
}
///////////////////////////////////////////////////////////////////////////////
//
// while_composite
//
// This composite has the form:
//
// while_(condition)
// [
// statement
// ]
//
// While the condition (an actor) evaluates to true, statement
// (another actor) is executed. The result type of this is void.
// Note the trailing underscore after while_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename CondT, typename DoT>
struct while_composite {
typedef while_composite<CondT, DoT> self_t;
template <typename TupleT>
struct result { typedef void type; };
while_composite(CondT const& cond_, DoT const& do__)
: cond(cond_), do_(do__) {}
template <typename TupleT>
void eval(TupleT const& args) const
{
while (cond.eval(args))
do_.eval(args);
}
CondT cond;
DoT do_;
};
//////////////////////////////////
template <typename CondT>
struct while_gen {
while_gen(CondT const& cond_)
: cond(cond_) {}
template <typename DoT>
actor<while_composite<
typename as_actor<CondT>::type,
typename as_actor<DoT>::type> >
operator[](DoT const& do_) const
{
typedef while_composite<
typename as_actor<CondT>::type,
typename as_actor<DoT>::type>
result;
return result(
as_actor<CondT>::convert(cond),
as_actor<DoT>::convert(do_));
}
CondT cond;
};
//////////////////////////////////
template <typename CondT>
inline while_gen<CondT>
while_(CondT const& cond)
{
return while_gen<CondT>(cond);
}
///////////////////////////////////////////////////////////////////////////////
//
// do_composite
//
// This composite has the form:
//
// do_
// [
// statement
// ]
// .while_(condition)
//
// While the condition (an actor) evaluates to true, statement
// (another actor) is executed. The statement is executed at least
// once. The result type of this is void. Note the trailing
// underscore after do_ and the leading dot and the trailing
// underscore before and after .while_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename DoT, typename CondT>
struct do_composite {
typedef do_composite<DoT, CondT> self_t;
template <typename TupleT>
struct result { typedef void type; };
do_composite(DoT const& do__, CondT const& cond_)
: do_(do__), cond(cond_) {}
template <typename TupleT>
void eval(TupleT const& args) const
{
do
do_.eval(args);
while (cond.eval(args));
}
DoT do_;
CondT cond;
};
////////////////////////////////////
template <typename DoT>
struct do_gen2 {
do_gen2(DoT const& do__)
: do_(do__) {}
template <typename CondT>
actor<do_composite<
typename as_actor<DoT>::type,
typename as_actor<CondT>::type> >
while_(CondT const& cond) const
{
typedef do_composite<
typename as_actor<DoT>::type,
typename as_actor<CondT>::type>
result;
return result(
as_actor<DoT>::convert(do_),
as_actor<CondT>::convert(cond));
}
DoT do_;
};
////////////////////////////////////
struct do_gen {
template <typename DoT>
do_gen2<DoT>
operator[](DoT const& do_) const
{
return do_gen2<DoT>(do_);
}
};
do_gen const do_ = do_gen();
///////////////////////////////////////////////////////////////////////////////
//
// for_composite
//
// This statement has the form:
//
// for_(init, condition, step)
// [
// statement
// ]
//
// Where init, condition, step and statement are all actors. init
// is executed once before entering the for-loop. The for-loop
// exits once condition evaluates to false. At each loop iteration,
// step and statement is called. The result of this statement is
// void. Note the trailing underscore after for_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename InitT, typename CondT, typename StepT, typename DoT>
struct for_composite {
typedef composite<InitT, CondT, StepT, DoT> self_t;
template <typename TupleT>
struct result { typedef void type; };
for_composite(
InitT const& init_,
CondT const& cond_,
StepT const& step_,
DoT const& do__)
: init(init_), cond(cond_), step(step_), do_(do__) {}
template <typename TupleT>
void
eval(TupleT const& args) const
{
for (init.eval(args); cond.eval(args); step.eval(args))
do_.eval(args);
}
InitT init; CondT cond; StepT step; DoT do_; // actors
};
//////////////////////////////////
template <typename InitT, typename CondT, typename StepT>
struct for_gen {
for_gen(
InitT const& init_,
CondT const& cond_,
StepT const& step_)
: init(init_), cond(cond_), step(step_) {}
template <typename DoT>
actor<for_composite<
typename as_actor<InitT>::type,
typename as_actor<CondT>::type,
typename as_actor<StepT>::type,
typename as_actor<DoT>::type> >
operator[](DoT const& do_) const
{
typedef for_composite<
typename as_actor<InitT>::type,
typename as_actor<CondT>::type,
typename as_actor<StepT>::type,
typename as_actor<DoT>::type>
result;
return result(
as_actor<InitT>::convert(init),
as_actor<CondT>::convert(cond),
as_actor<StepT>::convert(step),
as_actor<DoT>::convert(do_));
}
InitT init; CondT cond; StepT step;
};
//////////////////////////////////
template <typename InitT, typename CondT, typename StepT>
inline for_gen<InitT, CondT, StepT>
for_(InitT const& init, CondT const& cond, StepT const& step)
{
return for_gen<InitT, CondT, StepT>(init, cond, step);
}
} // namespace phoenix
#endif
File diff suppressed because it is too large Load Diff