primitives.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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 BOOST_SPIRIT_CLASSIC_PHOENIX_PRIMITIVES_HPP
  8. #define BOOST_SPIRIT_CLASSIC_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. tuple_index<N> const idx;
  54. return args[idx];
  55. }
  56. };
  57. //////////////////////////////////
  58. actor<argument<0> > const arg1 = argument<0>();
  59. actor<argument<1> > const arg2 = argument<1>();
  60. actor<argument<2> > const arg3 = argument<2>();
  61. #if PHOENIX_LIMIT > 3
  62. actor<argument<3> > const arg4 = argument<3>();
  63. actor<argument<4> > const arg5 = argument<4>();
  64. actor<argument<5> > const arg6 = argument<5>();
  65. #if PHOENIX_LIMIT > 6
  66. actor<argument<6> > const arg7 = argument<6>();
  67. actor<argument<7> > const arg8 = argument<7>();
  68. actor<argument<8> > const arg9 = argument<8>();
  69. #if PHOENIX_LIMIT > 9
  70. actor<argument<9> > const arg10 = argument<9>();
  71. actor<argument<10> > const arg11 = argument<10>();
  72. actor<argument<11> > const arg12 = argument<11>();
  73. #if PHOENIX_LIMIT > 12
  74. actor<argument<12> > const arg13 = argument<12>();
  75. actor<argument<13> > const arg14 = argument<13>();
  76. actor<argument<14> > const arg15 = argument<14>();
  77. #endif
  78. #endif
  79. #endif
  80. #endif
  81. ///////////////////////////////////////////////////////////////////////////////
  82. //
  83. // value class
  84. //
  85. // Lazy values
  86. //
  87. // A bound actual parameter is kept in a value class for deferred
  88. // access later when needed. A value object is immutable. Value
  89. // objects are typically created through the val(x) free function
  90. // which returns a value<T> with T deduced from the type of x. x is
  91. // held in the value<T> object by value.
  92. //
  93. // Lazy values are actors. As such, lazy values can be evaluated
  94. // through the actor's operator(). Such invocation gives the value's
  95. // identity. Example:
  96. //
  97. // cout << val(3)() << val("Hello World")();
  98. //
  99. // prints out "3 Hello World"
  100. //
  101. ///////////////////////////////////////////////////////////////////////////////
  102. template <typename T>
  103. struct value {
  104. typedef typename boost::remove_reference<T>::type plain_t;
  105. template <typename TupleT>
  106. struct result { typedef plain_t const type; };
  107. value(plain_t val_)
  108. : val(val_) {}
  109. template <typename TupleT>
  110. plain_t const
  111. eval(TupleT const& /*args*/) const
  112. {
  113. return val;
  114. }
  115. plain_t val;
  116. };
  117. //////////////////////////////////
  118. template <typename T>
  119. inline actor<value<T> > const
  120. val(T v)
  121. {
  122. return value<T>(v);
  123. }
  124. //////////////////////////////////
  125. template <typename BaseT>
  126. void
  127. val(actor<BaseT> const& v); // This is undefined and not allowed.
  128. ///////////////////////////////////////////////////////////////////////////
  129. //
  130. // Arbitrary types T are typically converted to a actor<value<T> >
  131. // (see as_actor<T> in actor.hpp). A specialization is also provided
  132. // for arrays. T[N] arrays are converted to actor<value<T const*> >.
  133. //
  134. ///////////////////////////////////////////////////////////////////////////
  135. template <typename T>
  136. struct as_actor {
  137. typedef actor<value<T> > type;
  138. static type convert(T const& x)
  139. { return value<T>(x); }
  140. };
  141. //////////////////////////////////
  142. template <typename T, int N>
  143. struct as_actor<T[N]> {
  144. typedef actor<value<T const*> > type;
  145. static type convert(T const x[N])
  146. { return value<T const*>(x); }
  147. };
  148. ///////////////////////////////////////////////////////////////////////////////
  149. //
  150. // variable class
  151. //
  152. // Lazy variables
  153. //
  154. // A bound actual parameter may also be held by non-const reference
  155. // in a variable class for deferred access later when needed. A
  156. // variable object is mutable, i.e. its referenced variable can be
  157. // modified. Variable objects are typically created through the
  158. // var(x) free function which returns a variable<T> with T deduced
  159. // from the type of x. x is held in the value<T> object by
  160. // reference.
  161. //
  162. // Lazy variables are actors. As such, lazy variables can be
  163. // evaluated through the actor's operator(). Such invocation gives
  164. // the variables's identity. Example:
  165. //
  166. // int i = 3;
  167. // char const* s = "Hello World";
  168. // cout << var(i)() << var(s)();
  169. //
  170. // prints out "3 Hello World"
  171. //
  172. // Another free function const_(x) may also be used. const_(x) creates
  173. // a variable<T const&> object using a constant reference.
  174. //
  175. ///////////////////////////////////////////////////////////////////////////////
  176. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  177. #pragma warning(push)
  178. #pragma warning(disable:4512) //assignment operator could not be generated
  179. #endif
  180. template <typename T>
  181. struct variable {
  182. template <typename TupleT>
  183. struct result { typedef T& type; };
  184. variable(T& var_)
  185. : var(var_) {}
  186. template <typename TupleT>
  187. T&
  188. eval(TupleT const& /*args*/) const
  189. {
  190. return var;
  191. }
  192. T& var;
  193. };
  194. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  195. #pragma warning(pop)
  196. #endif
  197. //////////////////////////////////
  198. template <typename T>
  199. inline actor<variable<T> > const
  200. var(T& v)
  201. {
  202. return variable<T>(v);
  203. }
  204. //////////////////////////////////
  205. template <typename T>
  206. inline actor<variable<T const> > const
  207. const_(T const& v)
  208. {
  209. return variable<T const>(v);
  210. }
  211. //////////////////////////////////
  212. template <typename BaseT>
  213. void
  214. var(actor<BaseT> const& v); // This is undefined and not allowed.
  215. //////////////////////////////////
  216. template <typename BaseT>
  217. void
  218. const_(actor<BaseT> const& v); // This is undefined and not allowed.
  219. ///////////////////////////////////////////////////////////////////////////////
  220. } // namespace phoenix
  221. #endif