Chris@102: /*============================================================================= Chris@102: Copyright (c) 2001-2014 Joel de Guzman Chris@102: Copyright (c) 2013 Carl Barron Chris@102: Chris@102: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: ==============================================================================*/ Chris@102: #if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM) Chris@102: #define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM Chris@102: Chris@102: #if defined(_MSC_VER) Chris@102: #pragma once Chris@102: #endif Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: Chris@102: #if defined(BOOST_MSVC) Chris@102: # pragma warning(push) Chris@102: # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning Chris@102: #endif Chris@102: Chris@102: namespace boost { namespace spirit { namespace x3 Chris@102: { Chris@102: template < Chris@102: typename Char = char Chris@102: , typename T = unused_type Chris@102: , typename Lookup = tst Chris@102: , typename Filter = tst_pass_through> Chris@102: struct symbols : parser> Chris@102: { Chris@102: typedef Char char_type; // the character type Chris@102: typedef T value_type; // the value associated with each entry Chris@102: typedef symbols this_type; Chris@102: typedef value_type attribute_type; Chris@102: Chris@102: static bool const has_attribute = Chris@102: !is_same::value; Chris@102: static bool const handles_container = Chris@102: traits::is_container::value; Chris@102: Chris@102: symbols(std::string const& name = "symbols") Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(new Lookup()) Chris@102: , name_(name) Chris@102: { Chris@102: } Chris@102: Chris@102: symbols(symbols const& syms) Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(syms.lookup) Chris@102: , name_(syms.name_) Chris@102: { Chris@102: } Chris@102: Chris@102: template Chris@102: symbols(symbols const& syms) Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(syms.lookup) Chris@102: , name_(syms.name_) Chris@102: { Chris@102: } Chris@102: Chris@102: template Chris@102: symbols(Symbols const& syms, std::string const& name = "symbols") Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(new Lookup()) Chris@102: , name_(name) Chris@102: { Chris@102: typename range_const_iterator::type si = boost::begin(syms); Chris@102: while (si != boost::end(syms)) Chris@102: add(*si++); Chris@102: } Chris@102: Chris@102: template Chris@102: symbols(Symbols const& syms, Data const& data Chris@102: , std::string const& name = "symbols") Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(new Lookup()) Chris@102: , name_(name) Chris@102: { Chris@102: typename range_const_iterator::type si = boost::begin(syms); Chris@102: typename range_const_iterator::type di = boost::begin(data); Chris@102: while (si != boost::end(syms)) Chris@102: add(*si++, *di++); Chris@102: } Chris@102: Chris@102: symbols(std::initializer_list> syms Chris@102: , std::string const & name="symbols") Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(new Lookup()) Chris@102: , name_(name) Chris@102: { Chris@102: typedef std::initializer_list> symbols_t; Chris@102: typename range_const_iterator::type si = boost::begin(syms); Chris@102: for (;si != boost::end(syms); ++si) Chris@102: add(si->first, si->second); Chris@102: } Chris@102: Chris@102: symbols(std::initializer_list syms Chris@102: , std::string const &name="symbols") Chris@102: : add(*this) Chris@102: , remove(*this) Chris@102: , lookup(new Lookup()) Chris@102: , name_(name) Chris@102: { Chris@102: typedef std::initializer_list symbols_t; Chris@102: typename range_const_iterator::type si = boost::begin(syms); Chris@102: while (si != boost::end(syms)) Chris@102: add(*si++); Chris@102: } Chris@102: Chris@102: symbols& Chris@102: operator=(symbols const& rhs) Chris@102: { Chris@102: name_ = rhs.name_; Chris@102: lookup = rhs.lookup; Chris@102: return *this; Chris@102: } Chris@102: Chris@102: template Chris@102: symbols& Chris@102: operator=(symbols const& rhs) Chris@102: { Chris@102: name_ = rhs.name_; Chris@102: lookup = rhs.lookup; Chris@102: return *this; Chris@102: } Chris@102: Chris@102: void clear() Chris@102: { Chris@102: lookup->clear(); Chris@102: } Chris@102: Chris@102: struct adder; Chris@102: struct remover; Chris@102: Chris@102: template Chris@102: adder const& Chris@102: operator=(Str const& str) Chris@102: { Chris@102: lookup->clear(); Chris@102: return add(str); Chris@102: } Chris@102: Chris@102: template Chris@102: friend adder const& Chris@102: operator+=(symbols& sym, Str const& str) Chris@102: { Chris@102: return sym.add(str); Chris@102: } Chris@102: Chris@102: template Chris@102: friend remover const& Chris@102: operator-=(symbols& sym, Str const& str) Chris@102: { Chris@102: return sym.remove(str); Chris@102: } Chris@102: Chris@102: template Chris@102: void for_each(F f) const Chris@102: { Chris@102: lookup->for_each(f); Chris@102: } Chris@102: Chris@102: template Chris@102: value_type& at(Str const& str) Chris@102: { Chris@102: return *lookup->add(traits::get_string_begin(str) Chris@102: , traits::get_string_end(str), T()); Chris@102: } Chris@102: Chris@102: template Chris@102: value_type* prefix_find(Iterator& first, Iterator const& last) Chris@102: { Chris@102: return lookup->find(first, last, Filter()); Chris@102: } Chris@102: Chris@102: template Chris@102: value_type const* prefix_find(Iterator& first, Iterator const& last) const Chris@102: { Chris@102: return lookup->find(first, last, Filter()); Chris@102: } Chris@102: Chris@102: template Chris@102: value_type* find(Str const& str) Chris@102: { Chris@102: return find_impl(traits::get_string_begin(str) Chris@102: , traits::get_string_end(str)); Chris@102: } Chris@102: Chris@102: template Chris@102: value_type const* find(Str const& str) const Chris@102: { Chris@102: return find_impl(traits::get_string_begin(str) Chris@102: , traits::get_string_end(str)); Chris@102: } Chris@102: Chris@102: private: Chris@102: template Chris@102: value_type* find_impl(Iterator begin, Iterator end) Chris@102: { Chris@102: value_type* r = lookup->find(begin, end, Filter()); Chris@102: return begin == end ? r : 0; Chris@102: } Chris@102: Chris@102: template Chris@102: value_type const* find_impl(Iterator begin, Iterator end) const Chris@102: { Chris@102: value_type const* r = lookup->find(begin, end, Filter()); Chris@102: return begin == end ? r : 0; Chris@102: } Chris@102: Chris@102: public: Chris@102: template Chris@102: bool parse(Iterator& first, Iterator const& last Chris@102: , Context const& context, unused_type, Attribute& attr) const Chris@102: { Chris@102: x3::skip_over(first, last, context); Chris@102: Chris@102: if (value_type* val_ptr Chris@102: = lookup->find(first, last, Filter())) Chris@102: { Chris@102: x3::traits::move_to(*val_ptr, attr); Chris@102: return true; Chris@102: } Chris@102: return false; Chris@102: } Chris@102: Chris@102: void name(std::string const &str) Chris@102: { Chris@102: name_ = str; Chris@102: } Chris@102: std::string const &name() const Chris@102: { Chris@102: return name_; Chris@102: } Chris@102: Chris@102: struct adder Chris@102: { Chris@102: template Chris@102: struct result { typedef adder const& type; }; Chris@102: Chris@102: adder(symbols& sym) Chris@102: : sym(sym) Chris@102: { Chris@102: } Chris@102: Chris@102: template Chris@102: adder const& Chris@102: operator()(Iterator first, Iterator last, T const& val) const Chris@102: { Chris@102: sym.lookup->add(first, last, val); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: template Chris@102: adder const& Chris@102: operator()(Str const& s, T const& val = T()) const Chris@102: { Chris@102: sym.lookup->add(traits::get_string_begin(s) Chris@102: , traits::get_string_end(s), val); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: template Chris@102: adder const& Chris@102: operator,(Str const& s) const Chris@102: { Chris@102: sym.lookup->add(traits::get_string_begin(s) Chris@102: , traits::get_string_end(s), T()); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: symbols& sym; Chris@102: }; Chris@102: Chris@102: struct remover Chris@102: { Chris@102: template Chris@102: struct result { typedef remover const& type; }; Chris@102: Chris@102: remover(symbols& sym) Chris@102: : sym(sym) Chris@102: { Chris@102: } Chris@102: Chris@102: template Chris@102: remover const& Chris@102: operator()(Iterator const& first, Iterator const& last) const Chris@102: { Chris@102: sym.lookup->remove(first, last); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: template Chris@102: remover const& Chris@102: operator()(Str const& s) const Chris@102: { Chris@102: sym.lookup->remove(traits::get_string_begin(s) Chris@102: , traits::get_string_end(s)); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: template Chris@102: remover const& Chris@102: operator,(Str const& s) const Chris@102: { Chris@102: sym.lookup->remove(traits::get_string_begin(s) Chris@102: , traits::get_string_end(s)); Chris@102: return *this; Chris@102: } Chris@102: Chris@102: symbols& sym; Chris@102: }; Chris@102: Chris@102: adder add; Chris@102: remover remove; Chris@102: shared_ptr lookup; Chris@102: std::string name_; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct get_info> Chris@102: { Chris@102: typedef std::string result_type; Chris@102: result_type operator()(symbols< Char, T Chris@102: , Lookup, Filter Chris@102: > const& symbols) const Chris@102: { Chris@102: return symbols.name(); Chris@102: } Chris@102: }; Chris@102: }}} Chris@102: Chris@102: #if defined(BOOST_MSVC) Chris@102: # pragma warning(pop) Chris@102: #endif Chris@102: Chris@102: #endif