Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM) Chris@16: #define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning(push) Chris@16: # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace spirit { namespace qi Chris@16: { Chris@16: template < Chris@16: typename Char = char Chris@16: , typename T = unused_type Chris@16: , typename Lookup = tst Chris@16: , typename Filter = tst_pass_through> Chris@16: struct symbols Chris@16: : proto::extends< Chris@16: typename proto::terminal< Chris@16: reference > Chris@16: >::type Chris@16: , symbols Chris@16: > Chris@16: , primitive_parser > Chris@16: { Chris@16: typedef Char char_type; // the character type Chris@16: typedef T value_type; // the value associated with each entry Chris@16: typedef symbols this_type; Chris@16: typedef reference reference_; Chris@16: typedef typename proto::terminal::type terminal; Chris@16: typedef proto::extends base_type; Chris@16: Chris@16: template Chris@16: struct attribute Chris@16: { Chris@16: typedef value_type type; Chris@16: }; Chris@16: Chris@16: symbols(std::string const& name = "symbols") Chris@16: : base_type(terminal::make(reference_(*this))) Chris@16: , add(*this) Chris@16: , remove(*this) Chris@16: , lookup(new Lookup()) Chris@16: , name_(name) Chris@16: { Chris@16: } Chris@16: Chris@16: symbols(symbols const& syms) Chris@16: : base_type(terminal::make(reference_(*this))) Chris@16: , add(*this) Chris@16: , remove(*this) Chris@16: , lookup(syms.lookup) Chris@16: , name_(syms.name_) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: symbols(symbols const& syms) Chris@16: : base_type(terminal::make(reference_(*this))) Chris@16: , add(*this) Chris@16: , remove(*this) Chris@16: , lookup(syms.lookup) Chris@16: , name_(syms.name_) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: symbols(Symbols const& syms, std::string const& name = "symbols") Chris@16: : base_type(terminal::make(reference_(*this))) Chris@16: , add(*this) Chris@16: , remove(*this) Chris@16: , lookup(new Lookup()) Chris@16: , name_(name) Chris@16: { Chris@16: typename range_const_iterator::type si = boost::begin(syms); Chris@16: while (si != boost::end(syms)) Chris@16: add(*si++); Chris@16: } Chris@16: Chris@16: template Chris@16: symbols(Symbols const& syms, Data const& data Chris@16: , std::string const& name = "symbols") Chris@16: : base_type(terminal::make(reference_(*this))) Chris@16: , add(*this) Chris@16: , remove(*this) Chris@16: , lookup(new Lookup()) Chris@16: , name_(name) Chris@16: { Chris@16: typename range_const_iterator::type si = boost::begin(syms); Chris@16: typename range_const_iterator::type di = boost::begin(data); Chris@16: while (si != boost::end(syms)) Chris@16: add(*si++, *di++); Chris@16: } Chris@16: Chris@16: symbols& Chris@16: operator=(symbols const& rhs) Chris@16: { Chris@16: name_ = rhs.name_; Chris@16: *lookup = *rhs.lookup; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: symbols& Chris@16: operator=(symbols const& rhs) Chris@16: { Chris@16: name_ = rhs.name_; Chris@16: *lookup = *rhs.lookup; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: void clear() Chris@16: { Chris@16: lookup->clear(); Chris@16: } Chris@16: Chris@16: struct adder; Chris@16: struct remover; Chris@16: Chris@16: template Chris@16: adder const& Chris@16: operator=(Str const& str) Chris@16: { Chris@16: lookup->clear(); Chris@16: return add(str); Chris@16: } Chris@16: Chris@16: template Chris@16: friend adder const& Chris@16: operator+=(symbols& sym, Str const& str) Chris@16: { Chris@16: return sym.add(str); Chris@16: } Chris@16: Chris@16: template Chris@16: friend remover const& Chris@16: operator-=(symbols& sym, Str const& str) Chris@16: { Chris@16: return sym.remove(str); Chris@16: } Chris@16: Chris@16: #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: // non-const version needed to suppress proto's += kicking in Chris@16: template Chris@16: friend adder const& Chris@16: operator+=(symbols& sym, Str& str) Chris@16: { Chris@16: return sym.add(str); Chris@16: } Chris@16: Chris@16: // non-const version needed to suppress proto's -= kicking in Chris@16: template Chris@16: friend remover const& Chris@16: operator-=(symbols& sym, Str& str) Chris@16: { Chris@16: return sym.remove(str); Chris@16: } Chris@16: #else Chris@16: // for rvalue references Chris@16: template Chris@16: friend adder const& Chris@16: operator+=(symbols& sym, Str&& str) Chris@16: { Chris@16: return sym.add(str); Chris@16: } Chris@16: Chris@16: // for rvalue references Chris@16: template Chris@16: friend remover const& Chris@16: operator-=(symbols& sym, Str&& str) Chris@16: { Chris@16: return sym.remove(str); Chris@16: } Chris@16: #endif Chris@16: template Chris@16: void for_each(F f) const Chris@16: { Chris@16: lookup->for_each(f); Chris@16: } Chris@16: Chris@16: template Chris@16: value_type& at(Str const& str) Chris@16: { Chris@16: return *lookup->add(traits::get_begin(str) Chris@16: , traits::get_end(str), T()); Chris@16: } Chris@16: Chris@16: template Chris@16: value_type* prefix_find(Iterator& first, Iterator const& last) Chris@16: { Chris@16: return lookup->find(first, last, Filter()); Chris@16: } Chris@16: Chris@16: template Chris@16: value_type const* prefix_find(Iterator& first, Iterator const& last) const Chris@16: { Chris@16: return lookup->find(first, last, Filter()); Chris@16: } Chris@16: Chris@16: template Chris@16: value_type* find(Str const& str) Chris@16: { Chris@16: return find_impl(traits::get_begin(str) Chris@16: , traits::get_end(str)); Chris@16: } Chris@16: Chris@16: template Chris@16: value_type const* find(Str const& str) const Chris@16: { Chris@16: return find_impl(traits::get_begin(str) Chris@16: , traits::get_end(str)); Chris@16: } Chris@16: Chris@16: private: Chris@16: template Chris@16: value_type* find_impl(Iterator begin, Iterator end) Chris@16: { Chris@16: value_type* r = lookup->find(begin, end, Filter()); Chris@16: return begin == end ? r : 0; Chris@16: } Chris@16: Chris@16: template Chris@16: value_type const* find_impl(Iterator begin, Iterator end) const Chris@16: { Chris@16: value_type const* r = lookup->find(begin, end, Filter()); Chris@16: return begin == end ? r : 0; Chris@16: } Chris@16: Chris@16: public: Chris@16: template Chris@16: bool parse(Iterator& first, Iterator const& last Chris@16: , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const Chris@16: { Chris@16: qi::skip_over(first, last, skipper); Chris@16: Chris@16: if (value_type* val_ptr Chris@16: = lookup->find(first, last, Filter())) Chris@16: { Chris@16: spirit::traits::assign_to(*val_ptr, attr_); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: template Chris@16: info what(Context& /*context*/) const Chris@16: { Chris@16: return info(name_); Chris@16: } Chris@16: Chris@16: void name(std::string const &str) Chris@16: { Chris@16: name_ = str; Chris@16: } Chris@16: std::string const &name() const Chris@16: { Chris@16: return name_; Chris@16: } Chris@16: Chris@16: struct adder Chris@16: { Chris@16: template Chris@16: struct result { typedef adder const& type; }; Chris@16: Chris@16: adder(symbols& sym_) Chris@16: : sym(sym_) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: adder const& Chris@16: operator()(Iterator const& first, Iterator const& last, T const& val) const Chris@16: { Chris@16: sym.lookup->add(first, last, val); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: adder const& Chris@16: operator()(Str const& s, T const& val = T()) const Chris@16: { Chris@16: sym.lookup->add(traits::get_begin(s) Chris@16: , traits::get_end(s), val); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: adder const& Chris@16: operator,(Str const& s) const Chris@16: { Chris@16: sym.lookup->add(traits::get_begin(s) Chris@16: , traits::get_end(s), T()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: symbols& sym; Chris@16: Chris@16: private: Chris@16: // silence MSVC warning C4512: assignment operator could not be generated Chris@16: adder& operator= (adder const&); Chris@16: }; Chris@16: Chris@16: struct remover Chris@16: { Chris@16: template Chris@16: struct result { typedef remover const& type; }; Chris@16: Chris@16: remover(symbols& sym_) Chris@16: : sym(sym_) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: remover const& Chris@16: operator()(Iterator const& first, Iterator const& last) const Chris@16: { Chris@16: sym.lookup->remove(first, last); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: remover const& Chris@16: operator()(Str const& s) const Chris@16: { Chris@16: sym.lookup->remove(traits::get_begin(s) Chris@16: , traits::get_end(s)); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: remover const& Chris@16: operator,(Str const& s) const Chris@16: { Chris@16: sym.lookup->remove(traits::get_begin(s) Chris@16: , traits::get_end(s)); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: symbols& sym; Chris@16: Chris@16: private: Chris@16: // silence MSVC warning C4512: assignment operator could not be generated Chris@16: remover& operator= (remover const&); Chris@16: }; Chris@16: Chris@16: adder add; Chris@16: remover remove; Chris@16: shared_ptr lookup; Chris@16: std::string name_; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Parser generators: make_xxx function (objects) Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct make_primitive >, Modifiers> Chris@16: { Chris@16: template Chris@16: struct no_case_filter Chris@16: { Chris@16: Char operator()(Char ch) const Chris@16: { Chris@16: return static_cast(CharEncoding::tolower(ch)); Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef has_modifier > no_case; Chris@16: typedef reference > reference_; Chris@16: typedef no_case_filter< Chris@16: typename spirit::detail::get_encoding_with_case< Chris@16: Modifiers Chris@16: , char_encoding::standard Chris@16: , no_case::value>::type> Chris@16: nc_filter; Chris@16: Chris@16: typedef typename mpl::if_< Chris@16: no_case Chris@16: , symbols Chris@16: , reference_>::type Chris@16: result_type; Chris@16: Chris@16: result_type operator()(reference_ ref, unused_type) const Chris@16: { Chris@16: return result_type(ref.ref.get()); Chris@16: } Chris@16: }; Chris@16: }}} Chris@16: Chris@16: namespace boost { namespace spirit { namespace traits Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct handles_container, Attr, Context, Iterator> Chris@16: : traits::is_container {}; Chris@16: }}} Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif