/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman 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_SYMBOL_MARCH_11_2007_1055AM) #define BOOST_SPIRIT_SYMBOL_MARCH_11_2007_1055AM #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 qi { template struct symbols_director { template struct attribute { typedef typename result_of::subject::type::ptr_type::element_type::value_type type; }; template < typename Component , typename Iterator, typename Context , typename Skipper, typename Attribute> static bool parse( Component const& component , Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , Attribute& attr) { typedef typename result_of::subject::type::ptr_type::element_type::value_type value_type; qi::skip(first, last, skipper); if (value_type* val_ptr = fusion::at_c<0>(component.elements) .lookup->find(first, last, Filter())) { detail::assign_to(*val_ptr, attr); return true; } return false; } template static std::string what(Component const& component, Context const& ctx) { // perhaps we should show some of the contents? return "symbols"; } }; template struct symbols_lookup { typedef shared_ptr ptr_type; ptr_type lookup; }; template > struct symbols : proto::extends< typename proto::terminal >::type , symbols > { typedef Char char_type; // the character type typedef T value_type; // the value associated with each entry typedef shared_ptr ptr_type; symbols() : add(*this) , remove(*this) { proto::arg(*this).lookup = ptr_type(new Lookup()); } template symbols(Symbols const& syms) : add(*this) , remove(*this) { proto::arg(*this).lookup = ptr_type(new Lookup()); typename range_const_iterator::type si = boost::begin(syms); while (si != boost::end(syms)) add(*si++); } template symbols(Symbols const& syms, Data const& data) : add(*this) , remove(*this) { proto::arg(*this).lookup = ptr_type(new Lookup()); 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& operator=(symbols const& rhs) { proto::arg(*this) = proto::arg(rhs); return *this; } void clear() { lookup()->clear(); } struct adder; struct remover; adder const& operator=(Char const* str) { lookup()->clear(); return add(str); } adder const& operator+=(Char const* str) { return add(str); } remover const& operator-=(Char const* str) { return remove(str); } ptr_type lookup() const { return proto::arg(*this).lookup; } template void for_each(F f) const { lookup()->for_each(f); } struct adder { template struct result { typedef adder const& type; }; adder(symbols& sym) : sym(sym) { } template adder const& operator()(Iterator const& first, Iterator const& last, T const& val = T()) const { sym.lookup()->add(first, last, val); return *this; } adder const& operator()(Char const* s, T const& val = T()) const { Char const* last = s; while (*last) last++; sym.lookup()->add(s, last, val); return *this; } adder const& operator,(Char const* s) const { Char const* last = s; while (*last) last++; sym.lookup()->add(s, last, T()); return *this; } symbols& sym; }; struct remover { template struct result { typedef adder 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; } remover const& operator()(Char const* s) const { Char const* last = s; while (*last) last++; sym.lookup()->remove(s, last); return *this; } remover const& operator,(Char const* s) const { Char const* last = s; while (*last) last++; sym.lookup()->remove(s, last); return *this; } symbols& sym; }; adder add; remover remove; }; }}} namespace boost { namespace spirit { namespace traits { namespace detail { template struct no_case_filter { template Char operator()(Char ch) const { return CharSet::tolower(ch); } }; } /////////////////////////////////////////////////////////////////////////// // generator for no-case symbols /////////////////////////////////////////////////////////////////////////// template struct make_modified_component, Elements, Modifier , typename enable_if< is_member_of_modifier >::type > { typedef detail::no_case_filter filter; typedef component, Elements> type; static type call(Elements const& elements) { // we return the same lookup but this time we use a director // with a filter that converts to lower-case. return elements; } }; }}} #if defined(BOOST_MSVC) # pragma warning(pop) #endif #endif