1
/*=============================================================================
3
Copyright (c) 2002-2003 Joel de Guzman
4
Copyright (c) 2002-2003 Martin Wille
5
http://spirit.sourceforge.net/
7
Permission to copy, use, modify, sell and distribute this software is
8
granted provided this copyright notice appears in all copies. This
9
software is provided "as is" without express or implied warranty, and
10
with no claim as to its suitability for any purpose.
11
=============================================================================*/
12
#ifndef BOOST_SPIRIT_FOR_HPP
13
#define BOOST_SPIRIT_FOR_HPP
14
////////////////////////////////////////////////////////////////////////////////
15
#if !defined(BOOST_SPIRIT_PARSER_HPP)
16
#include "boost/spirit/core/parser.hpp"
19
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
20
#include "boost/spirit/core/composite/composite.hpp"
23
#if !defined(BOOST_SPIRIT_CONDITIONS_IPP)
24
#include "boost/spirit/dynamic/impl/conditions.ipp"
26
////////////////////////////////////////////////////////////////////////////////
28
namespace boost { namespace spirit
33
template <typename FuncT>
34
struct for_functor : private subject_type<FuncT, nil_t>::type
36
typedef typename subject_type<FuncT, nil_t>::type base_t;
37
typedef typename boost::call_traits<FuncT>::param_type param_t;
38
typedef typename base_t::return_t return_t;
40
for_functor(param_t f) : base_t(f) {}
41
for_functor() : base_t() {}
42
return_t get() const { return base_t::get(); }
45
template <typename InitF>
46
struct for_init_functor : for_functor<InitF>
48
typedef for_functor<InitF> base_t;
49
typedef typename base_t::param_t param_t;
51
for_init_functor(param_t f) : base_t(f) {}
52
for_init_functor() : base_t() {}
53
void init() const { /*return*/ base_t::get()(); }
56
template <typename StepF>
57
struct for_step_functor : for_functor<StepF>
59
typedef for_functor<StepF> base_t;
60
typedef typename base_t::param_t param_t;
62
for_step_functor(param_t f) : base_t(f) {}
63
for_step_functor() : base_t() {}
64
void step() const { /*return*/ base_t::get()(); }
67
//////////////////////////////////
71
typename InitF, typename CondT, typename StepF,
75
: private for_init_functor<InitF>
76
, private for_step_functor<StepF>
77
, private condition_evaluator<typename as_parser<CondT>::type>
80
typename as_parser<ParsableT>::type,
81
parser< for_parser<InitF, CondT, StepF, ParsableT> >
84
typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
85
typedef as_parser<CondT> cond_as_parser_t;
86
typedef typename cond_as_parser_t::type condition_t;
87
typedef condition_evaluator<condition_t> eval_t;
88
typedef as_parser<ParsableT> as_parser_t;
89
typedef typename as_parser_t::type parser_t;
90
typedef unary< parser_t, parser< self_t > > base_t;
93
//////////////////////////////
94
// constructor, saves init, condition and step functors
95
// for later use the parse member function
98
InitF const &i, CondT const &c, StepF const &s,
101
: for_init_functor<InitF>(i)
102
, for_step_functor<StepF>(s)
103
, eval_t(cond_as_parser_t::convert(c))
104
, base_t(as_parser_t::convert(p))
108
: for_init_functor<InitF>()
109
, for_step_functor<StepF>()
114
//////////////////////////////
115
// parse member function
116
template <typename ScannerT>
117
typename parser_result<self_t, ScannerT>::type
118
parse(ScannerT const &scan) const
120
typedef typename parser_result<self_t, ScannerT>::type
122
typedef typename parser_result<parser_t, ScannerT>::type
125
typename ScannerT::iterator_t save(scan.first);
131
while ((eval_length = this->evaluate(scan))>=0)
133
length += eval_length;
134
body_result_t tmp(this->subject().parse(scan));
137
length+=tmp.length();
141
return scan.no_match();
146
boost::spirit::nil_t attr;
147
return scan.create_match
148
(length, attr, save, scan.first);
152
//////////////////////////////////
153
// for_parser_gen generates takes the body parser in brackets
154
// and returns the for_parser
155
template <typename InitF, typename CondT, typename StepF>
156
struct for_parser_gen
158
for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
164
template <typename ParsableT>
165
for_parser<InitF, CondT, StepF, ParsableT>
166
operator[](ParsableT const &p) const
168
return for_parser<InitF, CondT, StepF, ParsableT>
169
(init, condition, step, p);
173
CondT const &condition;
178
//////////////////////////////
179
// for_p, returns for-parser generator
180
// Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
183
typename InitF, typename ConditionT, typename StepF
185
impl::for_parser_gen<InitF, ConditionT, StepF>
186
for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
188
return impl::for_parser_gen<InitF, ConditionT, StepF>
189
(init_f, condition, step_f);
192
}} // namespace boost::spirit
194
#endif // BOOST_SPIRIT_FOR_HPP