9
3

generate.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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_DETAIL_GENERATE_FEB_20_2007_0959AM)
  6. #define BOOST_SPIRIT_KARMA_DETAIL_GENERATE_FEB_20_2007_0959AM
  7. #if defined(_MSC_VER)
  8. #pragma once
  9. #endif
  10. #include <boost/spirit/home/karma/meta_compiler.hpp>
  11. #include <boost/spirit/home/karma/delimit_out.hpp>
  12. #include <boost/spirit/home/karma/delimit_flag.hpp>
  13. #include <boost/spirit/home/karma/detail/output_iterator.hpp>
  14. #include <boost/spirit/home/support/unused.hpp>
  15. #include <boost/mpl/assert.hpp>
  16. #include <boost/mpl/bool.hpp>
  17. namespace boost { namespace spirit { namespace karma { namespace detail
  18. {
  19. ///////////////////////////////////////////////////////////////////////////
  20. template <typename Expr, typename Enable = void>
  21. struct generate_impl
  22. {
  23. // Report invalid expression error as early as possible.
  24. // If you got an error_invalid_expression error message here,
  25. // then the expression (Expr) is not a valid spirit karma expression.
  26. // Did you intend to use the auto_ facilities while forgetting to
  27. // #include <boost/spirit/include/karma_auto.hpp>?
  28. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  29. };
  30. template <typename Expr>
  31. struct generate_impl<Expr
  32. , typename enable_if<traits::matches<karma::domain, Expr> >::type>
  33. {
  34. template <typename OutputIterator>
  35. static bool call(
  36. OutputIterator& target_sink
  37. , Expr const& expr)
  38. {
  39. typedef traits::properties_of<
  40. typename result_of::compile<karma::domain, Expr>::type
  41. > properties;
  42. // wrap user supplied iterator into our own output iterator
  43. output_iterator<OutputIterator
  44. , mpl::int_<properties::value> > sink(target_sink);
  45. return compile<karma::domain>(expr).
  46. generate(sink, unused, unused, unused);
  47. }
  48. template <typename OutputIterator, typename Properties>
  49. static bool call(
  50. detail::output_iterator<OutputIterator, Properties>& sink
  51. , Expr const& expr)
  52. {
  53. return compile<karma::domain>(expr).
  54. generate(sink, unused, unused, unused);
  55. }
  56. };
  57. ///////////////////////////////////////////////////////////////////////////
  58. template <typename Expr, typename Enable = void>
  59. struct generate_delimited_impl
  60. {
  61. // Report invalid expression error as early as possible.
  62. // If you got an error_invalid_expression error message here,
  63. // then the expression (Expr) is not a valid spirit karma expression.
  64. // Did you intend to use the auto_ facilities while forgetting to
  65. // #include <boost/spirit/include/karma_auto.hpp>?
  66. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
  67. };
  68. template <typename Expr>
  69. struct generate_delimited_impl<Expr
  70. , typename enable_if<traits::matches<karma::domain, Expr> >::type>
  71. {
  72. template <typename OutputIterator, typename Delimiter>
  73. static bool call(
  74. OutputIterator& target_sink
  75. , Expr const& expr
  76. , Delimiter const& delimiter
  77. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
  78. {
  79. typedef traits::properties_of<
  80. typename result_of::compile<karma::domain, Expr>::type
  81. > properties;
  82. typedef traits::properties_of<
  83. typename result_of::compile<karma::domain, Delimiter>::type
  84. > delimiter_properties;
  85. // wrap user supplied iterator into our own output iterator
  86. detail::output_iterator<OutputIterator
  87. , mpl::int_<properties::value | delimiter_properties::value>
  88. > sink(target_sink);
  89. return call(sink, expr, delimiter, pre_delimit);
  90. }
  91. template <typename OutputIterator, typename Properties
  92. , typename Delimiter>
  93. static bool call(
  94. detail::output_iterator<OutputIterator, Properties>& sink
  95. , Expr const& expr
  96. , Delimiter const& delimiter
  97. , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
  98. {
  99. // Report invalid expression error as early as possible.
  100. // If you got an error_invalid_expression error message here,
  101. // then the delimiter is not a valid spirit karma expression.
  102. BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
  103. typename result_of::compile<karma::domain, Delimiter>::type const
  104. delimiter_ = compile<karma::domain>(delimiter);
  105. if (pre_delimit == delimit_flag::predelimit &&
  106. !karma::delimit_out(sink, delimiter_))
  107. {
  108. return false;
  109. }
  110. return compile<karma::domain>(expr).
  111. generate(sink, unused, delimiter_, unused);
  112. }
  113. };
  114. }}}}
  115. #endif