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 #ifndef BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP 10 #define BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP 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 29 namespace boost { namespace spirit { namespace qi 30 { 31 template <typename T> 32 struct as 33 : stateful_tag_type<T, tag::as> 34 { 35 //~ BOOST_SPIRIT_ASSERT_MSG( 36 //~ (traits::is_container<T>::type::value), 37 //~ error_type_must_be_a_container, 38 //~ (T)); 39 }; 40 }}} 41 42 namespace boost { namespace spirit 43 { 44 /////////////////////////////////////////////////////////////////////////// 45 // Enablers 46 /////////////////////////////////////////////////////////////////////////// 47 // enables as_string[...] 48 template <> 49 struct use_directive<qi::domain, tag::as_string> 50 : mpl::true_ {}; 51 52 // enables as_wstring[...] 53 template <> 54 struct use_directive<qi::domain, tag::as_wstring> 55 : mpl::true_ {}; 56 57 // enables as<T>[...] 58 template <typename T> 59 struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> > 60 : mpl::true_ 61 {}; 62 }} 63 64 namespace boost { namespace spirit { namespace qi 65 { 66 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 67 using spirit::as_string; 68 using spirit::as_wstring; 69 #endif 70 using spirit::as_string_type; 71 using spirit::as_wstring_type; 72 73 template <typename Subject, typename T> 74 struct as_directive : unary_parser<as_directive<Subject, T> > 75 { 76 typedef Subject subject_type; as_directiveboost::spirit::qi::as_directive77 as_directive(Subject const& subject_) 78 : subject(subject_) {} 79 80 template <typename Context, typename Iterator> 81 struct attribute 82 { 83 typedef T type; 84 }; 85 86 template <typename Iterator, typename Context 87 , typename Skipper, typename Attribute> parseboost::spirit::qi::as_directive88 bool parse(Iterator& first, Iterator const& last 89 , Context& context, Skipper const& skipper, Attribute& attr_) const 90 { 91 Iterator i = first; 92 T as_attr; 93 if (subject.parse(i, last, context, skipper, as_attr)) 94 { 95 spirit::traits::assign_to(as_attr, attr_); 96 first = i; 97 return true; 98 } 99 return false; 100 } 101 102 template <typename Iterator, typename Context, typename Skipper> parseboost::spirit::qi::as_directive103 bool parse(Iterator& first, Iterator const& last 104 , Context& context, Skipper const& skipper, T& attr_) const 105 { 106 Iterator i = first; 107 if (subject.parse(i, last, context, skipper, attr_)) 108 { 109 first = i; 110 return true; 111 } 112 return false; 113 } 114 115 template <typename Context> whatboost::spirit::qi::as_directive116 info what(Context& context) const 117 { 118 return info("as", subject.what(context)); 119 } 120 121 Subject subject; 122 }; 123 124 /////////////////////////////////////////////////////////////////////////// 125 // Parser generators: make_xxx function (objects) 126 /////////////////////////////////////////////////////////////////////////// 127 template <typename Subject, typename Modifiers> 128 struct make_directive<tag::as_string, Subject, Modifiers> 129 { 130 typedef as_directive<Subject, std::string> result_type; operator ()boost::spirit::qi::make_directive131 result_type operator()(unused_type, Subject const& subject 132 , unused_type) const 133 { 134 return result_type(subject); 135 } 136 }; 137 138 template <typename Subject, typename Modifiers> 139 struct make_directive<tag::as_wstring, Subject, Modifiers> 140 { 141 typedef as_directive<Subject, std::basic_string<wchar_t> > result_type; operator ()boost::spirit::qi::make_directive142 result_type operator()(unused_type, Subject const& subject 143 , unused_type) const 144 { 145 return result_type(subject); 146 } 147 }; 148 149 template <typename T, typename Subject, typename Modifiers> 150 struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers> 151 { 152 typedef as_directive<Subject, T> result_type; operator ()boost::spirit::qi::make_directive153 result_type operator()(unused_type, Subject const& subject 154 , unused_type) const 155 { 156 return result_type(subject); 157 } 158 }; 159 }}} 160 161 namespace boost { namespace spirit { namespace traits 162 { 163 /////////////////////////////////////////////////////////////////////////// 164 template <typename Subject, typename T> 165 struct has_semantic_action<qi::as_directive<Subject, T> > 166 : unary_has_semantic_action<Subject> {}; 167 168 /////////////////////////////////////////////////////////////////////////// 169 template <typename Subject, typename T, typename Attribute 170 , typename Context, typename Iterator> 171 struct handles_container<qi::as_directive<Subject, T>, Attribute 172 , Context, Iterator> 173 : mpl::false_ {}; 174 }}} 175 176 #endif 177