You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
256 lines
7.4 KiB
256 lines
7.4 KiB
/*============================================================================= |
|
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
|
|
|