EVOLUTION-MANAGER
Edit File: symbols.hpp
/*============================================================================= 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