/*=============================================================================
    Copyright (c) 2002-2003 Joel de Guzman
    Copyright (c) 2002-2003 Martin Wille
    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)
=============================================================================*/
#ifndef BOOST_SPIRIT_FOR_HPP
#define BOOST_SPIRIT_FOR_HPP
////////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>

////////////////////////////////////////////////////////////////////////////////

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    namespace impl
    {

        template <typename FuncT>
        struct for_functor
        {
            typedef typename boost::call_traits<FuncT>::param_type  param_t;

            for_functor(param_t f) : func(f) {}
            for_functor() {}
            FuncT func;
        };

        template <typename InitF>
        struct for_init_functor : for_functor<InitF>
        {
            typedef for_functor<InitF>          base_t;
            typedef typename base_t::param_t    param_t;

            for_init_functor(param_t f) : base_t(f) {}
            for_init_functor() : base_t() {}
            void init() const { /*return*/ this->func(); }
        };

        template <typename StepF>
        struct for_step_functor : for_functor<StepF>
        {
            typedef for_functor<StepF>          base_t;
            typedef typename base_t::param_t    param_t;

            for_step_functor(param_t f) : base_t(f) {}
            for_step_functor() : base_t() {}
            void step() const { /*return*/ this->func(); }
        };

        //////////////////////////////////
        // for_parser
        template
        <
            typename InitF, typename CondT, typename StepF,
            typename ParsableT
        >
        struct for_parser
            : private for_init_functor<InitF>
            , private for_step_functor<StepF>
            , private condition_evaluator<typename as_parser<CondT>::type>
            , public unary
            <
                typename as_parser<ParsableT>::type,
                parser< for_parser<InitF, CondT, StepF, ParsableT> >
            >
        {
            typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
            typedef as_parser<CondT>                           cond_as_parser_t;
            typedef typename cond_as_parser_t::type            condition_t;
            typedef condition_evaluator<condition_t>           eval_t;
            typedef as_parser<ParsableT>                       as_parser_t;
            typedef typename as_parser_t::type                 parser_t;
            typedef unary< parser_t, parser< self_t > >        base_t;


            //////////////////////////////
            // constructor, saves init, condition and step functors
            // for later use the parse member function
            for_parser
            (
                InitF const &i, CondT const &c, StepF const &s,
                ParsableT const &p
            )
                : for_init_functor<InitF>(i)
                , for_step_functor<StepF>(s)
                , eval_t(cond_as_parser_t::convert(c))
                , base_t(as_parser_t::convert(p))
            { }

            for_parser()
                : for_init_functor<InitF>()
                , for_step_functor<StepF>()
                , eval_t()
                , base_t()
            {}

            //////////////////////////////
            // parse member function
            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;
                typedef typename parser_result<parser_t, ScannerT>::type
                    body_result_t;

                typename ScannerT::iterator_t save(scan.first);

                std::size_t length = 0;
                int eval_length = 0;

                this->init();
                while ((eval_length = this->evaluate(scan))>=0)
                {
                    length += eval_length;
                    body_result_t tmp(this->subject().parse(scan));
                    if (tmp)
                    {
                        length+=tmp.length();
                    }
                    else
                    {
                        return scan.no_match();
                    }
                    this->step();
                }

                BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
                return scan.create_match
                    (length, attr, save, scan.first);
            }
        };

        //////////////////////////////////
        // for_parser_gen generates takes the body parser in brackets
        // and returns the for_parser
        template <typename InitF, typename CondT, typename StepF>
        struct for_parser_gen
        {
            for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
                : init(i)
                , condition(c)
                , step(s)
            {}

            template <typename ParsableT>
            for_parser<InitF, CondT, StepF, ParsableT>
            operator[](ParsableT const &p) const
            {
                return for_parser<InitF, CondT, StepF, ParsableT>
                    (init, condition, step, p);
            }

            InitF const &init;
            CondT const &condition;
            StepF const &step;
        };
    } // namespace impl

    //////////////////////////////
    // for_p, returns for-parser generator
    // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
    template
    <
        typename InitF, typename ConditionT, typename StepF
    >
    impl::for_parser_gen<InitF, ConditionT, StepF>
    for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
    {
        return impl::for_parser_gen<InitF, ConditionT, StepF>
            (init_f, condition, step_f);
    }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace BOOST_SPIRIT_CLASSIC_NS

#endif // BOOST_SPIRIT_FOR_HPP
