/*============================================================================= Copyright (c) 2001-2011 Hartmut Kaiser Copyright (c) 2011 Bryce Lelbach Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(SPIRIT_QI_BOOL_SEP_29_2009_0709AM) #define SPIRIT_QI_BOOL_SEP_29_2009_0709AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace qi { /////////////////////////////////////////////////////////////////////// // forward declaration only template struct bool_policies; /////////////////////////////////////////////////////////////////////// // This is the class that the user can instantiate directly in // order to create a customized bool parser template > struct bool_parser : spirit::terminal > { typedef tag::stateful_tag tag_type; bool_parser() {} bool_parser(BoolPolicies const& data) : spirit::terminal(data) {} }; } /////////////////////////////////////////////////////////////////////////// // Enablers /////////////////////////////////////////////////////////////////////////// template <> // enables bool_ struct use_terminal : mpl::true_ {}; template <> // enables true_ struct use_terminal : mpl::true_ {}; template <> // enables false_ struct use_terminal : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// template // enables lit(...) struct use_terminal > , typename enable_if >::type> : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// template // enables bool_(...) struct use_terminal > > : mpl::true_ {}; template <> // enables *lazy* bool_(...) struct use_lazy_terminal : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// // enables any custom bool_parser template struct use_terminal > : mpl::true_ {}; // enables any custom bool_parser(...) template struct use_terminal , fusion::vector1 > > : mpl::true_ {}; // enables *lazy* custom bool_parser(...) template struct use_lazy_terminal< qi::domain , tag::stateful_tag , 1 // arity > : mpl::true_ {}; }} namespace boost { namespace spirit { namespace qi { #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS using spirit::bool_; using spirit::true_; using spirit::false_; using spirit::lit; // lit(true) is equivalent to true #endif using spirit::bool_type; using spirit::true_type; using spirit::false_type; using spirit::lit_type; namespace detail { template struct bool_impl { template static bool parse(Iterator& first, Iterator const& last , Attribute& attr, BoolPolicies const& p, bool allow_true = true , bool disallow_false = false) { if (first == last) return false; #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) p; // suppresses warning: C4100: 'p' : unreferenced formal parameter #endif return (allow_true && p.parse_true(first, last, attr)) || (!disallow_false && p.parse_false(first, last, attr)); } }; } /////////////////////////////////////////////////////////////////////////// // This actual boolean parser /////////////////////////////////////////////////////////////////////////// template > struct any_bool_parser : primitive_parser > { template struct attribute { typedef T type; }; template bool parse(Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , Attribute& attr_) const { typedef detail::bool_impl extract; qi::skip_over(first, last, skipper); return extract::parse(first, last, attr_, BoolPolicies()); } template info what(Context& /*context*/) const { return info("boolean"); } }; template , bool no_attribute = true> struct literal_bool_parser : primitive_parser > { template literal_bool_parser(Value const& n) : n_(n) {} template struct attribute : mpl::if_c {}; template bool parse(Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , Attribute& attr_) const { typedef detail::bool_impl extract; qi::skip_over(first, last, skipper); return extract::parse(first, last, attr_, BoolPolicies(), n_, n_); } template info what(Context& /*context*/) const { return info("boolean"); } T n_; }; /////////////////////////////////////////////////////////////////////////// // Parser generators: make_xxx function (objects) /////////////////////////////////////////////////////////////////////////// template > struct make_bool { typedef has_modifier > no_case; typedef typename mpl::if_< mpl::and_< no_case , is_same, Policies> > , any_bool_parser > , any_bool_parser >::type result_type; result_type operator()(unused_type, unused_type) const { return result_type(); } }; template > struct make_direct_bool { typedef has_modifier > no_case; typedef typename mpl::if_< mpl::and_< no_case , is_same, Policies> > , literal_bool_parser, false> , literal_bool_parser >::type result_type; template result_type operator()(Terminal const& term, unused_type) const { return result_type(fusion::at_c<0>(term.args)); } }; template > struct make_predefined_direct_bool { typedef has_modifier > no_case; typedef typename mpl::if_< mpl::and_< no_case , is_same, Policies> > , literal_bool_parser, false> , literal_bool_parser >::type result_type; result_type operator()(unused_type, unused_type) const { return result_type(b); } }; template > struct make_literal_bool { typedef has_modifier > no_case; typedef typename mpl::if_< mpl::and_< no_case , is_same, Policies> > , literal_bool_parser > , literal_bool_parser >::type result_type; template result_type operator()(Terminal const& term, unused_type) const { return result_type(fusion::at_c<0>(term.args)); } }; /////////////////////////////////////////////////////////////////////////// template struct make_primitive< terminal_ex > , Modifiers, typename enable_if >::type> : make_literal_bool {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive : make_predefined_direct_bool {}; template struct make_primitive : make_predefined_direct_bool {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive< tag::stateful_tag, Modifiers> : make_bool {}; template struct make_primitive< terminal_ex , fusion::vector1 >, Modifiers> : make_direct_bool {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive : make_bool {}; template struct make_primitive< terminal_ex >, Modifiers> : make_direct_bool {}; }}} #endif