File indexing completed on 2025-01-19 09:47:45
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_SPIRIT_QI_NUMERIC_BOOL_HPP
0009 #define BOOST_SPIRIT_QI_NUMERIC_BOOL_HPP
0010
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014
0015 #include <boost/spirit/home/qi/skip_over.hpp>
0016 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
0017 #include <boost/spirit/home/qi/meta_compiler.hpp>
0018 #include <boost/spirit/home/qi/parser.hpp>
0019 #include <boost/spirit/home/qi/numeric/bool_policies.hpp>
0020 #include <boost/spirit/home/support/common_terminals.hpp>
0021 #include <boost/mpl/assert.hpp>
0022 #include <boost/detail/workaround.hpp>
0023 #include <boost/type_traits/is_same.hpp>
0024
0025 namespace boost { namespace spirit
0026 {
0027 namespace qi
0028 {
0029
0030
0031 template <typename T>
0032 struct bool_policies;
0033
0034
0035
0036
0037 template <typename T, typename BoolPolicies = bool_policies<T> >
0038 struct bool_parser
0039 : spirit::terminal<tag::stateful_tag<BoolPolicies, tag::bool_, T> >
0040 {
0041 typedef tag::stateful_tag<BoolPolicies, tag::bool_, T> tag_type;
0042
0043 bool_parser() {}
0044 bool_parser(BoolPolicies const& data)
0045 : spirit::terminal<tag_type>(data) {}
0046 };
0047 }
0048
0049
0050
0051
0052 template <>
0053 struct use_terminal<qi::domain, tag::bool_>
0054 : mpl::true_ {};
0055
0056 template <>
0057 struct use_terminal<qi::domain, tag::true_>
0058 : mpl::true_ {};
0059
0060 template <>
0061 struct use_terminal<qi::domain, tag::false_>
0062 : mpl::true_ {};
0063
0064
0065 template <typename A0>
0066 struct use_terminal<qi::domain
0067 , terminal_ex<tag::lit, fusion::vector1<A0> >
0068 , typename enable_if<is_same<A0, bool> >::type>
0069 : mpl::true_ {};
0070
0071
0072 template <typename A0>
0073 struct use_terminal<qi::domain
0074 , terminal_ex<tag::bool_, fusion::vector1<A0> >
0075 > : mpl::true_ {};
0076
0077 template <>
0078 struct use_lazy_terminal<qi::domain, tag::bool_, 1>
0079 : mpl::true_ {};
0080
0081
0082
0083 template <typename T, typename BoolPolicies>
0084 struct use_terminal<qi::domain
0085 , tag::stateful_tag<BoolPolicies, tag::bool_, T> >
0086 : mpl::true_ {};
0087
0088
0089 template <typename T, typename BoolPolicies, typename A0>
0090 struct use_terminal<qi::domain
0091 , terminal_ex<tag::stateful_tag<BoolPolicies, tag::bool_, T>
0092 , fusion::vector1<A0> > >
0093 : mpl::true_ {};
0094
0095
0096 template <typename T, typename BoolPolicies>
0097 struct use_lazy_terminal<
0098 qi::domain
0099 , tag::stateful_tag<BoolPolicies, tag::bool_, T>
0100 , 1
0101 > : mpl::true_ {};
0102 }}
0103
0104 namespace boost { namespace spirit { namespace qi
0105 {
0106 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0107 using spirit::bool_;
0108 using spirit::true_;
0109 using spirit::false_;
0110 using spirit::lit;
0111 #endif
0112 using spirit::bool_type;
0113 using spirit::true_type;
0114 using spirit::false_type;
0115 using spirit::lit_type;
0116
0117 namespace detail
0118 {
0119 template <typename T, typename BoolPolicies>
0120 struct bool_impl
0121 {
0122 template <typename Iterator, typename Attribute>
0123 static bool parse(Iterator& first, Iterator const& last
0124 , Attribute& attr, BoolPolicies const& p, bool allow_true = true
0125 , bool disallow_false = false)
0126 {
0127 if (first == last)
0128 return false;
0129
0130 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0131 (void)p;
0132 #endif
0133 return (allow_true && p.parse_true(first, last, attr)) ||
0134 (!disallow_false && p.parse_false(first, last, attr));
0135 }
0136 };
0137 }
0138
0139
0140
0141
0142 template <typename T, typename BoolPolicies = bool_policies<T> >
0143 struct any_bool_parser
0144 : primitive_parser<any_bool_parser<T, BoolPolicies> >
0145 {
0146 template <typename Context, typename Iterator>
0147 struct attribute
0148 {
0149 typedef T type;
0150 };
0151
0152 template <typename Iterator, typename Context
0153 , typename Skipper, typename Attribute>
0154 bool parse(Iterator& first, Iterator const& last
0155 , Context& , Skipper const& skipper
0156 , Attribute& attr_) const
0157 {
0158 typedef detail::bool_impl<T, BoolPolicies> extract;
0159 qi::skip_over(first, last, skipper);
0160 return extract::parse(first, last, attr_, BoolPolicies());
0161 }
0162
0163 template <typename Context>
0164 info what(Context& ) const
0165 {
0166 return info("boolean");
0167 }
0168 };
0169
0170 template <typename T, typename BoolPolicies = bool_policies<T>
0171 , bool no_attribute = true>
0172 struct literal_bool_parser
0173 : primitive_parser<literal_bool_parser<T, BoolPolicies, no_attribute> >
0174 {
0175 template <typename Value>
0176 literal_bool_parser(Value const& n) : n_(n) {}
0177
0178 template <typename Context, typename Iterator>
0179 struct attribute
0180 : mpl::if_c<no_attribute, unused_type, T>
0181 {};
0182
0183 template <typename Iterator, typename Context
0184 , typename Skipper, typename Attribute>
0185 bool parse(Iterator& first, Iterator const& last
0186 , Context& , Skipper const& skipper
0187 , Attribute& attr_) const
0188 {
0189 typedef detail::bool_impl<T, BoolPolicies> extract;
0190 qi::skip_over(first, last, skipper);
0191 return extract::parse(first, last, attr_, BoolPolicies(), n_, n_);
0192 }
0193
0194 template <typename Context>
0195 info what(Context& ) const
0196 {
0197 return info("boolean");
0198 }
0199
0200 T n_;
0201 };
0202
0203
0204
0205
0206 template <typename T, typename Modifiers
0207 , typename Policies = bool_policies<T> >
0208 struct make_bool
0209 {
0210 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
0211 no_case;
0212
0213 typedef typename mpl::if_<
0214 mpl::and_<
0215 no_case
0216 , is_same<bool_policies<T>, Policies>
0217 >
0218 , any_bool_parser<T, no_case_bool_policies<T> >
0219 , any_bool_parser<T, Policies> >::type
0220 result_type;
0221
0222 result_type operator()(unused_type, unused_type) const
0223 {
0224 return result_type();
0225 }
0226 };
0227
0228 template <typename T, typename Modifiers
0229 , typename Policies = bool_policies<T> >
0230 struct make_direct_bool
0231 {
0232 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
0233 no_case;
0234
0235 typedef typename mpl::if_<
0236 mpl::and_<
0237 no_case
0238 , is_same<bool_policies<T>, Policies>
0239 >
0240 , literal_bool_parser<T, no_case_bool_policies<T>, false>
0241 , literal_bool_parser<T, Policies, false> >::type
0242 result_type;
0243
0244 template <typename Terminal>
0245 result_type operator()(Terminal const& term, unused_type) const
0246 {
0247 return result_type(fusion::at_c<0>(term.args));
0248 }
0249 };
0250
0251 template <typename T, typename Modifiers, bool b
0252 , typename Policies = bool_policies<T> >
0253 struct make_predefined_direct_bool
0254 {
0255 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
0256 no_case;
0257
0258 typedef typename mpl::if_<
0259 mpl::and_<
0260 no_case
0261 , is_same<bool_policies<T>, Policies>
0262 >
0263 , literal_bool_parser<T, no_case_bool_policies<T>, false>
0264 , literal_bool_parser<T, Policies, false> >::type
0265 result_type;
0266
0267 result_type operator()(unused_type, unused_type) const
0268 {
0269 return result_type(b);
0270 }
0271 };
0272
0273 template <typename T, typename Modifiers
0274 , typename Policies = bool_policies<T> >
0275 struct make_literal_bool
0276 {
0277 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
0278 no_case;
0279
0280 typedef typename mpl::if_<
0281 mpl::and_<
0282 no_case
0283 , is_same<bool_policies<T>, Policies>
0284 >
0285 , literal_bool_parser<T, no_case_bool_policies<T> >
0286 , literal_bool_parser<T, Policies> >::type
0287 result_type;
0288
0289 template <typename Terminal>
0290 result_type operator()(Terminal const& term, unused_type) const
0291 {
0292 return result_type(fusion::at_c<0>(term.args));
0293 }
0294 };
0295
0296
0297 template <typename Modifiers, typename A0>
0298 struct make_primitive<
0299 terminal_ex<tag::lit, fusion::vector1<A0> >
0300 , Modifiers, typename enable_if<is_same<A0, bool> >::type>
0301 : make_literal_bool<bool, Modifiers> {};
0302
0303
0304 template <typename Modifiers>
0305 struct make_primitive<tag::false_, Modifiers>
0306 : make_predefined_direct_bool<bool, Modifiers, false>
0307 {};
0308
0309 template <typename Modifiers>
0310 struct make_primitive<tag::true_, Modifiers>
0311 : make_predefined_direct_bool<bool, Modifiers, true>
0312 {};
0313
0314
0315 template <typename T, typename Policies, typename Modifiers>
0316 struct make_primitive<
0317 tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
0318 : make_bool<T, Modifiers, Policies> {};
0319
0320 template <typename T, typename Policies, typename A0, typename Modifiers>
0321 struct make_primitive<
0322 terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
0323 , fusion::vector1<A0> >, Modifiers>
0324 : make_direct_bool<T, Modifiers, Policies> {};
0325
0326
0327 template <typename Modifiers>
0328 struct make_primitive<tag::bool_, Modifiers>
0329 : make_bool<bool, Modifiers> {};
0330
0331 template <typename Modifiers, typename A0>
0332 struct make_primitive<
0333 terminal_ex<tag::bool_
0334 , fusion::vector1<A0> >, Modifiers>
0335 : make_direct_bool<bool, Modifiers> {};
0336 }}}
0337
0338 #endif