generate_attr.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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_PP_IS_ITERATING)
  6. #if !defined(BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM)
  7. #define BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM
  8. #include <boost/spirit/home/karma/generate.hpp>
  9. #include <boost/fusion/include/vector.hpp>
  10. #include <boost/preprocessor/cat.hpp>
  11. #include <boost/preprocessor/iterate.hpp>
  12. #include <boost/preprocessor/repetition/enum.hpp>
  13. #include <boost/preprocessor/repetition/enum_params.hpp>
  14. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  15. #define BOOST_PP_FILENAME_1 <boost/spirit/home/karma/generate_attr.hpp>
  16. #define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
  17. #include BOOST_PP_ITERATE()
  18. #endif
  19. ///////////////////////////////////////////////////////////////////////////////
  20. //
  21. // Preprocessor vertical repetition code
  22. //
  23. ///////////////////////////////////////////////////////////////////////////////
  24. #else // defined(BOOST_PP_IS_ITERATING)
  25. #define N BOOST_PP_ITERATION()
  26. #define BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE(z, n, A) \
  27. BOOST_PP_CAT(A, n) const&
  28. namespace boost { namespace spirit { namespace karma
  29. {
  30. ///////////////////////////////////////////////////////////////////////////
  31. template <typename OutputIterator, typename Properties, typename Expr
  32. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  33. inline bool
  34. generate(
  35. detail::output_iterator<OutputIterator, Properties>& sink
  36. , Expr const& expr
  37. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  38. {
  39. // Report invalid expression error as early as possible.
  40. // If you got an error_invalid_expression error message here,
  41. // then the expression (expr) is not a valid spirit karma expression.
  42. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  43. typedef fusion::vector<
  44. BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
  45. > vector_type;
  46. vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
  47. return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
  48. }
  49. template <typename OutputIterator, typename Expr
  50. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  51. inline bool
  52. generate(
  53. OutputIterator& sink_
  54. , Expr const& expr
  55. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  56. {
  57. typedef traits::properties_of<
  58. typename result_of::compile<karma::domain, Expr>::type
  59. > properties;
  60. // wrap user supplied iterator into our own output iterator
  61. detail::output_iterator<OutputIterator
  62. , mpl::int_<properties::value> > sink(sink_);
  63. return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
  64. }
  65. template <typename OutputIterator, typename Expr
  66. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  67. inline bool
  68. generate(
  69. OutputIterator const& sink_
  70. , Expr const& expr
  71. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  72. {
  73. OutputIterator sink = sink_;
  74. return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
  75. }
  76. ///////////////////////////////////////////////////////////////////////////
  77. template <typename OutputIterator, typename Properties, typename Expr
  78. , typename Delimiter, BOOST_PP_ENUM_PARAMS(N, typename A)>
  79. inline bool
  80. generate_delimited(
  81. detail::output_iterator<OutputIterator, Properties>& sink
  82. , Expr const& expr
  83. , Delimiter const& delimiter
  84. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  85. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  86. {
  87. // Report invalid expression error as early as possible.
  88. // If you got an error_invalid_expression error message here,
  89. // then either the expression (expr) or skipper is not a valid
  90. // spirit karma expression.
  91. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  92. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
  93. typename result_of::compile<karma::domain, Delimiter>::type const
  94. delimiter_ = compile<karma::domain>(delimiter);
  95. if (pre_delimit == delimit_flag::predelimit &&
  96. !karma::delimit_out(sink, delimiter_))
  97. {
  98. return false;
  99. }
  100. typedef fusion::vector<
  101. BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
  102. > vector_type;
  103. vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
  104. return compile<karma::domain>(expr).
  105. generate(sink, unused, delimiter_, attr);
  106. }
  107. template <typename OutputIterator, typename Expr, typename Delimiter
  108. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  109. inline bool
  110. generate_delimited(
  111. OutputIterator& sink_
  112. , Expr const& expr
  113. , Delimiter const& delimiter
  114. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  115. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  116. {
  117. typedef traits::properties_of<
  118. typename result_of::compile<karma::domain, Expr>::type
  119. > properties;
  120. typedef traits::properties_of<
  121. typename result_of::compile<karma::domain, Delimiter>::type
  122. > delimiter_properties;
  123. // wrap user supplied iterator into our own output iterator
  124. detail::output_iterator<OutputIterator
  125. , mpl::int_<properties::value | delimiter_properties::value>
  126. > sink(sink_);
  127. return karma::generate_delimited(sink, expr, delimiter, pre_delimit
  128. , BOOST_PP_ENUM_PARAMS(N, attr));
  129. }
  130. template <typename OutputIterator, typename Expr, typename Delimiter
  131. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  132. inline bool
  133. generate_delimited(
  134. OutputIterator const& sink_
  135. , Expr const& expr
  136. , Delimiter const& delimiter
  137. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
  138. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  139. {
  140. OutputIterator sink = sink_;
  141. return karma::generate_delimited(sink, expr, delimiter, pre_delimit
  142. , BOOST_PP_ENUM_PARAMS(N, attr));
  143. }
  144. ///////////////////////////////////////////////////////////////////////////
  145. template <typename OutputIterator, typename Expr, typename Delimiter
  146. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  147. inline bool
  148. generate_delimited(
  149. OutputIterator& sink_
  150. , Expr const& expr
  151. , Delimiter const& delimiter
  152. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, 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
  165. , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
  166. }
  167. template <typename OutputIterator, typename Expr, typename Delimiter
  168. , BOOST_PP_ENUM_PARAMS(N, typename A)>
  169. inline bool
  170. generate_delimited(
  171. OutputIterator const& sink_
  172. , Expr const& expr
  173. , Delimiter const& delimiter
  174. , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
  175. {
  176. OutputIterator sink = sink_;
  177. return karma::generate_delimited(sink, expr, delimiter
  178. , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
  179. }
  180. }}}
  181. #undef BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE
  182. #undef N
  183. #endif // defined(BOOST_PP_IS_ITERATING)