123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /*=============================================================================
- Copyright (c) 2001-2014 Joel de Guzman
- Copyright (c) 2013 Carl Barron
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ==============================================================================*/
- #if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
- #define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
- #include <boost/spirit/home/x3/core/skip_over.hpp>
- #include <boost/spirit/home/x3/core/parser.hpp>
- #include <boost/spirit/home/x3/string/tst.hpp>
- #include <boost/spirit/home/x3/support/unused.hpp>
- #include <boost/spirit/home/x3/support/traits/string_traits.hpp>
- #include <boost/spirit/home/x3/support/traits/move_to.hpp>
- #include <boost/spirit/home/x3/support/no_case.hpp>
- #include <boost/spirit/home/support/char_encoding/ascii.hpp>
- #include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
- #include <boost/spirit/home/support/char_encoding/standard.hpp>
- #include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
- #include <initializer_list>
- #include <iterator> // std::begin
- #include <memory> // std::shared_ptr
- #include <type_traits>
- #if defined(BOOST_MSVC)
- # pragma warning(push)
- # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
- #endif
- namespace boost { namespace spirit { namespace x3
- {
- template <
- typename Encoding
- , typename T = unused_type
- , typename Lookup = tst<typename Encoding::char_type, T> >
- struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
- {
- typedef typename Encoding::char_type char_type; // the character type
- typedef Encoding encoding;
- typedef T value_type; // the value associated with each entry
- typedef value_type attribute_type;
- static bool const has_attribute =
- !std::is_same<unused_type, attribute_type>::value;
- static bool const handles_container =
- traits::is_container<attribute_type>::value;
- symbols_parser(std::string const& name = "symbols")
- : add{*this}
- , remove{*this}
- , lookup(std::make_shared<Lookup>())
- , name_(name)
- {
- }
- symbols_parser(symbols_parser const& syms)
- : add{*this}
- , remove{*this}
- , lookup(syms.lookup)
- , name_(syms.name_)
- {
- }
- template <typename Symbols>
- symbols_parser(Symbols const& syms, std::string const& name = "symbols")
- : symbols_parser(name)
- {
- for (auto& sym : syms)
- add(sym);
- }
- template <typename Symbols, typename Data>
- symbols_parser(Symbols const& syms, Data const& data
- , std::string const& name = "symbols")
- : symbols_parser(name)
- {
- using std::begin;
- auto di = begin(data);
- for (auto& sym : syms)
- add(sym, *di++);
- }
- symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
- , std::string const & name="symbols")
- : symbols_parser(name)
- {
- for (auto& sym : syms)
- add(sym.first, sym.second);
- }
- symbols_parser(std::initializer_list<char_type const*> syms
- , std::string const &name="symbols")
- : symbols_parser(name)
- {
- for (auto str : syms)
- add(str);
- }
- symbols_parser&
- operator=(symbols_parser const& rhs)
- {
- name_ = rhs.name_;
- lookup = rhs.lookup;
- return *this;
- }
- void clear()
- {
- lookup->clear();
- }
- struct adder;
- struct remover;
- template <typename Str>
- adder const&
- operator=(Str const& str)
- {
- lookup->clear();
- return add(str);
- }
- template <typename Str>
- friend adder const&
- operator+=(symbols_parser& sym, Str const& str)
- {
- return sym.add(str);
- }
- template <typename Str>
- friend remover const&
- operator-=(symbols_parser& sym, Str const& str)
- {
- return sym.remove(str);
- }
- template <typename F>
- void for_each(F f) const
- {
- lookup->for_each(f);
- }
- template <typename Str>
- value_type& at(Str const& str)
- {
- return *lookup->add(traits::get_string_begin<char_type>(str)
- , traits::get_string_end<char_type>(str), T());
- }
- template <typename Iterator>
- value_type* prefix_find(Iterator& first, Iterator const& last)
- {
- return lookup->find(first, last, case_compare<Encoding>());
- }
- template <typename Iterator>
- value_type const* prefix_find(Iterator& first, Iterator const& last) const
- {
- return lookup->find(first, last, case_compare<Encoding>());
- }
- template <typename Str>
- value_type* find(Str const& str)
- {
- return find_impl(traits::get_string_begin<char_type>(str)
- , traits::get_string_end<char_type>(str));
- }
- template <typename Str>
- value_type const* find(Str const& str) const
- {
- return find_impl(traits::get_string_begin<char_type>(str)
- , traits::get_string_end<char_type>(str));
- }
- private:
- template <typename Iterator>
- value_type* find_impl(Iterator begin, Iterator end)
- {
- value_type* r = lookup->find(begin, end, case_compare<Encoding>());
- return begin == end ? r : 0;
- }
- template <typename Iterator>
- value_type const* find_impl(Iterator begin, Iterator end) const
- {
- value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
- return begin == end ? r : 0;
- }
- public:
- template <typename Iterator, typename Context, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context const& context, unused_type, Attribute& attr) const
- {
- x3::skip_over(first, last, context);
- if (value_type const* val_ptr
- = lookup->find(first, last, get_case_compare<Encoding>(context)))
- {
- x3::traits::move_to(*val_ptr, attr);
- return true;
- }
- return false;
- }
- void name(std::string const &str)
- {
- name_ = str;
- }
- std::string const &name() const
- {
- return name_;
- }
- struct adder
- {
- template <typename Iterator>
- adder const&
- operator()(Iterator first, Iterator last, T const& val) const
- {
- sym.lookup->add(first, last, val);
- return *this;
- }
- template <typename Str>
- adder const&
- operator()(Str const& s, T const& val = T()) const
- {
- sym.lookup->add(traits::get_string_begin<char_type>(s)
- , traits::get_string_end<char_type>(s), val);
- return *this;
- }
- template <typename Str>
- adder const&
- operator,(Str const& s) const
- {
- sym.lookup->add(traits::get_string_begin<char_type>(s)
- , traits::get_string_end<char_type>(s), T());
- return *this;
- }
- symbols_parser& sym;
- };
- struct remover
- {
- template <typename Iterator>
- remover const&
- operator()(Iterator const& first, Iterator const& last) const
- {
- sym.lookup->remove(first, last);
- return *this;
- }
- template <typename Str>
- remover const&
- operator()(Str const& s) const
- {
- sym.lookup->remove(traits::get_string_begin<char_type>(s)
- , traits::get_string_end<char_type>(s));
- return *this;
- }
- template <typename Str>
- remover const&
- operator,(Str const& s) const
- {
- sym.lookup->remove(traits::get_string_begin<char_type>(s)
- , traits::get_string_end<char_type>(s));
- return *this;
- }
- symbols_parser& sym;
- };
- adder add;
- remover remove;
- std::shared_ptr<Lookup> lookup;
- std::string name_;
- };
- template <typename Encoding, typename T, typename Lookup>
- struct get_info<symbols_parser<Encoding, T, Lookup>>
- {
- typedef std::string result_type;
- result_type operator()(symbols_parser< Encoding, T
- , Lookup
- > const& symbols) const
- {
- return symbols.name();
- }
- };
- namespace standard
- {
- template <typename T = unused_type>
- using symbols = symbols_parser<char_encoding::standard, T>;
- }
- using standard::symbols;
- #ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
- namespace standard_wide
- {
- template <typename T = unused_type>
- using symbols = symbols_parser<char_encoding::standard_wide, T>;
- }
- #endif
- namespace ascii
- {
- template <typename T = unused_type>
- using symbols = symbols_parser<char_encoding::ascii, T>;
- }
- namespace iso8859_1
- {
- template <typename T = unused_type>
- using symbols = symbols_parser<char_encoding::iso8859_1, T>;
- }
- }}}
- #if defined(BOOST_MSVC)
- # pragma warning(pop)
- #endif
- #endif
|