/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2001 Daniel Nuffer
    http://spirit.sourceforge.net/

  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_DIRECTIVES_HPP)
#define BOOST_SPIRIT_DIRECTIVES_HPP

///////////////////////////////////////////////////////////////////////////////
#include <algorithm>

#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/scanner/skipper.hpp> 
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp>

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  contiguous class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct lexeme_parser_gen;

    template <typename ParserT>
    struct contiguous
    :   public unary<ParserT, parser<contiguous<ParserT> > >
    {
        typedef contiguous<ParserT>             self_t;
        typedef unary_parser_category           parser_category_t;
        typedef lexeme_parser_gen               parser_generator_t;
        typedef unary<ParserT, parser<self_t> > base_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename parser_result<ParserT, ScannerT>::type type;
        };

        contiguous(ParserT const& p)
        : base_t(p) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            return impl::contiguous_parser_parse<result_t>
                (this->subject(), scan, scan);
        }
    };

    struct lexeme_parser_gen
    {
        template <typename ParserT>
        struct result {

            typedef contiguous<ParserT> type;
        };

        template <typename ParserT>
        static contiguous<ParserT>
        generate(parser<ParserT> const& subject)
        {
            return contiguous<ParserT>(subject.derived());
        }

        template <typename ParserT>
        contiguous<ParserT>
        operator[](parser<ParserT> const& subject) const
        {
            return contiguous<ParserT>(subject.derived());
        }
    };

    //////////////////////////////////
    const lexeme_parser_gen lexeme_d = lexeme_parser_gen();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  lexeme_scanner
    //
    //      Given a Scanner, return the correct scanner type that
    //      the lexeme_d uses. Scanner is assumed to be a phrase
    //      level scanner (see skipper.hpp)
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ScannerT>
    struct lexeme_scanner
    {
        typedef scanner_policies<
            no_skipper_iteration_policy<
                typename ScannerT::iteration_policy_t>,
            typename ScannerT::match_policy_t,
            typename ScannerT::action_policy_t
        > policies_t;

        typedef typename
            rebind_scanner_policies<ScannerT, policies_t>::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  inhibit_case_iteration_policy class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BaseT>
    struct inhibit_case_iteration_policy : public BaseT
    {
        typedef BaseT base_t;

        inhibit_case_iteration_policy()
        : BaseT() {}

        template <typename PolicyT>
        inhibit_case_iteration_policy(PolicyT const& other)
        : BaseT(other) {}

        template <typename CharT>
        CharT filter(CharT ch) const
        { return impl::tolower_(ch); }
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  inhibit_case class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct inhibit_case_parser_gen;

    template <typename ParserT>
    struct inhibit_case
    :   public unary<ParserT, parser<inhibit_case<ParserT> > >
    {
        typedef inhibit_case<ParserT>           self_t;
        typedef unary_parser_category           parser_category_t;
        typedef inhibit_case_parser_gen         parser_generator_t;
        typedef unary<ParserT, parser<self_t> > base_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename parser_result<ParserT, ScannerT>::type type;
        };

        inhibit_case(ParserT const& p)
        : base_t(p) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            return impl::inhibit_case_parser_parse<result_t>
                (this->subject(), scan, scan);
        }
    };

    template <int N>
    struct inhibit_case_parser_gen_base
    {
        //  This hack is needed to make borland happy.
        //  If these member operators were defined in the
        //  inhibit_case_parser_gen class, or if this class
        //  is non-templated, borland ICEs.

        static inhibit_case<strlit<char const*> >
        generate(char const* str)
        { return inhibit_case<strlit<char const*> >(str); }

        static inhibit_case<strlit<wchar_t const*> >
        generate(wchar_t const* str)
        { return inhibit_case<strlit<wchar_t const*> >(str); }

        static inhibit_case<chlit<char> >
        generate(char ch)
        { return inhibit_case<chlit<char> >(ch); }

        static inhibit_case<chlit<wchar_t> >
        generate(wchar_t ch)
        { return inhibit_case<chlit<wchar_t> >(ch); }

        template <typename ParserT>
        static inhibit_case<ParserT>
        generate(parser<ParserT> const& subject)
        { return inhibit_case<ParserT>(subject.derived()); }

        inhibit_case<strlit<char const*> >
        operator[](char const* str) const
        { return inhibit_case<strlit<char const*> >(str); }

        inhibit_case<strlit<wchar_t const*> >
        operator[](wchar_t const* str) const
        { return inhibit_case<strlit<wchar_t const*> >(str); }

        inhibit_case<chlit<char> >
        operator[](char ch) const
        { return inhibit_case<chlit<char> >(ch); }

        inhibit_case<chlit<wchar_t> >
        operator[](wchar_t ch) const
        { return inhibit_case<chlit<wchar_t> >(ch); }

        template <typename ParserT>
        inhibit_case<ParserT>
        operator[](parser<ParserT> const& subject) const
        { return inhibit_case<ParserT>(subject.derived()); }
    };

    //////////////////////////////////
    struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0>
    {
        inhibit_case_parser_gen() {}
    };

    //////////////////////////////////
    //  Depracated
    const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen();

    //  Preferred syntax
    const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  as_lower_scanner
    //
    //      Given a Scanner, return the correct scanner type that
    //      the as_lower_d uses. Scanner is assumed to be a scanner
    //      with an inhibit_case_iteration_policy.
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename ScannerT>
    struct as_lower_scanner
    {
        typedef scanner_policies<
            inhibit_case_iteration_policy<
                typename ScannerT::iteration_policy_t>,
            typename ScannerT::match_policy_t,
            typename ScannerT::action_policy_t
        > policies_t;

        typedef typename
            rebind_scanner_policies<ScannerT, policies_t>::type type;
    };

    ///////////////////////////////////////////////////////////////////////////
    //
    //  longest_alternative class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct longest_parser_gen;

    template <typename A, typename B>
    struct longest_alternative
    :   public binary<A, B, parser<longest_alternative<A, B> > >
    {
        typedef longest_alternative<A, B>       self_t;
        typedef binary_parser_category          parser_category_t;
        typedef longest_parser_gen              parser_generator_t;
        typedef binary<A, B, parser<self_t> >   base_t;

        longest_alternative(A const& a, B const& b)
        : base_t(a, b) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            typename ScannerT::iterator_t save = scan.first;
            result_t l = this->left().parse(scan);
            std::swap(scan.first, save);
            result_t r = this->right().parse(scan);

            if (l || r)
            {
                if (l.length() > r.length())
                {
                    scan.first = save;
                    return l;
                }
                return r;
            }

            return scan.no_match();
        }
    };

    struct longest_parser_gen
    {
        template <typename A, typename B>
        struct result {

            typedef typename
                impl::to_longest_alternative<alternative<A, B> >::result_t
            type;
        };

        template <typename A, typename B>
        static typename
        impl::to_longest_alternative<alternative<A, B> >::result_t
        generate(alternative<A, B> const& alt)
        {
            return impl::to_longest_alternative<alternative<A, B> >::
                convert(alt);
        }

        //'generate' for binary composite
        template <typename A, typename B>
        static
        longest_alternative<A, B>
        generate(A const &left, B const &right)
        {
            return longest_alternative<A, B>(left, right);
        }

        template <typename A, typename B>
        typename impl::to_longest_alternative<alternative<A, B> >::result_t
        operator[](alternative<A, B> const& alt) const
        {
            return impl::to_longest_alternative<alternative<A, B> >::
                convert(alt);
        }
    };

    const longest_parser_gen longest_d = longest_parser_gen();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  shortest_alternative class
    //
    ///////////////////////////////////////////////////////////////////////////
    struct shortest_parser_gen;

    template <typename A, typename B>
    struct shortest_alternative
    :   public binary<A, B, parser<shortest_alternative<A, B> > >
    {
        typedef shortest_alternative<A, B>      self_t;
        typedef binary_parser_category          parser_category_t;
        typedef shortest_parser_gen             parser_generator_t;
        typedef binary<A, B, parser<self_t> >   base_t;

        shortest_alternative(A const& a, B const& b)
        : base_t(a, b) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            typename ScannerT::iterator_t save = scan.first;
            result_t l = this->left().parse(scan);
            std::swap(scan.first, save);
            result_t r = this->right().parse(scan);

            if (l || r)
            {
                if (l.length() < r.length() && l || !r)
                {
                    scan.first = save;
                    return l;
                }
                return r;
            }

            return scan.no_match();
        }
    };

    struct shortest_parser_gen
    {
        template <typename A, typename B>
        struct result {

            typedef typename
                impl::to_shortest_alternative<alternative<A, B> >::result_t
            type;
        };

        template <typename A, typename B>
        static typename
        impl::to_shortest_alternative<alternative<A, B> >::result_t
        generate(alternative<A, B> const& alt)
        {
            return impl::to_shortest_alternative<alternative<A, B> >::
                convert(alt);
        }

        //'generate' for binary composite
        template <typename A, typename B>
        static
        shortest_alternative<A, B>
        generate(A const &left, B const &right)
        {
            return shortest_alternative<A, B>(left, right);
        }

        template <typename A, typename B>
        typename impl::to_shortest_alternative<alternative<A, B> >::result_t
        operator[](alternative<A, B> const& alt) const
        {
            return impl::to_shortest_alternative<alternative<A, B> >::
                convert(alt);
        }
    };

    const shortest_parser_gen shortest_d = shortest_parser_gen();

    ///////////////////////////////////////////////////////////////////////////
    //
    //  min_bounded class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BoundsT>
    struct min_bounded_gen;

    template <typename ParserT, typename BoundsT>
    struct min_bounded
    :   public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > >
    {
        typedef min_bounded<ParserT, BoundsT>   self_t;
        typedef unary_parser_category           parser_category_t;
        typedef min_bounded_gen<BoundsT>        parser_generator_t;
        typedef unary<ParserT, parser<self_t> > base_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename parser_result<ParserT, ScannerT>::type type;
        };

        min_bounded(ParserT const& p, BoundsT const& min__)
        : base_t(p)
        , min_(min__) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            result_t hit = this->subject().parse(scan);
            if (hit.has_valid_attribute() && hit.value() < min_)
                return scan.no_match();
            return hit;
        }

        BoundsT min_;
    };

    template <typename BoundsT>
    struct min_bounded_gen
    {
        min_bounded_gen(BoundsT const& min__)
        : min_(min__) {}

        template <typename DerivedT>
        min_bounded<DerivedT, BoundsT>
        operator[](parser<DerivedT> const& p) const
        { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); }

        BoundsT min_;
    };

    template <typename BoundsT>
    inline min_bounded_gen<BoundsT>
    min_limit_d(BoundsT const& min_)
    { return min_bounded_gen<BoundsT>(min_); }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  max_bounded class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BoundsT>
    struct max_bounded_gen;

    template <typename ParserT, typename BoundsT>
    struct max_bounded
    :   public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > >
    {
        typedef max_bounded<ParserT, BoundsT>   self_t;
        typedef unary_parser_category           parser_category_t;
        typedef max_bounded_gen<BoundsT>        parser_generator_t;
        typedef unary<ParserT, parser<self_t> > base_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename parser_result<ParserT, ScannerT>::type type;
        };

        max_bounded(ParserT const& p, BoundsT const& max__)
        : base_t(p)
        , max_(max__) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            result_t hit = this->subject().parse(scan);
            if (hit.has_valid_attribute() && hit.value() > max_)
                return scan.no_match();
            return hit;
        }

        BoundsT max_;
    };

    template <typename BoundsT>
    struct max_bounded_gen
    {
        max_bounded_gen(BoundsT const& max__)
        : max_(max__) {}

        template <typename DerivedT>
        max_bounded<DerivedT, BoundsT>
        operator[](parser<DerivedT> const& p) const
        { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); }

        BoundsT max_;
    };

    //////////////////////////////////
    template <typename BoundsT>
    inline max_bounded_gen<BoundsT>
    max_limit_d(BoundsT const& max_)
    { return max_bounded_gen<BoundsT>(max_); }

    ///////////////////////////////////////////////////////////////////////////
    //
    //  bounded class
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename BoundsT>
    struct bounded_gen;

    template <typename ParserT, typename BoundsT>
    struct bounded
    :   public unary<ParserT, parser<bounded<ParserT, BoundsT> > >
    {
        typedef bounded<ParserT, BoundsT>       self_t;
        typedef unary_parser_category           parser_category_t;
        typedef bounded_gen<BoundsT>            parser_generator_t;
        typedef unary<ParserT, parser<self_t> > base_t;

        template <typename ScannerT>
        struct result
        {
            typedef typename parser_result<ParserT, ScannerT>::type type;
        };

        bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__)
        : base_t(p)
        , min_(min__)
        , max_(max__) {}

        template <typename ScannerT>
        typename parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename parser_result<self_t, ScannerT>::type result_t;
            result_t hit = this->subject().parse(scan);
            if (hit.has_valid_attribute() &&
                (hit.value() < min_ || hit.value() > max_))
                    return scan.no_match();
            return hit;
        }

        BoundsT min_, max_;
    };

    template <typename BoundsT>
    struct bounded_gen
    {
        bounded_gen(BoundsT const& min__, BoundsT const& max__)
        : min_(min__)
        , max_(max__) {}

        template <typename DerivedT>
        bounded<DerivedT, BoundsT>
        operator[](parser<DerivedT> const& p) const
        { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); }

        BoundsT min_, max_;
    };

    template <typename BoundsT>
    inline bounded_gen<BoundsT>
    limit_d(BoundsT const& min_, BoundsT const& max_)
    { return bounded_gen<BoundsT>(min_, max_); }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif

