omit.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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(SPIRIT_KARMA_OMIT_JUL_20_2009_1008AM)
  6. #define SPIRIT_KARMA_OMIT_JUL_20_2009_1008AM
  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/generator.hpp>
  12. #include <boost/spirit/home/karma/domain.hpp>
  13. #include <boost/spirit/home/support/unused.hpp>
  14. #include <boost/spirit/home/support/info.hpp>
  15. #include <boost/spirit/home/support/common_terminals.hpp>
  16. #include <boost/spirit/home/support/has_semantic_action.hpp>
  17. #include <boost/spirit/home/support/handles_container.hpp>
  18. #include <boost/spirit/home/karma/detail/attributes.hpp>
  19. namespace boost { namespace spirit
  20. {
  21. ///////////////////////////////////////////////////////////////////////////
  22. // Enablers
  23. ///////////////////////////////////////////////////////////////////////////
  24. template <>
  25. struct use_directive<karma::domain, tag::omit> // enables omit
  26. : mpl::true_ {};
  27. template <>
  28. struct use_directive<karma::domain, tag::skip> // enables skip
  29. : mpl::true_ {};
  30. }}
  31. namespace boost { namespace spirit { namespace karma
  32. {
  33. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  34. using spirit::omit;
  35. using spirit::skip;
  36. #endif
  37. using spirit::omit_type;
  38. using spirit::skip_type;
  39. ///////////////////////////////////////////////////////////////////////////
  40. // omit_directive consumes the attribute of subject generator without
  41. // generating anything
  42. ///////////////////////////////////////////////////////////////////////////
  43. template <typename Subject, bool Execute>
  44. struct omit_directive : unary_generator<omit_directive<Subject, Execute> >
  45. {
  46. typedef Subject subject_type;
  47. typedef mpl::int_<
  48. generator_properties::disabling | subject_type::properties::value
  49. > properties;
  50. omit_directive(Subject const& subject)
  51. : subject(subject) {}
  52. template <typename Context, typename Iterator = unused_type>
  53. struct attribute
  54. : traits::attribute_of<subject_type, Context, Iterator>
  55. {};
  56. template <typename OutputIterator, typename Context, typename Delimiter
  57. , typename Attribute>
  58. bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
  59. , Attribute const& attr) const
  60. {
  61. // We need to actually compile the output operation as we don't
  62. // have any other means to verify, whether the passed attribute is
  63. // compatible with the subject.
  64. // omit[] will execute the code, while skip[] doesn't execute it
  65. if (Execute) {
  66. // wrap the given output iterator to avoid output
  67. detail::disable_output<OutputIterator> disable(sink);
  68. return subject.generate(sink, ctx, d, attr);
  69. }
  70. return true;
  71. }
  72. template <typename Context>
  73. info what(Context& context) const
  74. {
  75. return info(Execute ? "omit" : "skip", subject.what(context));
  76. }
  77. Subject subject;
  78. };
  79. ///////////////////////////////////////////////////////////////////////////
  80. // Generator generators: make_xxx function (objects)
  81. ///////////////////////////////////////////////////////////////////////////
  82. template <typename Subject, typename Modifiers>
  83. struct make_directive<tag::omit, Subject, Modifiers>
  84. {
  85. typedef omit_directive<Subject, true> result_type;
  86. result_type operator()(unused_type, Subject const& subject
  87. , unused_type) const
  88. {
  89. return result_type(subject);
  90. }
  91. };
  92. template <typename Subject, typename Modifiers>
  93. struct make_directive<tag::skip, Subject, Modifiers>
  94. {
  95. typedef omit_directive<Subject, false> result_type;
  96. result_type operator()(unused_type, Subject const& subject
  97. , unused_type) const
  98. {
  99. return result_type(subject);
  100. }
  101. };
  102. }}}
  103. namespace boost { namespace spirit { namespace traits
  104. {
  105. ///////////////////////////////////////////////////////////////////////////
  106. template <typename Subject, bool Execute>
  107. struct has_semantic_action<karma::omit_directive<Subject, Execute> >
  108. : unary_has_semantic_action<Subject> {};
  109. ///////////////////////////////////////////////////////////////////////////
  110. template <typename Subject, bool Execute, typename Attribute
  111. , typename Context, typename Iterator>
  112. struct handles_container<karma::omit_directive<Subject, Execute>, Attribute
  113. , Context, Iterator>
  114. : unary_handles_container<Subject, Attribute, Context, Iterator> {};
  115. }}}
  116. #endif