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