]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | =============================================================================*/ | |
f67539c2 TL |
9 | #ifndef BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP |
10 | #define BOOST_SPIRIT_QI_DIRECTIVE_AS_HPP | |
7c673cae FG |
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> | |
7c673cae FG |
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; | |
77 | 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> | |
88 | 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> | |
103 | 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> | |
116 | 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; | |
131 | 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; | |
142 | 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; | |
153 | 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 |