/*============================================================================= 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 #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include #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 Char = char , typename T = unused_type , typename Lookup = tst , typename Filter = tst_pass_through> struct symbols : parser> { typedef Char char_type; // the character type typedef T value_type; // the value associated with each entry typedef symbols this_type; typedef value_type attribute_type; static bool const has_attribute = !is_same::value; static bool const handles_container = traits::is_container::value; symbols(std::string const& name = "symbols") : add(*this) , remove(*this) , lookup(new Lookup()) , name_(name) { } symbols(symbols const& syms) : add(*this) , remove(*this) , lookup(syms.lookup) , name_(syms.name_) { } template symbols(symbols const& syms) : add(*this) , remove(*this) , lookup(syms.lookup) , name_(syms.name_) { } template symbols(Symbols const& syms, std::string const& name = "symbols") : add(*this) , remove(*this) , lookup(new Lookup()) , name_(name) { typename range_const_iterator::type si = boost::begin(syms); while (si != boost::end(syms)) add(*si++); } template symbols(Symbols const& syms, Data const& data , std::string const& name = "symbols") : add(*this) , remove(*this) , lookup(new Lookup()) , name_(name) { typename range_const_iterator::type si = boost::begin(syms); typename range_const_iterator::type di = boost::begin(data); while (si != boost::end(syms)) add(*si++, *di++); } symbols(std::initializer_list> syms , std::string const & name="symbols") : add(*this) , remove(*this) , lookup(new Lookup()) , name_(name) { typedef std::initializer_list> symbols_t; typename range_const_iterator::type si = boost::begin(syms); for (;si != boost::end(syms); ++si) add(si->first, si->second); } symbols(std::initializer_list syms , std::string const &name="symbols") : add(*this) , remove(*this) , lookup(new Lookup()) , name_(name) { typedef std::initializer_list symbols_t; typename range_const_iterator::type si = boost::begin(syms); while (si != boost::end(syms)) add(*si++); } symbols& operator=(symbols const& rhs) { name_ = rhs.name_; lookup = rhs.lookup; return *this; } template symbols& operator=(symbols const& rhs) { name_ = rhs.name_; lookup = rhs.lookup; return *this; } void clear() { lookup->clear(); } struct adder; struct remover; template adder const& operator=(Str const& str) { lookup->clear(); return add(str); } template friend adder const& operator+=(symbols& sym, Str const& str) { return sym.add(str); } template friend remover const& operator-=(symbols& sym, Str const& str) { return sym.remove(str); } template void for_each(F f) const { lookup->for_each(f); } template value_type& at(Str const& str) { return *lookup->add(traits::get_string_begin(str) , traits::get_string_end(str), T()); } template value_type* prefix_find(Iterator& first, Iterator const& last) { return lookup->find(first, last, Filter()); } template value_type const* prefix_find(Iterator& first, Iterator const& last) const { return lookup->find(first, last, Filter()); } template value_type* find(Str const& str) { return find_impl(traits::get_string_begin(str) , traits::get_string_end(str)); } template value_type const* find(Str const& str) const { return find_impl(traits::get_string_begin(str) , traits::get_string_end(str)); } private: template value_type* find_impl(Iterator begin, Iterator end) { value_type* r = lookup->find(begin, end, Filter()); return begin == end ? r : 0; } template value_type const* find_impl(Iterator begin, Iterator end) const { value_type const* r = lookup->find(begin, end, Filter()); return begin == end ? r : 0; } public: template bool parse(Iterator& first, Iterator const& last , Context const& context, unused_type, Attribute& attr) const { x3::skip_over(first, last, context); if (value_type* val_ptr = lookup->find(first, last, Filter())) { 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 struct result { typedef adder const& type; }; adder(symbols& sym) : sym(sym) { } template adder const& operator()(Iterator first, Iterator last, T const& val) const { sym.lookup->add(first, last, val); return *this; } template adder const& operator()(Str const& s, T const& val = T()) const { sym.lookup->add(traits::get_string_begin(s) , traits::get_string_end(s), val); return *this; } template adder const& operator,(Str const& s) const { sym.lookup->add(traits::get_string_begin(s) , traits::get_string_end(s), T()); return *this; } symbols& sym; }; struct remover { template struct result { typedef remover const& type; }; remover(symbols& sym) : sym(sym) { } template remover const& operator()(Iterator const& first, Iterator const& last) const { sym.lookup->remove(first, last); return *this; } template remover const& operator()(Str const& s) const { sym.lookup->remove(traits::get_string_begin(s) , traits::get_string_end(s)); return *this; } template remover const& operator,(Str const& s) const { sym.lookup->remove(traits::get_string_begin(s) , traits::get_string_end(s)); return *this; } symbols& sym; }; adder add; remover remove; shared_ptr lookup; std::string name_; }; template struct get_info> { typedef std::string result_type; result_type operator()(symbols< Char, T , Lookup, Filter > const& symbols) const { return symbols.name(); } }; }}} #if defined(BOOST_MSVC) # pragma warning(pop) #endif #endif