/*=============================================================================
    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(SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM)
#define SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/operator/kleene.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/foreach.hpp>
#include <vector>

namespace boost { namespace spirit
{
    ///////////////////////////////////////////////////////////////////////////
    // Enablers
    ///////////////////////////////////////////////////////////////////////////
    template <>
    struct use_directive<qi::domain, tag::repeat>   // enables repeat[p]
      : mpl::true_ {};

    template <typename T>
    struct use_directive<qi::domain
      , terminal_ex<tag::repeat                     // enables repeat(exact)[p]
        , fusion::vector1<T> >
    > : mpl::true_ {};

    template <typename T>
    struct use_directive<qi::domain
      , terminal_ex<tag::repeat                     // enables repeat(min, max)[p]
        , fusion::vector2<T, T> >
    > : mpl::true_ {};

    template <typename T>
    struct use_directive<qi::domain
      , terminal_ex<tag::repeat                     // enables repeat(min, inf)[p]
        , fusion::vector2<T, inf_type> >
    > : mpl::true_ {};

    template <>                                     // enables *lazy* repeat(exact)[p]
    struct use_lazy_directive<
        qi::domain
      , tag::repeat
      , 1 // arity
    > : mpl::true_ {};

    template <>                                     // enables *lazy* repeat(min, max)[p]
    struct use_lazy_directive<                      // and repeat(min, inf)[p]
        qi::domain
      , tag::repeat
      , 2 // arity
    > : mpl::true_ {};
}}

namespace boost { namespace spirit { namespace qi
{
    using spirit::repeat;
    using spirit::repeat_type;
    using spirit::inf;
    using spirit::inf_type;

    template <typename T>
    struct exact_iterator // handles repeat(exact)[p]
    {
        exact_iterator(T const exact)
          : exact(exact) {}

        typedef T type;
        T start() const { return 0; }
        bool got_max(T i) const { return i >= exact; }
        bool got_min(T i) const { return i >= exact; }

        T const exact;

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

    template <typename T>
    struct finite_iterator // handles repeat(min, max)[p]
    {
        finite_iterator(T const min, T const max)
          : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
          , max BOOST_PREVENT_MACRO_SUBSTITUTION (max) {}

        typedef T type;
        T start() const { return 0; }
        bool got_max(T i) const { return i >= max; }
        bool got_min(T i) const { return i >= min; }

        T const min;
        T const max;

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

    template <typename T>
    struct infinite_iterator // handles repeat(min, inf)[p]
    {
        infinite_iterator(T const min)
          : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}

        typedef T type;
        T start() const { return 0; }
        bool got_max(T /*i*/) const { return false; }
        bool got_min(T i) const { return i >= min; }

        T const min;

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

    template <typename Subject, typename LoopIter>
    struct repeat_parser : unary_parser<repeat_parser<Subject, LoopIter> >
    {
        typedef Subject subject_type;

        template <typename Context, typename Iterator>
        struct attribute
        {
            // Build a std::vector from the subject's attribute. Note
            // that build_std_vector may return unused_type if the
            // subject's attribute is an unused_type.
            typedef typename
                traits::build_std_vector<
                    typename traits::attribute_of<
                        Subject, Context, Iterator>::type
                >::type
            type;
        };

        repeat_parser(Subject const& subject, LoopIter const& iter)
          : subject(subject), iter(iter) {}

        template <typename Iterator, typename Context
          , typename Skipper, typename ValueType, typename Attribute
          , typename LoopVar>
        bool parse_minimal(Iterator &first, Iterator const& last
          , Context& context, Skipper const& skipper
          , Attribute& attr, ValueType& val, LoopVar& i) const
        {
            // this scope allows save and required_attr to be reclaimed 
            // immediately after we're done with the required minimum 
            // iteration.
            Iterator save = first;
            std::vector<ValueType> required_attr;
            for (; !iter.got_min(i); ++i)
            {
                if (!subject.parse(save, last, context, skipper, val) ||
                    !traits::push_back(required_attr, val))
                {
                    return false;
                }

                first = save;
                traits::clear(val);
            }

            // if we got the required number of items, these are copied 
            // over (appended) to the 'real' attribute
            BOOST_FOREACH(ValueType const& v, required_attr)
            {
                traits::push_back(attr, v);
            }
            return true;
        }

        template <typename Iterator, typename Context
          , typename Skipper, typename LoopVar>
        bool parse_minimal(Iterator &first, Iterator const& last
          , Context& context, Skipper const& skipper
          , unused_type, unused_type, LoopVar& i) const
        {
            // this scope allows save and required_attr to be reclaimed 
            // immediately after we're done with the required minimum 
            // iteration.
            Iterator save = first;
            for (; !iter.got_min(i); ++i)
            {
                if (!subject.parse(save, last, context, skipper, unused))
                {
                    return false;
                }
                first = save;
            }
            return true;
        }

        template <typename Iterator, typename Context
          , typename Skipper, typename Attribute>
        bool parse(Iterator& first, Iterator const& last
          , Context& context, Skipper const& skipper
          , Attribute& attr) const
        {
            // create a local value if Attribute is not unused_type
            typedef typename traits::container_value<Attribute>::type 
                value_type;
            value_type val = value_type();
            typename LoopIter::type i = iter.start();

            // parse the minimum required
            Iterator save = first;
            if (!iter.got_min(i) &&
                !parse_minimal(save, last, context, skipper, attr, val, i))
            {
                return false;
            }

            // parse some more up to the maximum specified
            for (/**/; !iter.got_max(i); ++i) {
                if (!subject.parse(save, last, context, skipper, val) ||
                    !traits::push_back(attr, val))
                {
                    break;
                }
                first = save;
                traits::clear(val);
            }

            first = save;
            return true;
        }

        template <typename Context>
        info what(Context& context) const
        {
            return info("repeat", subject.what(context));
        }

        Subject subject;
        LoopIter iter;

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

    ///////////////////////////////////////////////////////////////////////////
    // Parser generators: make_xxx function (objects)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Subject, typename Modifiers>
    struct make_directive<tag::repeat, Subject, Modifiers>
    {
        typedef kleene<Subject> result_type;
        result_type operator()(unused_type, Subject const& subject, unused_type) const
        {
            return result_type(subject);
        }
    };

    template <typename T, typename Subject, typename Modifiers>
    struct make_directive<
        terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
    {
        typedef exact_iterator<T> iterator_type;
        typedef repeat_parser<Subject, iterator_type> result_type;

        template <typename Terminal>
        result_type operator()(
            Terminal const& term, Subject const& subject, unused_type) const
        {
            return result_type(subject, fusion::at_c<0>(term.args));
        }
    };

    template <typename T, typename Subject, typename Modifiers>
    struct make_directive<
        terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
    {
        typedef finite_iterator<T> iterator_type;
        typedef repeat_parser<Subject, iterator_type> result_type;

        template <typename Terminal>
        result_type operator()(
            Terminal const& term, Subject const& subject, unused_type) const
        {
            return result_type(subject,
                iterator_type(
                    fusion::at_c<0>(term.args)
                  , fusion::at_c<1>(term.args)
                )
            );
        }
    };

    template <typename T, typename Subject, typename Modifiers>
    struct make_directive<
        terminal_ex<tag::repeat
        , fusion::vector2<T, inf_type> >, Subject, Modifiers>
    {
        typedef infinite_iterator<T> iterator_type;
        typedef repeat_parser<Subject, iterator_type> result_type;

        template <typename Terminal>
        result_type operator()(
            Terminal const& term, Subject const& subject, unused_type) const
        {
            return result_type(subject, fusion::at_c<0>(term.args));
        }
    };
}}}

namespace boost { namespace spirit { namespace traits
{
    template <typename Subject, typename LoopIter>
    struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
      : unary_has_semantic_action<Subject> {};
}}}

#endif
