/*============================================================================= 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 #include #include #include //////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN namespace impl { template struct for_functor { typedef typename boost::call_traits::param_type param_t; for_functor(param_t f) : func(f) {} for_functor() {} FuncT func; }; template struct for_init_functor : for_functor { typedef for_functor 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 struct for_step_functor : for_functor { typedef for_functor 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 , private for_step_functor , private condition_evaluator::type> , public unary < typename as_parser::type, parser< for_parser > > { typedef for_parser self_t; typedef as_parser cond_as_parser_t; typedef typename cond_as_parser_t::type condition_t; typedef condition_evaluator eval_t; typedef as_parser 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(i) , for_step_functor(s) , eval_t(cond_as_parser_t::convert(c)) , base_t(as_parser_t::convert(p)) { } for_parser() : for_init_functor() , for_step_functor() , eval_t() , base_t() {} ////////////////////////////// // parse member function template typename parser_result::type parse(ScannerT const &scan) const { typedef typename parser_result::type result_t; typedef typename parser_result::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 struct for_parser_gen { for_parser_gen(InitF const &i, CondT const &c, StepF const &s) : init(i) , condition(c) , step(s) {} template for_parser operator[](ParsableT const &p) const { return for_parser (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 for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f) { return impl::for_parser_gen (init_f, condition, step_f); } BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #endif // BOOST_SPIRIT_FOR_HPP