Chris@102
|
1 /*=============================================================================
|
Chris@102
|
2 Copyright (c) 2001-2014 Joel de Guzman
|
Chris@102
|
3 Copyright (c) 2013 Carl Barron
|
Chris@102
|
4
|
Chris@102
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
7 ==============================================================================*/
|
Chris@102
|
8 #if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
|
Chris@102
|
9 #define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
|
Chris@102
|
10
|
Chris@102
|
11 #if defined(_MSC_VER)
|
Chris@102
|
12 #pragma once
|
Chris@102
|
13 #endif
|
Chris@102
|
14
|
Chris@102
|
15 #include <boost/spirit/home/x3/core/skip_over.hpp>
|
Chris@102
|
16 #include <boost/spirit/home/x3/core/parser.hpp>
|
Chris@102
|
17 #include <boost/spirit/home/x3/string/tst.hpp>
|
Chris@102
|
18 #include <boost/spirit/home/x3/support/unused.hpp>
|
Chris@102
|
19 #include <boost/spirit/home/x3/support/traits/string_traits.hpp>
|
Chris@102
|
20 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
|
Chris@102
|
21
|
Chris@102
|
22 #include <boost/fusion/include/at.hpp>
|
Chris@102
|
23 #include <boost/range.hpp>
|
Chris@102
|
24 #include <boost/type_traits/add_reference.hpp>
|
Chris@102
|
25 #include <boost/type_traits/is_same.hpp>
|
Chris@102
|
26 #include <boost/shared_ptr.hpp>
|
Chris@102
|
27
|
Chris@102
|
28 #include <initializer_list>
|
Chris@102
|
29
|
Chris@102
|
30 #if defined(BOOST_MSVC)
|
Chris@102
|
31 # pragma warning(push)
|
Chris@102
|
32 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
|
Chris@102
|
33 #endif
|
Chris@102
|
34
|
Chris@102
|
35 namespace boost { namespace spirit { namespace x3
|
Chris@102
|
36 {
|
Chris@102
|
37 template <
|
Chris@102
|
38 typename Char = char
|
Chris@102
|
39 , typename T = unused_type
|
Chris@102
|
40 , typename Lookup = tst<Char, T>
|
Chris@102
|
41 , typename Filter = tst_pass_through>
|
Chris@102
|
42 struct symbols : parser<symbols<Char, T, Lookup, Filter>>
|
Chris@102
|
43 {
|
Chris@102
|
44 typedef Char char_type; // the character type
|
Chris@102
|
45 typedef T value_type; // the value associated with each entry
|
Chris@102
|
46 typedef symbols<Char, T, Lookup, Filter> this_type;
|
Chris@102
|
47 typedef value_type attribute_type;
|
Chris@102
|
48
|
Chris@102
|
49 static bool const has_attribute =
|
Chris@102
|
50 !is_same<unused_type, attribute_type>::value;
|
Chris@102
|
51 static bool const handles_container =
|
Chris@102
|
52 traits::is_container<attribute_type>::value;
|
Chris@102
|
53
|
Chris@102
|
54 symbols(std::string const& name = "symbols")
|
Chris@102
|
55 : add(*this)
|
Chris@102
|
56 , remove(*this)
|
Chris@102
|
57 , lookup(new Lookup())
|
Chris@102
|
58 , name_(name)
|
Chris@102
|
59 {
|
Chris@102
|
60 }
|
Chris@102
|
61
|
Chris@102
|
62 symbols(symbols const& syms)
|
Chris@102
|
63 : add(*this)
|
Chris@102
|
64 , remove(*this)
|
Chris@102
|
65 , lookup(syms.lookup)
|
Chris@102
|
66 , name_(syms.name_)
|
Chris@102
|
67 {
|
Chris@102
|
68 }
|
Chris@102
|
69
|
Chris@102
|
70 template <typename Filter_>
|
Chris@102
|
71 symbols(symbols<Char, T, Lookup, Filter_> const& syms)
|
Chris@102
|
72 : add(*this)
|
Chris@102
|
73 , remove(*this)
|
Chris@102
|
74 , lookup(syms.lookup)
|
Chris@102
|
75 , name_(syms.name_)
|
Chris@102
|
76 {
|
Chris@102
|
77 }
|
Chris@102
|
78
|
Chris@102
|
79 template <typename Symbols>
|
Chris@102
|
80 symbols(Symbols const& syms, std::string const& name = "symbols")
|
Chris@102
|
81 : add(*this)
|
Chris@102
|
82 , remove(*this)
|
Chris@102
|
83 , lookup(new Lookup())
|
Chris@102
|
84 , name_(name)
|
Chris@102
|
85 {
|
Chris@102
|
86 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
|
Chris@102
|
87 while (si != boost::end(syms))
|
Chris@102
|
88 add(*si++);
|
Chris@102
|
89 }
|
Chris@102
|
90
|
Chris@102
|
91 template <typename Symbols, typename Data>
|
Chris@102
|
92 symbols(Symbols const& syms, Data const& data
|
Chris@102
|
93 , std::string const& name = "symbols")
|
Chris@102
|
94 : add(*this)
|
Chris@102
|
95 , remove(*this)
|
Chris@102
|
96 , lookup(new Lookup())
|
Chris@102
|
97 , name_(name)
|
Chris@102
|
98 {
|
Chris@102
|
99 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
|
Chris@102
|
100 typename range_const_iterator<Data>::type di = boost::begin(data);
|
Chris@102
|
101 while (si != boost::end(syms))
|
Chris@102
|
102 add(*si++, *di++);
|
Chris@102
|
103 }
|
Chris@102
|
104
|
Chris@102
|
105 symbols(std::initializer_list<std::pair<Char const*, T>> syms
|
Chris@102
|
106 , std::string const & name="symbols")
|
Chris@102
|
107 : add(*this)
|
Chris@102
|
108 , remove(*this)
|
Chris@102
|
109 , lookup(new Lookup())
|
Chris@102
|
110 , name_(name)
|
Chris@102
|
111 {
|
Chris@102
|
112 typedef std::initializer_list<std::pair<Char const*, T>> symbols_t;
|
Chris@102
|
113 typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
|
Chris@102
|
114 for (;si != boost::end(syms); ++si)
|
Chris@102
|
115 add(si->first, si->second);
|
Chris@102
|
116 }
|
Chris@102
|
117
|
Chris@102
|
118 symbols(std::initializer_list<Char const*> syms
|
Chris@102
|
119 , std::string const &name="symbols")
|
Chris@102
|
120 : add(*this)
|
Chris@102
|
121 , remove(*this)
|
Chris@102
|
122 , lookup(new Lookup())
|
Chris@102
|
123 , name_(name)
|
Chris@102
|
124 {
|
Chris@102
|
125 typedef std::initializer_list<Char const*> symbols_t;
|
Chris@102
|
126 typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
|
Chris@102
|
127 while (si != boost::end(syms))
|
Chris@102
|
128 add(*si++);
|
Chris@102
|
129 }
|
Chris@102
|
130
|
Chris@102
|
131 symbols&
|
Chris@102
|
132 operator=(symbols const& rhs)
|
Chris@102
|
133 {
|
Chris@102
|
134 name_ = rhs.name_;
|
Chris@102
|
135 lookup = rhs.lookup;
|
Chris@102
|
136 return *this;
|
Chris@102
|
137 }
|
Chris@102
|
138
|
Chris@102
|
139 template <typename Filter_>
|
Chris@102
|
140 symbols&
|
Chris@102
|
141 operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
|
Chris@102
|
142 {
|
Chris@102
|
143 name_ = rhs.name_;
|
Chris@102
|
144 lookup = rhs.lookup;
|
Chris@102
|
145 return *this;
|
Chris@102
|
146 }
|
Chris@102
|
147
|
Chris@102
|
148 void clear()
|
Chris@102
|
149 {
|
Chris@102
|
150 lookup->clear();
|
Chris@102
|
151 }
|
Chris@102
|
152
|
Chris@102
|
153 struct adder;
|
Chris@102
|
154 struct remover;
|
Chris@102
|
155
|
Chris@102
|
156 template <typename Str>
|
Chris@102
|
157 adder const&
|
Chris@102
|
158 operator=(Str const& str)
|
Chris@102
|
159 {
|
Chris@102
|
160 lookup->clear();
|
Chris@102
|
161 return add(str);
|
Chris@102
|
162 }
|
Chris@102
|
163
|
Chris@102
|
164 template <typename Str>
|
Chris@102
|
165 friend adder const&
|
Chris@102
|
166 operator+=(symbols& sym, Str const& str)
|
Chris@102
|
167 {
|
Chris@102
|
168 return sym.add(str);
|
Chris@102
|
169 }
|
Chris@102
|
170
|
Chris@102
|
171 template <typename Str>
|
Chris@102
|
172 friend remover const&
|
Chris@102
|
173 operator-=(symbols& sym, Str const& str)
|
Chris@102
|
174 {
|
Chris@102
|
175 return sym.remove(str);
|
Chris@102
|
176 }
|
Chris@102
|
177
|
Chris@102
|
178 template <typename F>
|
Chris@102
|
179 void for_each(F f) const
|
Chris@102
|
180 {
|
Chris@102
|
181 lookup->for_each(f);
|
Chris@102
|
182 }
|
Chris@102
|
183
|
Chris@102
|
184 template <typename Str>
|
Chris@102
|
185 value_type& at(Str const& str)
|
Chris@102
|
186 {
|
Chris@102
|
187 return *lookup->add(traits::get_string_begin<Char>(str)
|
Chris@102
|
188 , traits::get_string_end<Char>(str), T());
|
Chris@102
|
189 }
|
Chris@102
|
190
|
Chris@102
|
191 template <typename Iterator>
|
Chris@102
|
192 value_type* prefix_find(Iterator& first, Iterator const& last)
|
Chris@102
|
193 {
|
Chris@102
|
194 return lookup->find(first, last, Filter());
|
Chris@102
|
195 }
|
Chris@102
|
196
|
Chris@102
|
197 template <typename Iterator>
|
Chris@102
|
198 value_type const* prefix_find(Iterator& first, Iterator const& last) const
|
Chris@102
|
199 {
|
Chris@102
|
200 return lookup->find(first, last, Filter());
|
Chris@102
|
201 }
|
Chris@102
|
202
|
Chris@102
|
203 template <typename Str>
|
Chris@102
|
204 value_type* find(Str const& str)
|
Chris@102
|
205 {
|
Chris@102
|
206 return find_impl(traits::get_string_begin<Char>(str)
|
Chris@102
|
207 , traits::get_string_end<Char>(str));
|
Chris@102
|
208 }
|
Chris@102
|
209
|
Chris@102
|
210 template <typename Str>
|
Chris@102
|
211 value_type const* find(Str const& str) const
|
Chris@102
|
212 {
|
Chris@102
|
213 return find_impl(traits::get_string_begin<Char>(str)
|
Chris@102
|
214 , traits::get_string_end<Char>(str));
|
Chris@102
|
215 }
|
Chris@102
|
216
|
Chris@102
|
217 private:
|
Chris@102
|
218 template <typename Iterator>
|
Chris@102
|
219 value_type* find_impl(Iterator begin, Iterator end)
|
Chris@102
|
220 {
|
Chris@102
|
221 value_type* r = lookup->find(begin, end, Filter());
|
Chris@102
|
222 return begin == end ? r : 0;
|
Chris@102
|
223 }
|
Chris@102
|
224
|
Chris@102
|
225 template <typename Iterator>
|
Chris@102
|
226 value_type const* find_impl(Iterator begin, Iterator end) const
|
Chris@102
|
227 {
|
Chris@102
|
228 value_type const* r = lookup->find(begin, end, Filter());
|
Chris@102
|
229 return begin == end ? r : 0;
|
Chris@102
|
230 }
|
Chris@102
|
231
|
Chris@102
|
232 public:
|
Chris@102
|
233 template <typename Iterator, typename Context, typename Attribute>
|
Chris@102
|
234 bool parse(Iterator& first, Iterator const& last
|
Chris@102
|
235 , Context const& context, unused_type, Attribute& attr) const
|
Chris@102
|
236 {
|
Chris@102
|
237 x3::skip_over(first, last, context);
|
Chris@102
|
238
|
Chris@102
|
239 if (value_type* val_ptr
|
Chris@102
|
240 = lookup->find(first, last, Filter()))
|
Chris@102
|
241 {
|
Chris@102
|
242 x3::traits::move_to(*val_ptr, attr);
|
Chris@102
|
243 return true;
|
Chris@102
|
244 }
|
Chris@102
|
245 return false;
|
Chris@102
|
246 }
|
Chris@102
|
247
|
Chris@102
|
248 void name(std::string const &str)
|
Chris@102
|
249 {
|
Chris@102
|
250 name_ = str;
|
Chris@102
|
251 }
|
Chris@102
|
252 std::string const &name() const
|
Chris@102
|
253 {
|
Chris@102
|
254 return name_;
|
Chris@102
|
255 }
|
Chris@102
|
256
|
Chris@102
|
257 struct adder
|
Chris@102
|
258 {
|
Chris@102
|
259 template <typename, typename = unused_type, typename = unused_type>
|
Chris@102
|
260 struct result { typedef adder const& type; };
|
Chris@102
|
261
|
Chris@102
|
262 adder(symbols& sym)
|
Chris@102
|
263 : sym(sym)
|
Chris@102
|
264 {
|
Chris@102
|
265 }
|
Chris@102
|
266
|
Chris@102
|
267 template <typename Iterator>
|
Chris@102
|
268 adder const&
|
Chris@102
|
269 operator()(Iterator first, Iterator last, T const& val) const
|
Chris@102
|
270 {
|
Chris@102
|
271 sym.lookup->add(first, last, val);
|
Chris@102
|
272 return *this;
|
Chris@102
|
273 }
|
Chris@102
|
274
|
Chris@102
|
275 template <typename Str>
|
Chris@102
|
276 adder const&
|
Chris@102
|
277 operator()(Str const& s, T const& val = T()) const
|
Chris@102
|
278 {
|
Chris@102
|
279 sym.lookup->add(traits::get_string_begin<Char>(s)
|
Chris@102
|
280 , traits::get_string_end<Char>(s), val);
|
Chris@102
|
281 return *this;
|
Chris@102
|
282 }
|
Chris@102
|
283
|
Chris@102
|
284 template <typename Str>
|
Chris@102
|
285 adder const&
|
Chris@102
|
286 operator,(Str const& s) const
|
Chris@102
|
287 {
|
Chris@102
|
288 sym.lookup->add(traits::get_string_begin<Char>(s)
|
Chris@102
|
289 , traits::get_string_end<Char>(s), T());
|
Chris@102
|
290 return *this;
|
Chris@102
|
291 }
|
Chris@102
|
292
|
Chris@102
|
293 symbols& sym;
|
Chris@102
|
294 };
|
Chris@102
|
295
|
Chris@102
|
296 struct remover
|
Chris@102
|
297 {
|
Chris@102
|
298 template <typename, typename = unused_type, typename = unused_type>
|
Chris@102
|
299 struct result { typedef remover const& type; };
|
Chris@102
|
300
|
Chris@102
|
301 remover(symbols& sym)
|
Chris@102
|
302 : sym(sym)
|
Chris@102
|
303 {
|
Chris@102
|
304 }
|
Chris@102
|
305
|
Chris@102
|
306 template <typename Iterator>
|
Chris@102
|
307 remover const&
|
Chris@102
|
308 operator()(Iterator const& first, Iterator const& last) const
|
Chris@102
|
309 {
|
Chris@102
|
310 sym.lookup->remove(first, last);
|
Chris@102
|
311 return *this;
|
Chris@102
|
312 }
|
Chris@102
|
313
|
Chris@102
|
314 template <typename Str>
|
Chris@102
|
315 remover const&
|
Chris@102
|
316 operator()(Str const& s) const
|
Chris@102
|
317 {
|
Chris@102
|
318 sym.lookup->remove(traits::get_string_begin<Char>(s)
|
Chris@102
|
319 , traits::get_string_end<Char>(s));
|
Chris@102
|
320 return *this;
|
Chris@102
|
321 }
|
Chris@102
|
322
|
Chris@102
|
323 template <typename Str>
|
Chris@102
|
324 remover const&
|
Chris@102
|
325 operator,(Str const& s) const
|
Chris@102
|
326 {
|
Chris@102
|
327 sym.lookup->remove(traits::get_string_begin<Char>(s)
|
Chris@102
|
328 , traits::get_string_end<Char>(s));
|
Chris@102
|
329 return *this;
|
Chris@102
|
330 }
|
Chris@102
|
331
|
Chris@102
|
332 symbols& sym;
|
Chris@102
|
333 };
|
Chris@102
|
334
|
Chris@102
|
335 adder add;
|
Chris@102
|
336 remover remove;
|
Chris@102
|
337 shared_ptr<Lookup> lookup;
|
Chris@102
|
338 std::string name_;
|
Chris@102
|
339 };
|
Chris@102
|
340
|
Chris@102
|
341 template <typename Char, typename T, typename Lookup, typename Filter>
|
Chris@102
|
342 struct get_info<symbols<Char, T, Lookup, Filter>>
|
Chris@102
|
343 {
|
Chris@102
|
344 typedef std::string result_type;
|
Chris@102
|
345 result_type operator()(symbols< Char, T
|
Chris@102
|
346 , Lookup, Filter
|
Chris@102
|
347 > const& symbols) const
|
Chris@102
|
348 {
|
Chris@102
|
349 return symbols.name();
|
Chris@102
|
350 }
|
Chris@102
|
351 };
|
Chris@102
|
352 }}}
|
Chris@102
|
353
|
Chris@102
|
354 #if defined(BOOST_MSVC)
|
Chris@102
|
355 # pragma warning(pop)
|
Chris@102
|
356 #endif
|
Chris@102
|
357
|
Chris@102
|
358 #endif
|