1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 Copyright (c) 2010 Bryce Lelbach 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(SPIRIT_AS_DECEMBER_6_2010_1013AM) 10 #define SPIRIT_AS_DECEMBER_6_2010_1013AM 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/spirit/home/qi/meta_compiler.hpp> 17 #include <boost/spirit/home/qi/skip_over.hpp> 18 #include <boost/spirit/home/qi/parser.hpp> 19 #include <boost/spirit/home/qi/detail/assign_to.hpp> 20 #include <boost/spirit/home/support/unused.hpp> 21 #include <boost/spirit/home/support/info.hpp> 22 #include <boost/spirit/home/support/common_terminals.hpp> 23 #include <boost/spirit/home/support/unused.hpp> 24 #include <boost/spirit/home/support/has_semantic_action.hpp> 25 #include <boost/spirit/home/support/handles_container.hpp> 26 #include <boost/spirit/home/support/assert_msg.hpp> 27 #include <boost/spirit/home/support/container.hpp> 28 #include <boost/range/iterator_range.hpp> 29 #include <string> 30 31 namespace boost { namespace spirit { namespace qi 32 { 33 template <typename T> 34 struct as 35 : stateful_tag_type<T, tag::as> 36 { 37 //~ BOOST_SPIRIT_ASSERT_MSG( 38 //~ (traits::is_container<T>::type::value), 39 //~ error_type_must_be_a_container, 40 //~ (T)); 41 }; 42 }}} 43 44 namespace boost { namespace spirit 45 { 46 /////////////////////////////////////////////////////////////////////////// 47 // Enablers 48 /////////////////////////////////////////////////////////////////////////// 49 // enables as_string[...] 50 template <> 51 struct use_directive<qi::domain, tag::as_string> 52 : mpl::true_ {}; 53 54 // enables as_wstring[...] 55 template <> 56 struct use_directive<qi::domain, tag::as_wstring> 57 : mpl::true_ {}; 58 59 // enables as<T>[...] 60 template <typename T> 61 struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> > 62 : mpl::true_ 63 {}; 64 }} 65 66 namespace boost { namespace spirit { namespace qi 67 { 68 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 69 using spirit::as_string; 70 using spirit::as_wstring; 71 #endif 72 using spirit::as_string_type; 73 using spirit::as_wstring_type; 74 75 template <typename Subject, typename T> 76 struct as_directive : unary_parser<as_directive<Subject, T> > 77 { 78 typedef Subject subject_type; as_directiveboost::spirit::qi::as_directive79 as_directive(Subject const& subject_) 80 : subject(subject_) {} 81 82 template <typename Context, typename Iterator> 83 struct attribute 84 { 85 typedef T type; 86 }; 87 88 template <typename Iterator, typename Context 89 , typename Skipper, typename Attribute> parseboost::spirit::qi::as_directive90 bool parse(Iterator& first, Iterator const& last 91 , Context& context, Skipper const& skipper, Attribute& attr_) const 92 { 93 Iterator i = first; 94 T as_attr; 95 if (subject.parse(i, last, context, skipper, as_attr)) 96 { 97 spirit::traits::assign_to(as_attr, attr_); 98 first = i; 99 return true; 100 } 101 return false; 102 } 103 104 template <typename Iterator, typename Context, typename Skipper> parseboost::spirit::qi::as_directive105 bool parse(Iterator& first, Iterator const& last 106 , Context& context, Skipper const& skipper, T& attr_) const 107 { 108 Iterator i = first; 109 if (subject.parse(i, last, context, skipper, attr_)) 110 { 111 first = i; 112 return true; 113 } 114 return false; 115 } 116 117 template <typename Context> whatboost::spirit::qi::as_directive118 info what(Context& context) const 119 { 120 return info("as", subject.what(context)); 121 } 122 123 Subject subject; 124 }; 125 126 /////////////////////////////////////////////////////////////////////////// 127 // Parser generators: make_xxx function (objects) 128 /////////////////////////////////////////////////////////////////////////// 129 template <typename Subject, typename Modifiers> 130 struct make_directive<tag::as_string, Subject, Modifiers> 131 { 132 typedef as_directive<Subject, std::string> result_type; operator ()boost::spirit::qi::make_directive133 result_type operator()(unused_type, Subject const& subject 134 , unused_type) const 135 { 136 return result_type(subject); 137 } 138 }; 139 140 template <typename Subject, typename Modifiers> 141 struct make_directive<tag::as_wstring, Subject, Modifiers> 142 { 143 typedef as_directive<Subject, std::basic_string<wchar_t> > result_type; operator ()boost::spirit::qi::make_directive144 result_type operator()(unused_type, Subject const& subject 145 , unused_type) const 146 { 147 return result_type(subject); 148 } 149 }; 150 151 template <typename T, typename Subject, typename Modifiers> 152 struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers> 153 { 154 typedef as_directive<Subject, T> result_type; operator ()boost::spirit::qi::make_directive155 result_type operator()(unused_type, Subject const& subject 156 , unused_type) const 157 { 158 return result_type(subject); 159 } 160 }; 161 }}} 162 163 namespace boost { namespace spirit { namespace traits 164 { 165 /////////////////////////////////////////////////////////////////////////// 166 template <typename Subject, typename T> 167 struct has_semantic_action<qi::as_directive<Subject, T> > 168 : unary_has_semantic_action<Subject> {}; 169 170 /////////////////////////////////////////////////////////////////////////// 171 template <typename Subject, typename T, typename Attribute 172 , typename Context, typename Iterator> 173 struct handles_container<qi::as_directive<Subject, T>, Attribute 174 , Context, Iterator> 175 : mpl::false_ {}; 176 }}} 177 178 #endif 179