primitives.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*=============================================================================
  2. Phoenix V1.2.1
  3. Copyright (c) 2001-2002 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef PHOENIX_PRIMITIVES_HPP
  8. #define PHOENIX_PRIMITIVES_HPP
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <boost/spirit/home/classic/phoenix/actor.hpp>
  11. ///////////////////////////////////////////////////////////////////////////////
  12. namespace phoenix {
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //
  15. // argument class
  16. //
  17. // Lazy arguments
  18. //
  19. // An actor base class that extracts and returns the Nth argument
  20. // from the argument list passed in the 'args' tuple in the eval
  21. // member function (see actor.hpp). There are some predefined
  22. // argument constants that can be used as actors (arg1..argN).
  23. //
  24. // The argument actor is a place-holder for the actual arguments
  25. // passed by the client. For example, wherever arg1 is seen placed
  26. // in a lazy function (see functions.hpp) or lazy operator (see
  27. // operators.hpp), this will be replaced by the actual first
  28. // argument in the actual function evaluation. Argument actors are
  29. // essentially lazy arguments. A lazy argument is a full actor in
  30. // its own right and can be evaluated through the actor's operator().
  31. //
  32. // Example:
  33. //
  34. // char c = 'A';
  35. // int i = 123;
  36. // const char* s = "Hello World";
  37. //
  38. // cout << arg1(c) << ' ';
  39. // cout << arg1(i, s) << ' ';
  40. // cout << arg2(i, s) << ' ';
  41. //
  42. // will print out "A 123 Hello World"
  43. //
  44. ///////////////////////////////////////////////////////////////////////////////
  45. template <int N>
  46. struct argument {
  47. template <typename TupleT>
  48. struct result { typedef typename tuple_element<N, TupleT>::type type; };
  49. template <typename TupleT>
  50. typename tuple_element<N, TupleT>::type
  51. eval(TupleT const& args) const
  52. {
  53. return args[tuple_index<N>()];
  54. }
  55. };
  56. //////////////////////////////////
  57. actor<argument<0> > const arg1 = argument<0>();
  58. actor<argument<1> > const arg2 = argument<1>();
  59. actor<argument<2> > const arg3 = argument<2>();
  60. #if PHOENIX_LIMIT > 3
  61. actor<argument<3> > const arg4 = argument<3>();
  62. actor<argument<4> > const arg5 = argument<4>();
  63. actor<argument<5> > const arg6 = argument<5>();
  64. #if PHOENIX_LIMIT > 6
  65. actor<argument<6> > const arg7 = argument<6>();
  66. actor<argument<7> > const arg8 = argument<7>();
  67. actor<argument<8> > const arg9 = argument<8>();
  68. #if PHOENIX_LIMIT > 9
  69. actor<argument<9> > const arg10 = argument<9>();
  70. actor<argument<10> > const arg11 = argument<10>();
  71. actor<argument<11> > const arg12 = argument<11>();
  72. #if PHOENIX_LIMIT > 12
  73. actor<argument<12> > const arg13 = argument<12>();
  74. actor<argument<13> > const arg14 = argument<13>();
  75. actor<argument<14> > const arg15 = argument<14>();
  76. #endif
  77. #endif
  78. #endif
  79. #endif
  80. ///////////////////////////////////////////////////////////////////////////////
  81. //
  82. // value class
  83. //
  84. // Lazy values
  85. //
  86. // A bound actual parameter is kept in a value class for deferred
  87. // access later when needed. A value object is immutable. Value
  88. // objects are typically created through the val(x) free function
  89. // which returns a value<T> with T deduced from the type of x. x is
  90. // held in the value<T> object by value.
  91. //
  92. // Lazy values are actors. As such, lazy values can be evaluated
  93. // through the actor's operator(). Such invocation gives the value's
  94. // identity. Example:
  95. //
  96. // cout << val(3)() << val("Hello World")();
  97. //
  98. // prints out "3 Hello World"
  99. //
  100. ///////////////////////////////////////////////////////////////////////////////
  101. template <typename T>
  102. struct value {
  103. typedef typename boost::remove_reference<T>::type plain_t;
  104. template <typename TupleT>
  105. struct result { typedef plain_t const type; };
  106. value(plain_t val_)
  107. : val(val_) {}
  108. template <typename TupleT>
  109. plain_t const
  110. eval(TupleT const& /*args*/) const
  111. {
  112. return val;
  113. }
  114. plain_t val;
  115. };
  116. //////////////////////////////////
  117. template <typename T>
  118. inline actor<value<T> > const
  119. val(T v)
  120. {
  121. return value<T>(v);
  122. }
  123. //////////////////////////////////
  124. template <typename BaseT>
  125. void
  126. val(actor<BaseT> const& v); // This is undefined and not allowed.
  127. ///////////////////////////////////////////////////////////////////////////
  128. //
  129. // Arbitrary types T are typically converted to a actor<value<T> >
  130. // (see as_actor<T> in actor.hpp). A specialization is also provided
  131. // for arrays. T[N] arrays are converted to actor<value<T const*> >.
  132. //
  133. ///////////////////////////////////////////////////////////////////////////
  134. template <typename T>
  135. struct as_actor {
  136. typedef actor<value<T> > type;
  137. static type convert(T const& x)
  138. { return value<T>(x); }
  139. };
  140. //////////////////////////////////
  141. template <typename T, int N>
  142. struct as_actor<T[N]> {
  143. typedef actor<value<T const*> > type;
  144. static type convert(T const x[N])
  145. { return value<T const*>(x); }
  146. };
  147. ///////////////////////////////////////////////////////////////////////////////
  148. //
  149. // variable class
  150. //
  151. // Lazy variables
  152. //
  153. // A bound actual parameter may also be held by non-const reference
  154. // in a variable class for deferred access later when needed. A
  155. // variable object is mutable, i.e. its referenced variable can be
  156. // modified. Variable objects are typically created through the
  157. // var(x) free function which returns a variable<T> with T deduced
  158. // from the type of x. x is held in the value<T> object by
  159. // reference.
  160. //
  161. // Lazy variables are actors. As such, lazy variables can be
  162. // evaluated through the actor's operator(). Such invocation gives
  163. // the variables's identity. Example:
  164. //
  165. // int i = 3;
  166. // char const* s = "Hello World";
  167. // cout << var(i)() << var(s)();
  168. //
  169. // prints out "3 Hello World"
  170. //
  171. // Another free function const_(x) may also be used. const_(x) creates
  172. // a variable<T const&> object using a constant reference.
  173. //
  174. ///////////////////////////////////////////////////////////////////////////////
  175. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  176. #pragma warning(push)
  177. #pragma warning(disable:4512) //assignment operator could not be generated
  178. #endif
  179. template <typename T>
  180. struct variable {
  181. template <typename TupleT>
  182. struct result { typedef T& type; };
  183. variable(T& var_)
  184. : var(var_) {}
  185. template <typename TupleT>
  186. T&
  187. eval(TupleT const& /*args*/) const
  188. {
  189. return var;
  190. }
  191. T& var;
  192. };
  193. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  194. #pragma warning(pop)
  195. #endif
  196. //////////////////////////////////
  197. template <typename T>
  198. inline actor<variable<T> > const
  199. var(T& v)
  200. {
  201. return variable<T>(v);
  202. }
  203. //////////////////////////////////
  204. template <typename T>
  205. inline actor<variable<T const> > const
  206. const_(T const& v)
  207. {
  208. return variable<T const>(v);
  209. }
  210. //////////////////////////////////
  211. template <typename BaseT>
  212. void
  213. var(actor<BaseT> const& v); // This is undefined and not allowed.
  214. //////////////////////////////////
  215. template <typename BaseT>
  216. void
  217. const_(actor<BaseT> const& v); // This is undefined and not allowed.
  218. ///////////////////////////////////////////////////////////////////////////////
  219. } // namespace phoenix
  220. #endif