///////////////////////////////////////////////////////////////////////////////
// as_set.hpp
//
//  Copyright 2008 Eric Niebler. 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)

#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007
#define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_SET_HPP_EAN_04_05_2007

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/mpl/assert.hpp>
#include <boost/proto/core.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/static/static.hpp>
#include <boost/xpressive/detail/utility/chset/chset.hpp>
#include <boost/xpressive/detail/utility/traits_utils.hpp>

namespace boost { namespace xpressive { namespace grammar_detail
{

    ///////////////////////////////////////////////////////////////////////////
    // CharLiteral
    template<typename Char>
    struct CharLiteral
      : or_<
            terminal<char>
          , terminal<Char>
        >
    {};

    template<>
    struct CharLiteral<char>
      : terminal<char>
    {};

    ///////////////////////////////////////////////////////////////////////////
    // ListSet
    //  matches expressions like (set= 'a','b','c')
    //  calculates the size of the set
    template<typename Char>
    struct ListSet
      : or_<
            when<
                comma<ListSet<Char>, CharLiteral<Char> >
              , make<mpl::next<call<ListSet<Char>(_left)> > > // TODO make a custom transform for this...
            >
          , when<
                assign<detail::set_initializer_type, CharLiteral<Char> >
              , make<mpl::int_<1> >
            >
        >
    {};

    template<typename Char, typename Traits>
    void fill_list_set(Char *&, detail::set_initializer_type, Traits const &)
    {}

    template<typename Char, typename Expr, typename Traits>
    void fill_list_set(Char *&buffer, Expr const &expr, Traits const &traits)
    {
        fill_list_set(buffer, proto::left(expr), traits);
        *buffer++ = traits.translate(detail::char_cast<Char>(proto::value(proto::right(expr)), traits));
    }

    ///////////////////////////////////////////////////////////////////////////////
    // as_list_set_matcher
    template<typename Char, typename Callable = proto::callable>
    struct as_list_set_matcher : proto::transform<as_list_set_matcher<Char, Callable> >
    {
        template<typename Expr, typename State, typename Data>
        struct impl : proto::transform_impl<Expr, State, Data>
        {
            typedef typename impl::data data_type;
            typedef
                detail::set_matcher<
                    typename data_type::traits_type
                  , typename ListSet<Char>::template impl<Expr, State, Data>::result_type
                >
            result_type;

            result_type operator ()(
                typename impl::expr_param expr
              , typename impl::state_param
              , typename impl::data_param data
            ) const
            {
                result_type set;
                typedef typename impl::data data_type;
                typename data_type::char_type *buffer = set.set_;
                fill_list_set(buffer, expr, data.traits());
                return set;
            }
        };
    };

    ///////////////////////////////////////////////////////////////////////////////
    // merge_charset
    //
    template<typename Grammar, typename CharSet, typename Data>
    struct merge_charset
    {
        typedef typename Data::traits_type traits_type;
        typedef typename CharSet::char_type char_type;
        typedef typename CharSet::icase_type icase_type;

        merge_charset(CharSet &charset, Data &data)
          : charset_(charset)
          , visitor_(data)
        {}

        template<typename Expr>
        void operator ()(Expr const &expr) const
        {
            this->call_(expr, typename Expr::proto_tag());
        }

    private:
        merge_charset &operator =(merge_charset const &);

        template<typename Expr, typename Tag>
        void call_(Expr const &expr, Tag) const
        {
            this->set_(
                typename Grammar::template impl<Expr const &, detail::end_xpression, Data &>()(
                    expr
                  , detail::end_xpression()
                  , this->visitor_
                )
            );
        }

        template<typename Expr>
        void call_(Expr const &expr, tag::bitwise_or) const
        {
            (*this)(proto::left(expr));
            (*this)(proto::right(expr));
        }

        template<typename Not>
        void set_(detail::literal_matcher<traits_type, icase_type, Not> const &ch) const
        {
            // BUGBUG fixme!
            BOOST_MPL_ASSERT_NOT((Not));
            set_char(this->charset_.charset_, ch.ch_, this->visitor_.traits(), icase_type());
        }

        void set_(detail::range_matcher<traits_type, icase_type> const &rg) const
        {
            // BUGBUG fixme!
            BOOST_ASSERT(!rg.not_);
            set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->visitor_.traits(), icase_type());
        }

        template<typename Size>
        void set_(detail::set_matcher<traits_type, Size> const &set_) const
        {
            // BUGBUG fixme!
            BOOST_ASSERT(!set_.not_);
            for(int i = 0; i < Size::value; ++i)
            {
                set_char(this->charset_.charset_, set_.set_[i], this->visitor_.traits(), icase_type());
            }
        }

        void set_(detail::posix_charset_matcher<traits_type> const &posix) const
        {
            set_class(this->charset_.charset_, posix.mask_, posix.not_, this->visitor_.traits());
        }

        CharSet &charset_;
        Data &visitor_;
    };

    ///////////////////////////////////////////////////////////////////////////////
    //
    template<typename Grammar, typename Callable = proto::callable>
    struct as_set_matcher : proto::transform<as_set_matcher<Grammar, Callable> >
    {
        template<typename Expr, typename State, typename Data>
        struct impl : proto::transform_impl<Expr, State, Data>
        {
            typedef typename impl::data data_type;
            typedef typename data_type::char_type char_type;

            // if sizeof(char_type)==1, merge everything into a basic_chset
            // BUGBUG this is not optimal.
            typedef
                typename mpl::if_c<
                    detail::is_narrow_char<char_type>::value
                  , detail::basic_chset<char_type>
                  , detail::compound_charset<typename data_type::traits_type>
                >::type
            charset_type;

            typedef
                detail::charset_matcher<
                    typename data_type::traits_type
                  , typename data_type::icase_type
                  , charset_type
                >
            result_type;

            result_type operator ()(
                typename impl::expr_param expr
              , typename impl::state_param
              , typename impl::data_param data
            ) const
            {
                result_type matcher;
                merge_charset<Grammar, result_type, typename impl::data> merge(matcher, data);
                merge(expr); // Walks the tree and fills in the charset
                return matcher;
            }
        };
    };

}}}

#endif
