PageRenderTime 45ms CodeModel.GetById 17ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/spirit/home/qi/string/symbols.hpp

http://hadesmem.googlecode.com/
C++ Header | 414 lines | 346 code | 54 blank | 14 comment | 7 complexity | 223dea5e84f17f03771f7d35fa11301f MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2011 Joel de Guzman
  3
  4    Distributed under the Boost Software License, Version 1.0. (See accompanying
  5    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6==============================================================================*/
  7#if !defined(BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM)
  8#define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM
  9
 10#if defined(_MSC_VER)
 11#pragma once
 12#endif
 13
 14#include <boost/spirit/home/qi/domain.hpp>
 15#include <boost/spirit/home/qi/skip_over.hpp>
 16#include <boost/spirit/home/qi/string/tst.hpp>
 17#include <boost/spirit/home/qi/reference.hpp>
 18#include <boost/spirit/home/qi/meta_compiler.hpp>
 19#include <boost/spirit/home/qi/detail/assign_to.hpp>
 20#include <boost/spirit/home/qi/parser.hpp>
 21#include <boost/spirit/home/support/detail/get_encoding.hpp>
 22#include <boost/spirit/home/support/modify.hpp>
 23#include <boost/spirit/home/support/info.hpp>
 24#include <boost/spirit/home/support/unused.hpp>
 25#include <boost/spirit/home/support/string_traits.hpp>
 26
 27#include <boost/fusion/include/at.hpp>
 28#include <boost/range.hpp>
 29#include <boost/type_traits/add_reference.hpp>
 30#include <boost/shared_ptr.hpp>
 31
 32#if defined(BOOST_MSVC)
 33# pragma warning(push)
 34# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
 35#endif
 36
 37namespace boost { namespace spirit { namespace qi
 38{
 39    template <
 40        typename Char = char
 41      , typename T = unused_type
 42      , typename Lookup = tst<Char, T>
 43      , typename Filter = tst_pass_through>
 44    struct symbols
 45      : proto::extends<
 46            typename proto::terminal<
 47                reference<symbols<Char, T, Lookup, Filter> >
 48            >::type
 49          , symbols<Char, T, Lookup, Filter>
 50        >
 51      , primitive_parser<symbols<Char, T, Lookup, Filter> >
 52    {
 53        typedef Char char_type; // the character type
 54        typedef T value_type; // the value associated with each entry
 55        typedef symbols<Char, T, Lookup, Filter> this_type;
 56        typedef reference<this_type> reference_;
 57        typedef typename proto::terminal<reference_>::type terminal;
 58        typedef proto::extends<terminal, this_type> base_type;
 59
 60        template <typename Context, typename Iterator>
 61        struct attribute
 62        {
 63            typedef value_type type;
 64        };
 65
 66        symbols(std::string const& name = "symbols")
 67          : base_type(terminal::make(reference_(*this)))
 68          , add(*this)
 69          , remove(*this)
 70          , lookup(new Lookup())
 71          , name_(name)
 72        {
 73        }
 74
 75        symbols(symbols const& syms)
 76          : base_type(terminal::make(reference_(*this)))
 77          , add(*this)
 78          , remove(*this)
 79          , lookup(syms.lookup)
 80          , name_(syms.name_)
 81        {
 82        }
 83
 84        template <typename Filter_>
 85        symbols(symbols<Char, T, Lookup, Filter_> const& syms)
 86          : base_type(terminal::make(reference_(*this)))
 87          , add(*this)
 88          , remove(*this)
 89          , lookup(syms.lookup)
 90          , name_(syms.name_)
 91        {
 92        }
 93
 94        template <typename Symbols>
 95        symbols(Symbols const& syms, std::string const& name = "symbols")
 96          : base_type(terminal::make(reference_(*this)))
 97          , add(*this)
 98          , remove(*this)
 99          , lookup(new Lookup())
100          , name_(name)
101        {
102            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
103            while (si != boost::end(syms))
104                add(*si++);
105        }
106
107        template <typename Symbols, typename Data>
108        symbols(Symbols const& syms, Data const& data
109              , std::string const& name = "symbols")
110          : base_type(terminal::make(reference_(*this)))
111          , add(*this)
112          , remove(*this)
113          , lookup(new Lookup())
114          , name_(name)
115        {
116            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
117            typename range_const_iterator<Data>::type di = boost::begin(data);
118            while (si != boost::end(syms))
119                add(*si++, *di++);
120        }
121
122        symbols&
123        operator=(symbols const& rhs)
124        {
125            name_ = rhs.name_;
126            *lookup = *rhs.lookup;
127            return *this;
128        }
129
130        template <typename Filter_>
131        symbols&
132        operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
133        {
134            name_ = rhs.name_;
135            *lookup = *rhs.lookup;
136            return *this;
137        }
138
139        void clear()
140        {
141            lookup->clear();
142        }
143
144        struct adder;
145        struct remover;
146
147        template <typename Str>
148        adder const&
149        operator=(Str const& str)
150        {
151            lookup->clear();
152            return add(str);
153        }
154
155        template <typename Str>
156        friend adder const&
157        operator+=(symbols& sym, Str const& str)
158        {
159            return sym.add(str);
160        }
161
162        template <typename Str>
163        friend remover const&
164        operator-=(symbols& sym, Str const& str)
165        {
166            return sym.remove(str);
167        }
168
169        // non-const version needed to suppress proto's += kicking in
170        template <typename Str>
171        friend adder const&
172        operator+=(symbols& sym, Str& str)
173        {
174            return sym.add(str);
175        }
176
177        // non-const version needed to suppress proto's -= kicking in
178        template <typename Str>
179        friend remover const&
180        operator-=(symbols& sym, Str& str)
181        {
182            return sym.remove(str);
183        }
184
185        template <typename F>
186        void for_each(F f) const
187        {
188            lookup->for_each(f);
189        }
190
191        template <typename Str>
192        value_type& at(Str const& str)
193        {
194            return *lookup->add(traits::get_begin<Char>(str)
195                , traits::get_end<Char>(str), T());
196        }
197
198        template <typename Iterator>
199        value_type* prefix_find(Iterator& first, Iterator const& last)
200        {
201            return lookup->find(first, last, Filter());
202        }
203
204        template <typename Iterator>
205        value_type const* prefix_find(Iterator& first, Iterator const& last) const
206        {
207            return lookup->find(first, last, Filter());
208        }
209
210        template <typename Str>
211        value_type* find(Str const& str)
212        {
213            return find_impl(traits::get_begin<Char>(str)
214                , traits::get_end<Char>(str));
215        }
216
217        template <typename Str>
218        value_type const* find(Str const& str) const
219        {
220            return find_impl(traits::get_begin<Char>(str)
221                , traits::get_end<Char>(str));
222        }
223
224private:
225        template <typename Iterator>
226        value_type* find_impl(Iterator begin, Iterator end)
227        {
228            value_type* r = lookup->find(begin, end, Filter());
229            return begin == end ? r : 0;
230        }
231
232        template <typename Iterator>
233        value_type const* find_impl(Iterator begin, Iterator end) const
234        {
235            value_type const* r = lookup->find(begin, end, Filter());
236            return begin == end ? r : 0;
237        }
238
239public:
240        template <typename Iterator, typename Context
241          , typename Skipper, typename Attribute>
242        bool parse(Iterator& first, Iterator const& last
243          , Context& /*context*/, Skipper const& skipper, Attribute& attr) const
244        {
245            qi::skip_over(first, last, skipper);
246
247            if (value_type* val_ptr
248                = lookup->find(first, last, Filter()))
249            {
250                spirit::traits::assign_to(*val_ptr, attr);
251                return true;
252            }
253            return false;
254        }
255
256        template <typename Context>
257        info what(Context& /*context*/) const
258        {
259            return info(name_);
260        }
261
262        void name(std::string const &str)
263        {
264            name_ = str;
265        }
266        std::string const &name() const
267        {
268            return name_;
269        }
270
271        struct adder
272        {
273            template <typename, typename = unused_type, typename = unused_type>
274            struct result { typedef adder const& type; };
275
276            adder(symbols& sym)
277              : sym(sym)
278            {
279            }
280
281            template <typename Iterator>
282            adder const&
283            operator()(Iterator const& first, Iterator const& last, T const& val) const
284            {
285                sym.lookup->add(first, last, val);
286                return *this;
287            }
288
289            template <typename Str>
290            adder const&
291            operator()(Str const& s, T const& val = T()) const
292            {
293                sym.lookup->add(traits::get_begin<Char>(s)
294                  , traits::get_end<Char>(s), val);
295                return *this;
296            }
297
298            template <typename Str>
299            adder const&
300            operator,(Str const& s) const
301            {
302                sym.lookup->add(traits::get_begin<Char>(s)
303                  , traits::get_end<Char>(s), T());
304                return *this;
305            }
306
307            symbols& sym;
308
309        private:
310            // silence MSVC warning C4512: assignment operator could not be generated
311            adder& operator= (adder const&);
312        };
313
314        struct remover
315        {
316            template <typename, typename = unused_type, typename = unused_type>
317            struct result { typedef remover const& type; };
318
319            remover(symbols& sym)
320              : sym(sym)
321            {
322            }
323
324            template <typename Iterator>
325            remover const&
326            operator()(Iterator const& first, Iterator const& last) const
327            {
328                sym.lookup->remove(first, last);
329                return *this;
330            }
331
332            template <typename Str>
333            remover const&
334            operator()(Str const& s) const
335            {
336                sym.lookup->remove(traits::get_begin<Char>(s)
337                  , traits::get_end<Char>(s));
338                return *this;
339            }
340
341            template <typename Str>
342            remover const&
343            operator,(Str const& s) const
344            {
345                sym.lookup->remove(traits::get_begin<Char>(s)
346                  , traits::get_end<Char>(s));
347                return *this;
348            }
349
350            symbols& sym;
351
352        private:
353            // silence MSVC warning C4512: assignment operator could not be generated
354            remover& operator= (remover const&);
355        };
356
357        adder add;
358        remover remove;
359        shared_ptr<Lookup> lookup;
360        std::string name_;
361    };
362
363    ///////////////////////////////////////////////////////////////////////////
364    // Parser generators: make_xxx function (objects)
365    ///////////////////////////////////////////////////////////////////////////
366    template <typename Char, typename T, typename Lookup
367      , typename Filter, typename Modifiers>
368    struct make_primitive<reference<symbols<Char, T, Lookup, Filter> >, Modifiers>
369    {
370        template <typename CharEncoding>
371        struct no_case_filter
372        {
373            Char operator()(Char ch) const
374            {
375                return static_cast<Char>(CharEncoding::tolower(ch));
376            }
377        };
378
379        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
380        typedef reference<symbols<Char, T, Lookup, Filter> > reference_;
381        typedef no_case_filter<
382            typename spirit::detail::get_encoding_with_case<
383                Modifiers
384              , char_encoding::standard
385              , no_case::value>::type>
386        nc_filter;
387
388        typedef typename mpl::if_<
389            no_case
390          , symbols<Char, T, Lookup, nc_filter>
391          , reference_>::type
392        result_type;
393
394        result_type operator()(reference_ ref, unused_type) const
395        {
396            return result_type(ref.ref.get());
397        }
398    };
399}}}
400
401namespace boost { namespace spirit { namespace traits
402{
403    ///////////////////////////////////////////////////////////////////////////
404    template <typename Char, typename T, typename Lookup, typename Filter
405      , typename Attr, typename Context, typename Iterator>
406    struct handles_container<qi::symbols<Char, T, Lookup, Filter>, Attr, Context, Iterator>
407      : traits::is_container<Attr> {}; 
408}}}
409
410#if defined(BOOST_MSVC)
411# pragma warning(pop)
412#endif
413
414#endif