/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Copyright (c) 2010 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(BOOST_SPIRIT_LIT_APR_18_2006_1125PM) #define BOOST_SPIRIT_LIT_APR_18_2006_1125PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { /////////////////////////////////////////////////////////////////////////// // Enablers /////////////////////////////////////////////////////////////////////////// template struct use_terminal >::type> // enables strings : mpl::true_ {}; template struct use_terminal // enables string(str) , fusion::vector1 > > : traits::is_string {}; template // enables string(f) struct use_lazy_terminal< qi::domain , tag::char_code , 1 /*arity*/ > : mpl::true_ {}; // enables lit(...) template struct use_terminal > , typename enable_if >::type> : mpl::true_ {}; }} namespace boost { namespace spirit { namespace qi { #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS using spirit::lit; #endif using spirit::lit_type; /////////////////////////////////////////////////////////////////////////// // Parse for literal strings /////////////////////////////////////////////////////////////////////////// template struct literal_string : primitive_parser > { typedef typename remove_const::type>::type char_type; typedef std::basic_string string_type; literal_string(typename add_reference::type str_) : str(str_) {} template struct attribute { typedef typename mpl::if_c< no_attribute, unused_type, string_type>::type type; }; template bool parse(Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const { qi::skip_over(first, last, skipper); return detail::string_parse(str, first, last, attr_); } template info what(Context& /*context*/) const { return info("literal-string", str); } String str; // silence MSVC warning C4512: assignment operator could not be generated BOOST_DELETED_FUNCTION(literal_string& operator= (literal_string const&)) }; template struct no_case_literal_string : primitive_parser > { typedef typename remove_const::type>::type char_type; typedef std::basic_string string_type; template no_case_literal_string(char_type const* in, CharEncoding encoding) : str_lo(in) , str_hi(in) { #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) encoding; // suppresses warning: C4100: 'encoding' : unreferenced formal parameter #endif typename string_type::iterator loi = str_lo.begin(); typename string_type::iterator hii = str_hi.begin(); for (; loi != str_lo.end(); ++loi, ++hii, ++in) { typedef typename CharEncoding::char_type encoded_char_type; *loi = static_cast(encoding.tolower(encoded_char_type(*loi))); *hii = static_cast(encoding.toupper(encoded_char_type(*hii))); } } template struct attribute { typedef typename mpl::if_c< no_attribute, unused_type, string_type>::type type; }; template bool parse(Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const { qi::skip_over(first, last, skipper); return detail::string_parse(str_lo, str_hi, first, last, attr_); } template info what(Context& /*context*/) const { return info("no-case-literal-string", str_lo); } string_type str_lo, str_hi; }; /////////////////////////////////////////////////////////////////////////// // Parser generators: make_xxx function (objects) /////////////////////////////////////////////////////////////////////////// template struct make_primitive >::type> { typedef has_modifier > no_case; typedef typename add_const::type const_string; typedef typename mpl::if_< no_case , no_case_literal_string , literal_string >::type result_type; result_type operator()( typename add_reference::type str, unused_type) const { return op(str, no_case()); } template result_type op(String const& str, mpl::false_) const { return result_type(str); } template result_type op(String const& str, mpl::true_) const { typename spirit::detail::get_encoding::type encoding; return result_type(traits::get_c_string(str), encoding); } }; // lit("...") template struct make_primitive< terminal_ex > , Modifiers , typename enable_if >::type> { typedef has_modifier > no_case; typedef typename add_const::type const_string; typedef typename mpl::if_< no_case , no_case_literal_string , literal_string >::type result_type; template result_type operator()(Terminal const& term, unused_type) const { return op(fusion::at_c<0>(term.args), no_case()); } template result_type op(String const& str, mpl::false_) const { return result_type(str); } template result_type op(String const& str, mpl::true_) const { typedef typename traits::char_encoding_from_char< typename traits::char_type_of::type>::type encoding_type; typename spirit::detail::get_encoding::type encoding; return result_type(traits::get_c_string(str), encoding); } }; /////////////////////////////////////////////////////////////////////////// // string("...") template struct make_primitive< terminal_ex< tag::char_code , fusion::vector1 > , Modifiers> { typedef CharEncoding encoding; typedef has_modifier > no_case; typedef typename add_const::type const_string; typedef typename mpl::if_< no_case , no_case_literal_string , literal_string >::type result_type; template result_type operator()(Terminal const& term, unused_type) const { return op(fusion::at_c<0>(term.args), no_case()); } template result_type op(String const& str, mpl::false_) const { return result_type(str); } template result_type op(String const& str, mpl::true_) const { return result_type(traits::get_c_string(str), encoding()); } }; }}} namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// template struct handles_container , Attribute, Context, Iterator> : mpl::true_ {}; template struct handles_container , Attribute, Context, Iterator> : mpl::true_ {}; }}} #endif