PageRenderTime 34ms CodeModel.GetById 13ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/spirit/home/qi/directive/repeat.hpp

http://hadesmem.googlecode.com/
C++ Header | 297 lines | 229 code | 44 blank | 24 comment | 5 complexity | 4c3bd0a96b11b5d8dcf8dde358e52fd7 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2011 Joel de Guzman
  3    Copyright (c) 2001-2011 Hartmut Kaiser
  4
  5    Distributed under the Boost Software License, Version 1.0. (See accompanying
  6    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7=============================================================================*/
  8#if !defined(SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM)
  9#define SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM
 10
 11#if defined(_MSC_VER)
 12#pragma once
 13#endif
 14
 15#include <boost/spirit/home/qi/meta_compiler.hpp>
 16#include <boost/spirit/home/qi/parser.hpp>
 17#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
 18#include <boost/spirit/home/qi/operator/kleene.hpp>
 19#include <boost/spirit/home/support/container.hpp>
 20#include <boost/spirit/home/support/common_terminals.hpp>
 21#include <boost/spirit/home/qi/detail/attributes.hpp>
 22#include <boost/spirit/home/qi/detail/fail_function.hpp>
 23#include <boost/spirit/home/qi/detail/pass_container.hpp>
 24#include <boost/spirit/home/support/info.hpp>
 25#include <boost/spirit/home/support/has_semantic_action.hpp>
 26#include <boost/spirit/home/support/handles_container.hpp>
 27#include <boost/fusion/include/at.hpp>
 28#include <vector>
 29
 30namespace boost { namespace spirit
 31{
 32    ///////////////////////////////////////////////////////////////////////////
 33    // Enablers
 34    ///////////////////////////////////////////////////////////////////////////
 35    template <>
 36    struct use_directive<qi::domain, tag::repeat>   // enables repeat[p]
 37      : mpl::true_ {};
 38
 39    template <typename T>
 40    struct use_directive<qi::domain
 41      , terminal_ex<tag::repeat                     // enables repeat(exact)[p]
 42        , fusion::vector1<T> >
 43    > : mpl::true_ {};
 44
 45    template <typename T>
 46    struct use_directive<qi::domain
 47      , terminal_ex<tag::repeat                     // enables repeat(min, max)[p]
 48        , fusion::vector2<T, T> >
 49    > : mpl::true_ {};
 50
 51    template <typename T>
 52    struct use_directive<qi::domain
 53      , terminal_ex<tag::repeat                     // enables repeat(min, inf)[p]
 54        , fusion::vector2<T, inf_type> >
 55    > : mpl::true_ {};
 56
 57    template <>                                     // enables *lazy* repeat(exact)[p]
 58    struct use_lazy_directive<
 59        qi::domain
 60      , tag::repeat
 61      , 1 // arity
 62    > : mpl::true_ {};
 63
 64    template <>                                     // enables *lazy* repeat(min, max)[p]
 65    struct use_lazy_directive<                      // and repeat(min, inf)[p]
 66        qi::domain
 67      , tag::repeat
 68      , 2 // arity
 69    > : mpl::true_ {};
 70}}
 71
 72namespace boost { namespace spirit { namespace qi
 73{
 74#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
 75    using spirit::repeat;
 76    using spirit::inf;
 77#endif
 78    using spirit::repeat_type;
 79    using spirit::inf_type;
 80
 81    template <typename T>
 82    struct exact_iterator // handles repeat(exact)[p]
 83    {
 84        exact_iterator(T const exact)
 85          : exact(exact) {}
 86
 87        typedef T type;
 88        T start() const { return 0; }
 89        bool got_max(T i) const { return i >= exact; }
 90        bool got_min(T i) const { return i >= exact; }
 91
 92        T const exact;
 93
 94    private:
 95        // silence MSVC warning C4512: assignment operator could not be generated
 96        exact_iterator& operator= (exact_iterator const&);
 97    };
 98
 99    template <typename T>
100    struct finite_iterator // handles repeat(min, max)[p]
101    {
102        finite_iterator(T const min, T const max)
103          : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
104          , max BOOST_PREVENT_MACRO_SUBSTITUTION (max) {}
105
106        typedef T type;
107        T start() const { return 0; }
108        bool got_max(T i) const { return i >= max; }
109        bool got_min(T i) const { return i >= min; }
110
111        T const min;
112        T const max;
113
114    private:
115        // silence MSVC warning C4512: assignment operator could not be generated
116        finite_iterator& operator= (finite_iterator const&);
117    };
118
119    template <typename T>
120    struct infinite_iterator // handles repeat(min, inf)[p]
121    {
122        infinite_iterator(T const min)
123          : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
124
125        typedef T type;
126        T start() const { return 0; }
127        bool got_max(T /*i*/) const { return false; }
128        bool got_min(T i) const { return i >= min; }
129
130        T const min;
131
132    private:
133        // silence MSVC warning C4512: assignment operator could not be generated
134        infinite_iterator& operator= (infinite_iterator const&);
135    };
136
137    template <typename Subject, typename LoopIter>
138    struct repeat_parser : unary_parser<repeat_parser<Subject, LoopIter> >
139    {
140        typedef Subject subject_type;
141
142        template <typename Context, typename Iterator>
143        struct attribute
144        {
145            // Build a std::vector from the subject's attribute. Note
146            // that build_std_vector may return unused_type if the
147            // subject's attribute is an unused_type.
148            typedef typename
149                traits::build_std_vector<
150                    typename traits::attribute_of<
151                        Subject, Context, Iterator>::type
152                >::type
153            type;
154        };
155
156        repeat_parser(Subject const& subject, LoopIter const& iter)
157          : subject(subject), iter(iter) {}
158
159        template <typename F>
160        bool parse_container(F f) const
161        {
162            typename LoopIter::type i = iter.start();
163            for (/**/; !iter.got_min(i); ++i)
164            {
165                if (f (subject))
166                    return false;
167            }
168
169            // parse some more up to the maximum specified
170            typename F::iterator_type save = f.f.first;
171            for (/**/; !iter.got_max(i); ++i)
172            {
173                if (f (subject))
174                    break;
175                save = f.f.first;
176            }
177
178            f.f.first = save;
179            return true;
180        }
181
182        template <typename Iterator, typename Context
183          , typename Skipper, typename Attribute>
184        bool parse(Iterator& first, Iterator const& last
185          , Context& context, Skipper const& skipper
186          , Attribute& attr) const
187        {
188            typedef detail::fail_function<Iterator, Context, Skipper>
189                fail_function;
190
191            // ensure the attribute is actually a container type
192            traits::make_container(attr);
193
194            Iterator iter = first;
195            fail_function f(iter, last, context, skipper);
196            if (!parse_container(detail::make_pass_container(f, attr)))
197                return false;
198
199            first = f.first;
200            return true;
201        }
202
203        template <typename Context>
204        info what(Context& context) const
205        {
206            return info("repeat", subject.what(context));
207        }
208
209        Subject subject;
210        LoopIter iter;
211
212    private:
213        // silence MSVC warning C4512: assignment operator could not be generated
214        repeat_parser& operator= (repeat_parser const&);
215    };
216
217    ///////////////////////////////////////////////////////////////////////////
218    // Parser generators: make_xxx function (objects)
219    ///////////////////////////////////////////////////////////////////////////
220    template <typename Subject, typename Modifiers>
221    struct make_directive<tag::repeat, Subject, Modifiers>
222    {
223        typedef kleene<Subject> result_type;
224        result_type operator()(unused_type, Subject const& subject, unused_type) const
225        {
226            return result_type(subject);
227        }
228    };
229
230    template <typename T, typename Subject, typename Modifiers>
231    struct make_directive<
232        terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
233    {
234        typedef exact_iterator<T> iterator_type;
235        typedef repeat_parser<Subject, iterator_type> result_type;
236
237        template <typename Terminal>
238        result_type operator()(
239            Terminal const& term, Subject const& subject, unused_type) const
240        {
241            return result_type(subject, fusion::at_c<0>(term.args));
242        }
243    };
244
245    template <typename T, typename Subject, typename Modifiers>
246    struct make_directive<
247        terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
248    {
249        typedef finite_iterator<T> iterator_type;
250        typedef repeat_parser<Subject, iterator_type> result_type;
251
252        template <typename Terminal>
253        result_type operator()(
254            Terminal const& term, Subject const& subject, unused_type) const
255        {
256            return result_type(subject,
257                iterator_type(
258                    fusion::at_c<0>(term.args)
259                  , fusion::at_c<1>(term.args)
260                )
261            );
262        }
263    };
264
265    template <typename T, typename Subject, typename Modifiers>
266    struct make_directive<
267        terminal_ex<tag::repeat
268        , fusion::vector2<T, inf_type> >, Subject, Modifiers>
269    {
270        typedef infinite_iterator<T> iterator_type;
271        typedef repeat_parser<Subject, iterator_type> result_type;
272
273        template <typename Terminal>
274        result_type operator()(
275            Terminal const& term, Subject const& subject, unused_type) const
276        {
277            return result_type(subject, fusion::at_c<0>(term.args));
278        }
279    };
280}}}
281
282namespace boost { namespace spirit { namespace traits
283{
284    ///////////////////////////////////////////////////////////////////////////
285    template <typename Subject, typename LoopIter>
286    struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
287      : unary_has_semantic_action<Subject> {};
288
289    ///////////////////////////////////////////////////////////////////////////
290    template <typename Subject, typename LoopIter, typename Attribute
291      , typename Context, typename Iterator>
292    struct handles_container<qi::repeat_parser<Subject, LoopIter>
293          , Attribute, Context, Iterator>
294      : mpl::true_ {};
295}}}
296
297#endif