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 <initializer_list>
25 #include <iterator> // std::begin
26 #include <memory> // std::shared_ptr
27 #include <type_traits>
29 #if defined(BOOST_MSVC)
30 # pragma warning(push)
31 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
34 namespace boost { namespace spirit { namespace x3
38 , typename T = unused_type
39 , typename Lookup = tst<typename Encoding::char_type, T> >
40 struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
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;
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;
52 symbols_parser(std::string const& name = "symbols")
55 , lookup(std::make_shared<Lookup>())
60 symbols_parser(symbols_parser const& syms)
68 template <typename Symbols>
69 symbols_parser(Symbols const& syms, std::string const& name = "symbols")
70 : symbols_parser(name)
72 for (auto& sym : syms)
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)
82 auto di = begin(data);
83 for (auto& sym : syms)
87 symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
88 , std::string const & name="symbols")
89 : symbols_parser(name)
91 for (auto& sym : syms)
92 add(sym.first, sym.second);
95 symbols_parser(std::initializer_list<char_type const*> syms
96 , std::string const &name="symbols")
97 : symbols_parser(name)
104 operator=(symbols_parser const& rhs)
119 template <typename Str>
121 operator=(Str const& str)
127 template <typename Str>
129 operator+=(symbols_parser& sym, Str const& str)
134 template <typename Str>
135 friend remover const&
136 operator-=(symbols_parser& sym, Str const& str)
138 return sym.remove(str);
141 template <typename F>
142 void for_each(F f) const
147 template <typename Str>
148 value_type& at(Str const& str)
150 return *lookup->add(traits::get_string_begin<char_type>(str)
151 , traits::get_string_end<char_type>(str), T());
154 template <typename Iterator>
155 value_type* prefix_find(Iterator& first, Iterator const& last)
157 return lookup->find(first, last, case_compare<Encoding>());
160 template <typename Iterator>
161 value_type const* prefix_find(Iterator& first, Iterator const& last) const
163 return lookup->find(first, last, case_compare<Encoding>());
166 template <typename Str>
167 value_type* find(Str const& str)
169 return find_impl(traits::get_string_begin<char_type>(str)
170 , traits::get_string_end<char_type>(str));
173 template <typename Str>
174 value_type const* find(Str const& str) const
176 return find_impl(traits::get_string_begin<char_type>(str)
177 , traits::get_string_end<char_type>(str));
182 template <typename Iterator>
183 value_type* find_impl(Iterator begin, Iterator end)
185 value_type* r = lookup->find(begin, end, case_compare<Encoding>());
186 return begin == end ? r : 0;
189 template <typename Iterator>
190 value_type const* find_impl(Iterator begin, Iterator end) const
192 value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
193 return begin == end ? r : 0;
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
202 x3::skip_over(first, last, context);
204 if (value_type const* val_ptr
205 = lookup->find(first, last, get_case_compare<Encoding>(context)))
207 x3::traits::move_to(*val_ptr, attr);
213 void name(std::string const &str)
217 std::string const &name() const
224 template <typename Iterator>
226 operator()(Iterator first, Iterator last, T const& val) const
228 sym.lookup->add(first, last, val);
232 template <typename Str>
234 operator()(Str const& s, T const& val = T()) const
236 sym.lookup->add(traits::get_string_begin<char_type>(s)
237 , traits::get_string_end<char_type>(s), val);
241 template <typename Str>
243 operator,(Str const& s) const
245 sym.lookup->add(traits::get_string_begin<char_type>(s)
246 , traits::get_string_end<char_type>(s), T());
255 template <typename Iterator>
257 operator()(Iterator const& first, Iterator const& last) const
259 sym.lookup->remove(first, last);
263 template <typename Str>
265 operator()(Str const& s) const
267 sym.lookup->remove(traits::get_string_begin<char_type>(s)
268 , traits::get_string_end<char_type>(s));
272 template <typename Str>
274 operator,(Str const& s) const
276 sym.lookup->remove(traits::get_string_begin<char_type>(s)
277 , traits::get_string_end<char_type>(s));
286 std::shared_ptr<Lookup> lookup;
290 template <typename Encoding, typename T, typename Lookup>
291 struct get_info<symbols_parser<Encoding, T, Lookup>>
293 typedef std::string result_type;
294 result_type operator()(symbols_parser< Encoding, T
296 > const& symbols) const
298 return symbols.name();
304 template <typename T = unused_type>
305 using symbols = symbols_parser<char_encoding::standard, T>;
308 using standard::symbols;
310 #ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
311 namespace standard_wide
313 template <typename T = unused_type>
314 using symbols = symbols_parser<char_encoding::standard_wide, T>;
320 template <typename T = unused_type>
321 using symbols = symbols_parser<char_encoding::ascii, T>;
326 template <typename T = unused_type>
327 using symbols = symbols_parser<char_encoding::iso8859_1, T>;
332 #if defined(BOOST_MSVC)
333 # pragma warning(pop)