omit.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. #if defined(_MSC_VER) && _MSC_VER < 1900
  65. # pragma warning(push)
  66. # pragma warning(disable: 4127) // conditional expression is constant
  67. #endif
  68. // omit[] will execute the code, while skip[] doesn't execute it
  69. if (Execute) {
  70. #if defined(_MSC_VER) && _MSC_VER < 1900
  71. # pragma warning(pop)
  72. #endif
  73. // wrap the given output iterator to avoid output
  74. detail::disable_output<OutputIterator> disable(sink);
  75. return subject.generate(sink, ctx, d, attr);
  76. }
  77. return true;
  78. }
  79. template <typename Context>
  80. info what(Context& context) const
  81. {
  82. return info(Execute ? "omit" : "skip", subject.what(context));
  83. }
  84. Subject subject;
  85. };
  86. ///////////////////////////////////////////////////////////////////////////
  87. // Generator generators: make_xxx function (objects)
  88. ///////////////////////////////////////////////////////////////////////////
  89. template <typename Subject, typename Modifiers>
  90. struct make_directive<tag::omit, Subject, Modifiers>
  91. {
  92. typedef omit_directive<Subject, true> result_type;
  93. result_type operator()(unused_type, Subject const& subject
  94. , unused_type) const
  95. {
  96. return result_type(subject);
  97. }
  98. };
  99. template <typename Subject, typename Modifiers>
  100. struct make_directive<tag::skip, Subject, Modifiers>
  101. {
  102. typedef omit_directive<Subject, false> result_type;
  103. result_type operator()(unused_type, Subject const& subject
  104. , unused_type) const
  105. {
  106. return result_type(subject);
  107. }
  108. };
  109. }}}
  110. namespace boost { namespace spirit { namespace traits
  111. {
  112. ///////////////////////////////////////////////////////////////////////////
  113. template <typename Subject, bool Execute>
  114. struct has_semantic_action<karma::omit_directive<Subject, Execute> >
  115. : unary_has_semantic_action<Subject> {};
  116. ///////////////////////////////////////////////////////////////////////////
  117. template <typename Subject, bool Execute, typename Attribute
  118. , typename Context, typename Iterator>
  119. struct handles_container<karma::omit_directive<Subject, Execute>, Attribute
  120. , Context, Iterator>
  121. : unary_handles_container<Subject, Attribute, Context, Iterator> {};
  122. }}}
  123. #endif