|
|
|||
File indexing completed on 2025-12-16 10:09:07
0001 /*============================================================================= 0002 Phoenix V1.2.1 0003 Copyright (c) 2001-2002 Joel de Guzman 0004 0005 Distributed under the Boost Software License, Version 1.0. (See accompanying 0006 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0007 ==============================================================================*/ 0008 #ifndef BOOST_SPIRIT_CLASSIC_PHOENIX_PRIMITIVES_HPP 0009 #define BOOST_SPIRIT_CLASSIC_PHOENIX_PRIMITIVES_HPP 0010 0011 /////////////////////////////////////////////////////////////////////////////// 0012 #include <boost/spirit/home/classic/phoenix/actor.hpp> 0013 0014 /////////////////////////////////////////////////////////////////////////////// 0015 namespace phoenix { 0016 0017 /////////////////////////////////////////////////////////////////////////////// 0018 // 0019 // argument class 0020 // 0021 // Lazy arguments 0022 // 0023 // An actor base class that extracts and returns the Nth argument 0024 // from the argument list passed in the 'args' tuple in the eval 0025 // member function (see actor.hpp). There are some predefined 0026 // argument constants that can be used as actors (arg1..argN). 0027 // 0028 // The argument actor is a place-holder for the actual arguments 0029 // passed by the client. For example, wherever arg1 is seen placed 0030 // in a lazy function (see functions.hpp) or lazy operator (see 0031 // operators.hpp), this will be replaced by the actual first 0032 // argument in the actual function evaluation. Argument actors are 0033 // essentially lazy arguments. A lazy argument is a full actor in 0034 // its own right and can be evaluated through the actor's operator(). 0035 // 0036 // Example: 0037 // 0038 // char c = 'A'; 0039 // int i = 123; 0040 // const char* s = "Hello World"; 0041 // 0042 // cout << arg1(c) << ' '; 0043 // cout << arg1(i, s) << ' '; 0044 // cout << arg2(i, s) << ' '; 0045 // 0046 // will print out "A 123 Hello World" 0047 // 0048 /////////////////////////////////////////////////////////////////////////////// 0049 template <int N> 0050 struct argument { 0051 0052 template <typename TupleT> 0053 struct result { typedef typename tuple_element<N, TupleT>::type type; }; 0054 0055 template <typename TupleT> 0056 typename tuple_element<N, TupleT>::type 0057 eval(TupleT const& args) const 0058 { 0059 tuple_index<N> const idx; 0060 return args[idx]; 0061 } 0062 }; 0063 0064 ////////////////////////////////// 0065 actor<argument<0> > const arg1 = argument<0>(); 0066 actor<argument<1> > const arg2 = argument<1>(); 0067 actor<argument<2> > const arg3 = argument<2>(); 0068 0069 #if PHOENIX_LIMIT > 3 0070 actor<argument<3> > const arg4 = argument<3>(); 0071 actor<argument<4> > const arg5 = argument<4>(); 0072 actor<argument<5> > const arg6 = argument<5>(); 0073 0074 #if PHOENIX_LIMIT > 6 0075 actor<argument<6> > const arg7 = argument<6>(); 0076 actor<argument<7> > const arg8 = argument<7>(); 0077 actor<argument<8> > const arg9 = argument<8>(); 0078 0079 #if PHOENIX_LIMIT > 9 0080 actor<argument<9> > const arg10 = argument<9>(); 0081 actor<argument<10> > const arg11 = argument<10>(); 0082 actor<argument<11> > const arg12 = argument<11>(); 0083 0084 #if PHOENIX_LIMIT > 12 0085 actor<argument<12> > const arg13 = argument<12>(); 0086 actor<argument<13> > const arg14 = argument<13>(); 0087 actor<argument<14> > const arg15 = argument<14>(); 0088 0089 #endif 0090 #endif 0091 #endif 0092 #endif 0093 /////////////////////////////////////////////////////////////////////////////// 0094 // 0095 // value class 0096 // 0097 // Lazy values 0098 // 0099 // A bound actual parameter is kept in a value class for deferred 0100 // access later when needed. A value object is immutable. Value 0101 // objects are typically created through the val(x) free function 0102 // which returns a value<T> with T deduced from the type of x. x is 0103 // held in the value<T> object by value. 0104 // 0105 // Lazy values are actors. As such, lazy values can be evaluated 0106 // through the actor's operator(). Such invocation gives the value's 0107 // identity. Example: 0108 // 0109 // cout << val(3)() << val("Hello World")(); 0110 // 0111 // prints out "3 Hello World" 0112 // 0113 /////////////////////////////////////////////////////////////////////////////// 0114 template <typename T> 0115 struct value { 0116 0117 typedef typename boost::remove_reference<T>::type plain_t; 0118 0119 template <typename TupleT> 0120 struct result { typedef plain_t const type; }; 0121 0122 value(plain_t val_) 0123 : val(val_) {} 0124 0125 template <typename TupleT> 0126 plain_t const 0127 eval(TupleT const& /*args*/) const 0128 { 0129 return val; 0130 } 0131 0132 plain_t val; 0133 }; 0134 0135 ////////////////////////////////// 0136 template <typename T> 0137 inline actor<value<T> > const 0138 val(T v) 0139 { 0140 return value<T>(v); 0141 } 0142 0143 ////////////////////////////////// 0144 template <typename BaseT> 0145 void 0146 val(actor<BaseT> const& v); // This is undefined and not allowed. 0147 0148 /////////////////////////////////////////////////////////////////////////// 0149 // 0150 // Arbitrary types T are typically converted to a actor<value<T> > 0151 // (see as_actor<T> in actor.hpp). A specialization is also provided 0152 // for arrays. T[N] arrays are converted to actor<value<T const*> >. 0153 // 0154 /////////////////////////////////////////////////////////////////////////// 0155 template <typename T> 0156 struct as_actor { 0157 0158 typedef actor<value<T> > type; 0159 static type convert(T const& x) 0160 { return value<T>(x); } 0161 }; 0162 0163 ////////////////////////////////// 0164 template <typename T, int N> 0165 struct as_actor<T[N]> { 0166 0167 typedef actor<value<T const*> > type; 0168 static type convert(T const x[N]) 0169 { return value<T const*>(x); } 0170 }; 0171 0172 /////////////////////////////////////////////////////////////////////////////// 0173 // 0174 // variable class 0175 // 0176 // Lazy variables 0177 // 0178 // A bound actual parameter may also be held by non-const reference 0179 // in a variable class for deferred access later when needed. A 0180 // variable object is mutable, i.e. its referenced variable can be 0181 // modified. Variable objects are typically created through the 0182 // var(x) free function which returns a variable<T> with T deduced 0183 // from the type of x. x is held in the value<T> object by 0184 // reference. 0185 // 0186 // Lazy variables are actors. As such, lazy variables can be 0187 // evaluated through the actor's operator(). Such invocation gives 0188 // the variables's identity. Example: 0189 // 0190 // int i = 3; 0191 // char const* s = "Hello World"; 0192 // cout << var(i)() << var(s)(); 0193 // 0194 // prints out "3 Hello World" 0195 // 0196 // Another free function const_(x) may also be used. const_(x) creates 0197 // a variable<T const&> object using a constant reference. 0198 // 0199 /////////////////////////////////////////////////////////////////////////////// 0200 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 0201 #pragma warning(push) 0202 #pragma warning(disable:4512) //assignment operator could not be generated 0203 #endif 0204 0205 template <typename T> 0206 struct variable { 0207 0208 template <typename TupleT> 0209 struct result { typedef T& type; }; 0210 0211 variable(T& var_) 0212 : var(var_) {} 0213 0214 template <typename TupleT> 0215 T& 0216 eval(TupleT const& /*args*/) const 0217 { 0218 return var; 0219 } 0220 0221 T& var; 0222 }; 0223 0224 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 0225 #pragma warning(pop) 0226 #endif 0227 0228 ////////////////////////////////// 0229 template <typename T> 0230 inline actor<variable<T> > const 0231 var(T& v) 0232 { 0233 return variable<T>(v); 0234 } 0235 0236 ////////////////////////////////// 0237 template <typename T> 0238 inline actor<variable<T const> > const 0239 const_(T const& v) 0240 { 0241 return variable<T const>(v); 0242 } 0243 0244 ////////////////////////////////// 0245 template <typename BaseT> 0246 void 0247 var(actor<BaseT> const& v); // This is undefined and not allowed. 0248 0249 ////////////////////////////////// 0250 template <typename BaseT> 0251 void 0252 const_(actor<BaseT> const& v); // This is undefined and not allowed. 0253 0254 /////////////////////////////////////////////////////////////////////////////// 0255 } // namespace phoenix 0256 0257 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|