generate.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #if !defined(BOOST_SPIRIT_KARMA_GENERATE_DEC_01_2009_0734PM)
  6. #define BOOST_SPIRIT_KARMA_GENERATE_DEC_01_2009_0734PM
  7. #if defined(_MSC_VER)
  8. #pragma once
  9. #endif
  10. #include <boost/spirit/home/support/context.hpp>
  11. #include <boost/spirit/home/support/nonterminal/locals.hpp>
  12. #include <boost/spirit/home/karma/detail/generate.hpp>
  13. namespace boost { namespace spirit { namespace karma
  14. {
  15. ///////////////////////////////////////////////////////////////////////////
  16. template <typename OutputIterator, typename Expr>
  17. inline bool
  18. generate(
  19. OutputIterator& sink
  20. , Expr const& expr)
  21. {
  22. return detail::generate_impl<Expr>::call(sink, expr);
  23. }
  24. template <typename OutputIterator, typename Expr>
  25. inline bool
  26. generate(
  27. OutputIterator const& sink_
  28. , Expr const& expr)
  29. {
  30. OutputIterator sink = sink_;
  31. return karma::generate(sink, expr);
  32. }
  33. ///////////////////////////////////////////////////////////////////////////
  34. namespace detail
  35. {
  36. template <typename T>
  37. struct make_context
  38. {
  39. typedef context<fusion::cons<T const&>, locals<> > type;
  40. };
  41. template <>
  42. struct make_context<unused_type>
  43. {
  44. typedef unused_type type;
  45. };
  46. }
  47. template <typename OutputIterator, typename Properties, typename Expr
  48. , typename Attr>
  49. inline bool
  50. generate(
  51. detail::output_iterator<OutputIterator, Properties>& sink
  52. , Expr const& expr
  53. , Attr const& attr)
  54. {
  55. // Report invalid expression error as early as possible.
  56. // If you got an error_invalid_expression error message here,
  57. // then the expression (expr) is not a valid spirit karma expression.
  58. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  59. typename detail::make_context<Attr>::type context(attr);
  60. return compile<karma::domain>(expr).generate(sink, context, unused, attr);
  61. }
  62. template <typename OutputIterator, typename Expr, typename Attr>
  63. inline bool
  64. generate(
  65. OutputIterator& sink_
  66. , Expr const& expr
  67. , Attr const& attr)
  68. {
  69. // Report invalid expression error as early as possible.
  70. // If you got an error_invalid_expression error message here,
  71. // then the expression (expr) is not a valid spirit karma expression.
  72. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  73. typedef traits::properties_of<
  74. typename result_of::compile<karma::domain, Expr>::type
  75. > properties;
  76. // wrap user supplied iterator into our own output iterator
  77. detail::output_iterator<OutputIterator
  78. , mpl::int_<properties::value> > sink(sink_);
  79. return karma::generate(sink, expr, attr);
  80. }
  81. template <typename OutputIterator, typename Expr, typename Attr>
  82. inline bool
  83. generate(
  84. OutputIterator const& sink_
  85. , Expr const& expr
  86. , Attr const& attr)
  87. {
  88. OutputIterator sink = sink_;
  89. return karma::generate(sink, expr, attr);
  90. }
  91. ///////////////////////////////////////////////////////////////////////////
  92. template <typename OutputIterator, typename Expr, typename Delimiter>
  93. inline bool
  94. generate_delimited(
  95. OutputIterator& sink
  96. , Expr const& expr
  97. , Delimiter const& delimiter
  98. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit =
  99. delimit_flag::dont_predelimit)
  100. {
  101. return detail::generate_delimited_impl<Expr>::call(
  102. sink, expr, delimiter, pre_delimit);
  103. }
  104. template <typename OutputIterator, typename Expr, typename Delimiter>
  105. inline bool
  106. generate_delimited(
  107. OutputIterator const& sink_
  108. , Expr const& expr
  109. , Delimiter const& delimiter
  110. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit =
  111. delimit_flag::dont_predelimit)
  112. {
  113. OutputIterator sink = sink_;
  114. return karma::generate_delimited(sink, expr, delimiter, pre_delimit);
  115. }
  116. ///////////////////////////////////////////////////////////////////////////
  117. template <typename OutputIterator, typename Properties, typename Expr
  118. , typename Delimiter, typename Attribute>
  119. inline bool
  120. generate_delimited(
  121. detail::output_iterator<OutputIterator, Properties>& sink
  122. , Expr const& expr
  123. , Delimiter const& delimiter
  124. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  125. , Attribute const& attr)
  126. {
  127. // Report invalid expression error as early as possible.
  128. // If you got an error_invalid_expression error message here,
  129. // then either the expression (expr) or skipper is not a valid
  130. // spirit karma expression.
  131. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  132. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
  133. typename result_of::compile<karma::domain, Delimiter>::type const
  134. delimiter_ = compile<karma::domain>(delimiter);
  135. if (pre_delimit == delimit_flag::predelimit &&
  136. !karma::delimit_out(sink, delimiter_))
  137. {
  138. return false;
  139. }
  140. typename detail::make_context<Attribute>::type context(attr);
  141. return compile<karma::domain>(expr).
  142. generate(sink, context, delimiter_, attr);
  143. }
  144. template <typename OutputIterator, typename Expr, typename Delimiter
  145. , typename Attribute>
  146. inline bool
  147. generate_delimited(
  148. OutputIterator& sink_
  149. , Expr const& expr
  150. , Delimiter const& delimiter
  151. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  152. , Attribute const& attr)
  153. {
  154. typedef traits::properties_of<
  155. typename result_of::compile<karma::domain, Expr>::type
  156. > properties;
  157. typedef traits::properties_of<
  158. typename result_of::compile<karma::domain, Delimiter>::type
  159. > delimiter_properties;
  160. // wrap user supplied iterator into our own output iterator
  161. detail::output_iterator<OutputIterator
  162. , mpl::int_<properties::value | delimiter_properties::value>
  163. > sink(sink_);
  164. return karma::generate_delimited(sink, expr, delimiter, pre_delimit, attr);
  165. }
  166. template <typename OutputIterator, typename Expr, typename Delimiter
  167. , typename Attribute>
  168. inline bool
  169. generate_delimited(
  170. OutputIterator const& sink_
  171. , Expr const& expr
  172. , Delimiter const& delimiter
  173. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  174. , Attribute const& attr)
  175. {
  176. OutputIterator sink = sink_;
  177. return karma::generate_delimited(sink, expr, delimiter, pre_delimit, attr);
  178. }
  179. ///////////////////////////////////////////////////////////////////////////
  180. template <typename OutputIterator, typename Expr, typename Delimiter
  181. , typename Attribute>
  182. inline bool
  183. generate_delimited(
  184. OutputIterator& sink
  185. , Expr const& expr
  186. , Delimiter const& delimiter
  187. , Attribute const& attr)
  188. {
  189. return karma::generate_delimited(sink, expr, delimiter
  190. , delimit_flag::dont_predelimit, attr);
  191. }
  192. template <typename OutputIterator, typename Expr, typename Delimiter
  193. , typename Attribute>
  194. inline bool
  195. generate_delimited(
  196. OutputIterator const& sink_
  197. , Expr const& expr
  198. , Delimiter const& delimiter
  199. , Attribute const& attr)
  200. {
  201. OutputIterator sink = sink_;
  202. return karma::generate_delimited(sink, expr, delimiter
  203. , delimit_flag::dont_predelimit, attr);
  204. }
  205. }}}
  206. #endif