/*=============================================================================
    Copyright (c) 2001-2010 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_SYMBOLS_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/string/tst.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/detail/get_encoding.hpp>
#include <boost/spirit/home/support/modify.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/string_traits.hpp>

#include <boost/fusion/include/at.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/shared_ptr.hpp>

#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 <
        typename Char = char
      , typename T = unused_type
      , typename Lookup = tst<Char, T>
      , typename Filter = tst_pass_through>
    struct symbols
      : proto::extends<
            typename proto::terminal<
                reference<symbols<Char, T, Lookup, Filter> >
            >::type
          , symbols<Char, T, Lookup, Filter>
        >
      , primitive_parser<symbols<Char, T, Lookup, Filter> >
    {
        typedef Char char_type; // the character type
        typedef T value_type; // the value associated with each entry
        typedef symbols<Char, T, Lookup, Filter> this_type;
        typedef reference<this_type> reference_;
        typedef typename proto::terminal<reference_>::type terminal;
        typedef proto::extends<terminal, this_type> base_type;

        template <typename Context, typename Iterator>
        struct attribute
        {
            typedef value_type type;
        };

        symbols()
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {
        }

        symbols(symbols const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {
        }

        template <typename Filter_>
        symbols(symbols<Char, T, Lookup, Filter_> const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(syms.lookup)
        {
        }

        template <typename Symbols>
        symbols(Symbols const& syms)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {
            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
            while (si != boost::end(syms))
                add(*si++);
        }

        template <typename Symbols, typename Data>
        symbols(Symbols const& syms, Data const& data)
          : base_type(terminal::make(reference_(*this)))
          , add(*this)
          , remove(*this)
          , lookup(new Lookup())
        {
            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
            typename range_const_iterator<Data>::type di = boost::begin(data);
            while (si != boost::end(syms))
                add(*si++, *di++);
        }

        symbols&
        operator=(symbols const& rhs)
        {
            *lookup = *rhs.lookup;
            return *this;
        }

        template <typename Filter_>
        symbols&
        operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
        {
            *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& sym, Str const& str)
        {
            return sym.add(str);
        }

        template <typename Str>
        friend remover const&
        operator-=(symbols& sym, Str const& str)
        {
            return sym.remove(str);
        }

        // non-const version needed to suppress proto's += kicking in
        template <typename Str>
        friend adder const&
        operator+=(symbols& sym, Str& str)
        {
            return sym.add(str);
        }

        // non-const version needed to suppress proto's -= kicking in
        template <typename Str>
        friend remover const&
        operator-=(symbols& sym, Str& 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_begin<Char>(str)
                , traits::get_end<Char>(str), T());
        }

        template <typename Iterator>
        value_type* prefix_find(Iterator& first, Iterator const& last)
        {
            return lookup->find(first, last, Filter());
        }

        template <typename Iterator>
        value_type const* prefix_find(Iterator& first, Iterator const& last) const
        {
            return lookup->find(first, last, Filter());
        }

        template <typename Str>
        value_type* find(Str const& str)
        {
            return find_impl(traits::get_begin<Char>(str)
                , traits::get_end<Char>(str));
        }

        template <typename Str>
        value_type const* find(Str const& str) const
        {
            return find_impl(traits::get_begin<Char>(str)
                , traits::get_end<Char>(str));
        }

private:
        template <typename Iterator>
        value_type* find_impl(Iterator begin, Iterator end)
        {
            value_type* r = lookup->find(begin, end, Filter());
            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, Filter());
            return begin == end ? r : 0;
        }

public:
        template <typename Iterator, typename Context
          , typename Skipper, typename Attribute>
        bool parse(Iterator& first, Iterator const& last
          , Context& /*context*/, Skipper const& skipper, Attribute& attr) const
        {
            qi::skip_over(first, last, skipper);

            if (value_type* val_ptr
                = lookup->find(first, last, Filter()))
            {
                spirit::traits::assign_to(*val_ptr, attr);
                return true;
            }
            return false;
        }

        template <typename Context>
        info what(Context& /*context*/) const
        {
            return info("symbols"); // $$$ for now! give symbols a name $$$
        }

        struct adder
        {
            template <typename, typename = unused_type, typename = unused_type>
            struct result { typedef adder const& type; };

            adder(symbols& sym)
              : sym(sym)
            {
            }

            template <typename Iterator>
            adder const&
            operator()(Iterator const& first, Iterator const& 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_begin<Char>(s)
                  , traits::get_end<Char>(s), val);
                return *this;
            }

            template <typename Str>
            adder const&
            operator,(Str const& s) const
            {
                sym.lookup->add(traits::get_begin<Char>(s)
                  , traits::get_end<Char>(s), T());
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            adder& operator= (adder const&);
        };

        struct remover
        {
            template <typename, typename = unused_type, typename = unused_type>
            struct result { typedef remover const& type; };

            remover(symbols& sym)
              : sym(sym)
            {
            }

            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_begin<Char>(s)
                  , traits::get_end<Char>(s));
                return *this;
            }

            template <typename Str>
            remover const&
            operator,(Str const& s) const
            {
                sym.lookup->remove(traits::get_begin<Char>(s)
                  , traits::get_end<Char>(s));
                return *this;
            }

            symbols& sym;

        private:
            // silence MSVC warning C4512: assignment operator could not be generated
            remover& operator= (remover const&);
        };

        adder add;
        remover remove;
        shared_ptr<Lookup> lookup;
    };

    ///////////////////////////////////////////////////////////////////////////
    // Parser generators: make_xxx function (objects)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Char, typename T, typename Lookup
      , typename Filter, typename Modifiers>
    struct make_primitive<reference<symbols<Char, T, Lookup, Filter> >, Modifiers>
    {
        template <typename CharEncoding>
        struct no_case_filter
        {
            Char operator()(Char ch) const
            {
                return static_cast<Char>(CharEncoding::tolower(ch));
            }
        };

        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
        typedef reference<symbols<Char, T, Lookup, Filter> > reference_;
        typedef no_case_filter<
            typename spirit::detail::get_encoding_with_case<
                Modifiers
              , char_encoding::standard
              , no_case::value>::type>
        nc_filter;

        typedef typename mpl::if_<
            no_case
          , symbols<Char, T, Lookup, nc_filter>
          , reference_>::type
        result_type;

        result_type operator()(reference_ ref, unused_type) const
        {
            return result_type(ref.ref.get());
        }
    };
}}}

#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif

#endif
