File indexing completed on 2025-01-19 09:47:35
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_CHAR_GENERATOR_SEP_07_2009_0417PM)
0008 #define BOOST_SPIRIT_CHAR_GENERATOR_SEP_07_2009_0417PM
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/spirit/home/karma/domain.hpp>
0015 #include <boost/spirit/home/karma/generator.hpp>
0016 #include <boost/spirit/home/karma/detail/generate_to.hpp>
0017 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0018 #include <boost/spirit/home/karma/meta_compiler.hpp>
0019 #include <boost/spirit/home/karma/delimit_out.hpp>
0020 #include <boost/spirit/home/support/unused.hpp>
0021 #include <boost/spirit/home/support/info.hpp>
0022 #include <boost/spirit/home/support/container.hpp>
0023 #include <boost/proto/operators.hpp>
0024 #include <boost/proto/tags.hpp>
0025
0026 namespace boost { namespace spirit
0027 {
0028
0029
0030
0031 template <>
0032 struct use_operator<karma::domain, proto::tag::complement>
0033 : mpl::true_ {};
0034
0035 }}
0036
0037 namespace boost { namespace spirit { namespace traits
0038 {
0039 namespace detail
0040 {
0041 BOOST_MPL_HAS_XXX_TRAIT_DEF(char_generator_id)
0042 }
0043
0044 template <typename T>
0045 struct is_char_generator : detail::has_char_generator_id<T> {};
0046 }}}
0047
0048 namespace boost { namespace spirit { namespace karma
0049 {
0050
0051
0052
0053 template <typename Derived, typename CharEncoding, typename Tag
0054 , typename Char = typename CharEncoding::char_type, typename Attr = Char>
0055 struct char_generator : primitive_generator<Derived>
0056 {
0057 typedef CharEncoding char_encoding;
0058 typedef Tag tag;
0059 typedef Char char_type;
0060 struct char_generator_id;
0061
0062
0063
0064 template <typename Context, typename Unused>
0065 struct attribute
0066 {
0067 typedef Attr type;
0068 };
0069
0070 template <
0071 typename OutputIterator, typename Context, typename Delimiter
0072 , typename Attribute>
0073 bool generate(OutputIterator& sink, Context& context, Delimiter const& d
0074 , Attribute const& attr) const
0075 {
0076 if (!traits::has_optional_value(attr))
0077 return false;
0078
0079 Attr ch = Attr();
0080 if (!this->derived().test(traits::extract_from<Attr>(attr, context), ch, context))
0081 return false;
0082
0083 return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&
0084 karma::delimit_out(sink, d);
0085 }
0086
0087
0088
0089
0090
0091
0092 };
0093
0094
0095
0096
0097 template <typename Positive>
0098 struct negated_char_generator
0099 : char_generator<negated_char_generator<Positive>
0100 , typename Positive::char_encoding, typename Positive::tag>
0101 {
0102 negated_char_generator(Positive const& positive)
0103 : positive(positive) {}
0104
0105 template <typename Attribute, typename CharParam, typename Context>
0106 bool test(Attribute const& attr, CharParam& ch, Context& context) const
0107 {
0108 return !positive.test(attr, ch, context);
0109 }
0110
0111 template <typename Context>
0112 info what(Context& context) const
0113 {
0114 return info("not", positive.what(context));
0115 }
0116
0117 Positive positive;
0118 };
0119
0120
0121
0122
0123 namespace detail
0124 {
0125 template <typename Positive>
0126 struct make_negated_char_generator
0127 {
0128 typedef negated_char_generator<Positive> result_type;
0129 result_type operator()(Positive const& positive) const
0130 {
0131 return result_type(positive);
0132 }
0133 };
0134
0135 template <typename Positive>
0136 struct make_negated_char_generator<negated_char_generator<Positive> >
0137 {
0138 typedef Positive result_type;
0139 result_type operator()(negated_char_generator<Positive> const& ncg) const
0140 {
0141 return ncg.positive;
0142 }
0143 };
0144 }
0145
0146 template <typename Elements, typename Modifiers>
0147 struct make_composite<proto::tag::complement, Elements, Modifiers>
0148 {
0149 typedef typename
0150 fusion::result_of::value_at_c<Elements, 0>::type
0151 subject;
0152
0153 BOOST_SPIRIT_ASSERT_MSG((
0154 traits::is_char_generator<subject>::value
0155 ), subject_is_not_negatable, (subject));
0156
0157 typedef typename
0158 detail::make_negated_char_generator<subject>::result_type
0159 result_type;
0160
0161 result_type operator()(Elements const& elements, unused_type) const
0162 {
0163 return detail::make_negated_char_generator<subject>()(
0164 fusion::at_c<0>(elements));
0165 }
0166 };
0167
0168 }}}
0169
0170 #endif