omit.hpp 5.0 KB

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