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