| /*============================================================================= |
| 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 |