~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/spirit/dynamic/for.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Spirit v1.6.1
 
3
    Copyright (c) 2002-2003 Joel de Guzman
 
4
    Copyright (c) 2002-2003 Martin Wille
 
5
    http://spirit.sourceforge.net/
 
6
 
 
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"
 
17
#endif
 
18
 
 
19
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
 
20
#include "boost/spirit/core/composite/composite.hpp"
 
21
#endif
 
22
 
 
23
#if !defined(BOOST_SPIRIT_CONDITIONS_IPP)
 
24
#include "boost/spirit/dynamic/impl/conditions.ipp"
 
25
#endif
 
26
////////////////////////////////////////////////////////////////////////////////
 
27
 
 
28
namespace boost { namespace spirit
 
29
{
 
30
    namespace impl
 
31
    {
 
32
 
 
33
        template <typename FuncT>
 
34
        struct for_functor : private subject_type<FuncT, nil_t>::type
 
35
        {
 
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;
 
39
 
 
40
            for_functor(param_t f) : base_t(f) {}
 
41
            for_functor() : base_t() {}
 
42
            return_t get() const { return base_t::get(); }
 
43
        };
 
44
 
 
45
        template <typename InitF>
 
46
        struct for_init_functor : for_functor<InitF>
 
47
        {
 
48
            typedef for_functor<InitF>          base_t;
 
49
            typedef typename base_t::param_t    param_t;
 
50
 
 
51
            for_init_functor(param_t f) : base_t(f) {}
 
52
            for_init_functor() : base_t() {}
 
53
            void init() const { /*return*/ base_t::get()(); }
 
54
        };
 
55
 
 
56
        template <typename StepF>
 
57
        struct for_step_functor : for_functor<StepF>
 
58
        {
 
59
            typedef for_functor<StepF>          base_t;
 
60
            typedef typename base_t::param_t    param_t;
 
61
 
 
62
            for_step_functor(param_t f) : base_t(f) {}
 
63
            for_step_functor() : base_t() {}
 
64
            void step() const { /*return*/ base_t::get()(); }
 
65
        };
 
66
 
 
67
        //////////////////////////////////
 
68
        // for_parser
 
69
        template
 
70
        <
 
71
            typename InitF, typename CondT, typename StepF,
 
72
            typename ParsableT
 
73
        >
 
74
        struct for_parser
 
75
            : private for_init_functor<InitF>
 
76
            , private for_step_functor<StepF>
 
77
            , private condition_evaluator<typename as_parser<CondT>::type>
 
78
            , public unary
 
79
            <
 
80
                typename as_parser<ParsableT>::type,
 
81
                parser< for_parser<InitF, CondT, StepF, ParsableT> >
 
82
            >
 
83
        {
 
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;
 
91
 
 
92
 
 
93
            //////////////////////////////
 
94
            // constructor, saves init, condition and step functors
 
95
            // for later use the parse member function
 
96
            for_parser
 
97
            (
 
98
                InitF const &i, CondT const &c, StepF const &s,
 
99
                ParsableT const &p
 
100
            )
 
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))
 
105
            { }
 
106
 
 
107
            for_parser()
 
108
                : for_init_functor<InitF>()
 
109
                , for_step_functor<StepF>()
 
110
                , eval_t()
 
111
                , base_t()
 
112
            {}
 
113
 
 
114
            //////////////////////////////
 
115
            // parse member function
 
116
            template <typename ScannerT>
 
117
            typename parser_result<self_t, ScannerT>::type
 
118
            parse(ScannerT const &scan) const
 
119
            {
 
120
                typedef typename parser_result<self_t, ScannerT>::type
 
121
                    result_t;
 
122
                typedef typename parser_result<parser_t, ScannerT>::type
 
123
                    body_result_t;
 
124
 
 
125
                typename ScannerT::iterator_t save(scan.first);
 
126
 
 
127
                int length = 0;
 
128
                int eval_length = 0;
 
129
 
 
130
                this->init();
 
131
                while ((eval_length = this->evaluate(scan))>=0)
 
132
                {
 
133
                    length += eval_length;
 
134
                    body_result_t tmp(this->subject().parse(scan));
 
135
                    if (tmp)
 
136
                    {
 
137
                        length+=tmp.length();
 
138
                    }
 
139
                    else
 
140
                    {
 
141
                        return scan.no_match();
 
142
                    }
 
143
                    this->step();
 
144
                }
 
145
 
 
146
                boost::spirit::nil_t attr;
 
147
                return scan.create_match
 
148
                    (length, attr, save, scan.first);
 
149
            }
 
150
        };
 
151
 
 
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
 
157
        {
 
158
            for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
 
159
                : init(i)
 
160
                , condition(c)
 
161
                , step(s)
 
162
            {}
 
163
 
 
164
            template <typename ParsableT>
 
165
            for_parser<InitF, CondT, StepF, ParsableT>
 
166
            operator[](ParsableT const &p) const
 
167
            {
 
168
                return for_parser<InitF, CondT, StepF, ParsableT>
 
169
                    (init, condition, step, p);
 
170
            }
 
171
 
 
172
            InitF const &init;
 
173
            CondT const &condition;
 
174
            StepF const &step;
 
175
        };
 
176
    } // namespace impl
 
177
 
 
178
    //////////////////////////////
 
179
    // for_p, returns for-parser generator
 
180
    // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
 
181
    template
 
182
    <
 
183
        typename InitF, typename ConditionT, typename StepF
 
184
    >
 
185
    impl::for_parser_gen<InitF, ConditionT, StepF>
 
186
    for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
 
187
    {
 
188
        return impl::for_parser_gen<InitF, ConditionT, StepF>
 
189
            (init_f, condition, step_f);
 
190
    }
 
191
 
 
192
}} // namespace boost::spirit
 
193
 
 
194
#endif // BOOST_SPIRIT_FOR_HPP