1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2013 Carl Barron
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
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>
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>
24 #include <boost/fusion/include/at.hpp>
25 #include <boost/range.hpp>
26 #include <boost/type_traits/add_reference.hpp>
27 #include <boost/type_traits/is_same.hpp>
28 #include <boost/shared_ptr.hpp>
30 #include <initializer_list>
32 #if defined(BOOST_MSVC)
33 # pragma warning(push)
34 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
37 namespace boost { namespace spirit { namespace x3
41 , typename T = unused_type
42 , typename Lookup = tst<typename Encoding::char_type, T> >
43 struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
45 typedef typename Encoding::char_type char_type; // the character type
46 typedef Encoding encoding;
47 typedef T value_type; // the value associated with each entry
48 typedef value_type attribute_type;
50 static bool const has_attribute =
51 !is_same<unused_type, attribute_type>::value;
52 static bool const handles_container =
53 traits::is_container<attribute_type>::value;
55 symbols_parser(std::string const& name = "symbols")
58 , lookup(new Lookup())
63 symbols_parser(symbols_parser const& syms)
71 template <typename Symbols>
72 symbols_parser(Symbols const& syms, std::string const& name = "symbols")
75 , lookup(new Lookup())
78 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
79 while (si != boost::end(syms))
83 template <typename Symbols, typename Data>
84 symbols_parser(Symbols const& syms, Data const& data
85 , std::string const& name = "symbols")
88 , lookup(new Lookup())
91 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
92 typename range_const_iterator<Data>::type di = boost::begin(data);
93 while (si != boost::end(syms))
97 symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
98 , std::string const & name="symbols")
101 , lookup(new Lookup())
104 typedef std::initializer_list<std::pair<char_type const*, T>> symbols_t;
105 typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
106 for (;si != boost::end(syms); ++si)
107 add(si->first, si->second);
110 symbols_parser(std::initializer_list<char_type const*> syms
111 , std::string const &name="symbols")
114 , lookup(new Lookup())
117 typedef std::initializer_list<char_type const*> symbols_t;
118 typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
119 while (si != boost::end(syms))
124 operator=(symbols_parser const& rhs)
139 template <typename Str>
141 operator=(Str const& str)
147 template <typename Str>
149 operator+=(symbols_parser& sym, Str const& str)
154 template <typename Str>
155 friend remover const&
156 operator-=(symbols_parser& sym, Str const& str)
158 return sym.remove(str);
161 template <typename F>
162 void for_each(F f) const
167 template <typename Str>
168 value_type& at(Str const& str)
170 return *lookup->add(traits::get_string_begin<char_type>(str)
171 , traits::get_string_end<char_type>(str), T());
174 template <typename Iterator>
175 value_type* prefix_find(Iterator& first, Iterator const& last)
177 return lookup->find(first, last, case_compare<Encoding>());
180 template <typename Iterator>
181 value_type const* prefix_find(Iterator& first, Iterator const& last) const
183 return lookup->find(first, last, case_compare<Encoding>());
186 template <typename Str>
187 value_type* find(Str const& str)
189 return find_impl(traits::get_string_begin<char_type>(str)
190 , traits::get_string_end<char_type>(str));
193 template <typename Str>
194 value_type const* find(Str const& str) const
196 return find_impl(traits::get_string_begin<char_type>(str)
197 , traits::get_string_end<char_type>(str));
202 template <typename Iterator>
203 value_type* find_impl(Iterator begin, Iterator end)
205 value_type* r = lookup->find(begin, end, case_compare<Encoding>());
206 return begin == end ? r : 0;
209 template <typename Iterator>
210 value_type const* find_impl(Iterator begin, Iterator end) const
212 value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
213 return begin == end ? r : 0;
218 template <typename Iterator, typename Context, typename Attribute>
219 bool parse(Iterator& first, Iterator const& last
220 , Context const& context, unused_type, Attribute& attr) const
222 x3::skip_over(first, last, context);
224 if (value_type const* val_ptr
225 = lookup->find(first, last, get_case_compare<Encoding>(context)))
227 x3::traits::move_to(*val_ptr, attr);
233 void name(std::string const &str)
237 std::string const &name() const
244 template <typename, typename = unused_type, typename = unused_type>
245 struct result { typedef adder const& type; };
247 adder(symbols_parser& sym)
252 template <typename Iterator>
254 operator()(Iterator first, Iterator last, T const& val) const
256 sym.lookup->add(first, last, val);
260 template <typename Str>
262 operator()(Str const& s, T const& val = T()) const
264 sym.lookup->add(traits::get_string_begin<char_type>(s)
265 , traits::get_string_end<char_type>(s), val);
269 template <typename Str>
271 operator,(Str const& s) const
273 sym.lookup->add(traits::get_string_begin<char_type>(s)
274 , traits::get_string_end<char_type>(s), T());
283 template <typename, typename = unused_type, typename = unused_type>
284 struct result { typedef remover const& type; };
286 remover(symbols_parser& sym)
291 template <typename Iterator>
293 operator()(Iterator const& first, Iterator const& last) const
295 sym.lookup->remove(first, last);
299 template <typename Str>
301 operator()(Str const& s) const
303 sym.lookup->remove(traits::get_string_begin<char_type>(s)
304 , traits::get_string_end<char_type>(s));
308 template <typename Str>
310 operator,(Str const& s) const
312 sym.lookup->remove(traits::get_string_begin<char_type>(s)
313 , traits::get_string_end<char_type>(s));
322 shared_ptr<Lookup> lookup;
326 template <typename Encoding, typename T, typename Lookup>
327 struct get_info<symbols_parser<Encoding, T, Lookup>>
329 typedef std::string result_type;
330 result_type operator()(symbols_parser< Encoding, T
332 > const& symbols) const
334 return symbols.name();
340 template <typename T = unused_type>
341 using symbols = symbols_parser<char_encoding::standard, T>;
344 using standard::symbols;
346 namespace standard_wide
348 template <typename T = unused_type>
349 using symbols = symbols_parser<char_encoding::standard_wide, T>;
354 template <typename T = unused_type>
355 using symbols = symbols_parser<char_encoding::ascii, T>;
360 template <typename T = unused_type>
361 using symbols = symbols_parser<char_encoding::iso8859_1, T>;
366 #if defined(BOOST_MSVC)
367 # pragma warning(pop)