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