]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/spirit/home/classic/dynamic/for.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / spirit / home / classic / dynamic / for.hpp
1 /*=============================================================================
2     Copyright (c) 2002-2003 Joel de Guzman
3     Copyright (c) 2002-2003 Martin Wille
4     http://spirit.sourceforge.net/
5
6   Distributed under the Boost Software License, Version 1.0. (See accompanying
7   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #ifndef BOOST_SPIRIT_FOR_HPP
10 #define BOOST_SPIRIT_FOR_HPP
11 ////////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/namespace.hpp>
13 #include <boost/spirit/home/classic/core/parser.hpp>
14 #include <boost/spirit/home/classic/core/composite/composite.hpp>
15 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
16
17 ////////////////////////////////////////////////////////////////////////////////
18
19 namespace boost { namespace spirit {
20
21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
22
23     namespace impl
24     {
25
26         template <typename FuncT>
27         struct for_functor
28         {
29             typedef typename boost::call_traits<FuncT>::param_type  param_t;
30
31             for_functor(param_t f) : func(f) {}
32             for_functor() {}
33             FuncT func;
34         };
35
36         template <typename InitF>
37         struct for_init_functor : for_functor<InitF>
38         {
39             typedef for_functor<InitF>          base_t;
40             typedef typename base_t::param_t    param_t;
41
42             for_init_functor(param_t f) : base_t(f) {}
43             for_init_functor() : base_t() {}
44             void init() const { /*return*/ this->func(); }
45         };
46
47         template <typename StepF>
48         struct for_step_functor : for_functor<StepF>
49         {
50             typedef for_functor<StepF>          base_t;
51             typedef typename base_t::param_t    param_t;
52
53             for_step_functor(param_t f) : base_t(f) {}
54             for_step_functor() : base_t() {}
55             void step() const { /*return*/ this->func(); }
56         };
57
58         //////////////////////////////////
59         // for_parser
60         template
61         <
62             typename InitF, typename CondT, typename StepF,
63             typename ParsableT
64         >
65         struct for_parser
66             : private for_init_functor<InitF>
67             , private for_step_functor<StepF>
68             , private condition_evaluator<typename as_parser<CondT>::type>
69             , public unary
70             <
71                 typename as_parser<ParsableT>::type,
72                 parser< for_parser<InitF, CondT, StepF, ParsableT> >
73             >
74         {
75             typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
76             typedef as_parser<CondT>                           cond_as_parser_t;
77             typedef typename cond_as_parser_t::type            condition_t;
78             typedef condition_evaluator<condition_t>           eval_t;
79             typedef as_parser<ParsableT>                       as_parser_t;
80             typedef typename as_parser_t::type                 parser_t;
81             typedef unary< parser_t, parser< self_t > >        base_t;
82
83
84             //////////////////////////////
85             // constructor, saves init, condition and step functors
86             // for later use the parse member function
87             for_parser
88             (
89                 InitF const &i, CondT const &c, StepF const &s,
90                 ParsableT const &p
91             )
92                 : for_init_functor<InitF>(i)
93                 , for_step_functor<StepF>(s)
94                 , eval_t(cond_as_parser_t::convert(c))
95                 , base_t(as_parser_t::convert(p))
96             { }
97
98             for_parser()
99                 : for_init_functor<InitF>()
100                 , for_step_functor<StepF>()
101                 , eval_t()
102                 , base_t()
103             {}
104
105             //////////////////////////////
106             // parse member function
107             template <typename ScannerT>
108             typename parser_result<self_t, ScannerT>::type
109             parse(ScannerT const &scan) const
110             {
111                 typedef typename parser_result<self_t, ScannerT>::type
112                     result_t;
113                 typedef typename parser_result<parser_t, ScannerT>::type
114                     body_result_t;
115
116                 typename ScannerT::iterator_t save(scan.first);
117
118                 std::size_t length = 0;
119                 int eval_length = 0;
120
121                 this->init();
122                 while ((eval_length = this->evaluate(scan))>=0)
123                 {
124                     length += eval_length;
125                     body_result_t tmp(this->subject().parse(scan));
126                     if (tmp)
127                     {
128                         length+=tmp.length();
129                     }
130                     else
131                     {
132                         return scan.no_match();
133                     }
134                     this->step();
135                 }
136
137                 BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
138                 return scan.create_match
139                     (length, attr, save, scan.first);
140             }
141         };
142
143         //////////////////////////////////
144         // for_parser_gen generates takes the body parser in brackets
145         // and returns the for_parser
146         template <typename InitF, typename CondT, typename StepF>
147         struct for_parser_gen
148         {
149             for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
150                 : init(i)
151                 , condition(c)
152                 , step(s)
153             {}
154
155             template <typename ParsableT>
156             for_parser<InitF, CondT, StepF, ParsableT>
157             operator[](ParsableT const &p) const
158             {
159                 return for_parser<InitF, CondT, StepF, ParsableT>
160                     (init, condition, step, p);
161             }
162
163             InitF const &init;
164             CondT const &condition;
165             StepF const &step;
166         };
167     } // namespace impl
168
169     //////////////////////////////
170     // for_p, returns for-parser generator
171     // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
172     template
173     <
174         typename InitF, typename ConditionT, typename StepF
175     >
176     impl::for_parser_gen<InitF, ConditionT, StepF>
177     for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
178     {
179         return impl::for_parser_gen<InitF, ConditionT, StepF>
180             (init_f, condition, step_f);
181     }
182
183 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
184
185 }} // namespace BOOST_SPIRIT_CLASSIC_NS
186
187 #endif // BOOST_SPIRIT_FOR_HPP