PageRenderTime 69ms CodeModel.GetById 9ms app.highlight 55ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/boost/spirit/home/phoenix/stl/container/container.hpp

http://pythonocc.googlecode.com/
C++ Header | 706 lines | 518 code | 73 blank | 115 comment | 1 complexity | 56b7b3364856797892079a0131716502 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2004 Angus Leeming
  3    Copyright (c) 2004 Joel de Guzman
  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#ifndef PHOENIX_STL_CONTAINER_CONTAINER_HPP
  9#define PHOENIX_STL_CONTAINER_CONTAINER_HPP
 10
 11#include <boost/spirit/home/phoenix/stl/container/detail/container.hpp>
 12#include <boost/spirit/home/phoenix/function/function.hpp>
 13#include <boost/mpl/and.hpp>
 14#include <boost/mpl/not.hpp>
 15#include <boost/mpl/or.hpp>
 16#include <boost/type_traits/is_const.hpp>
 17
 18namespace boost { namespace phoenix
 19{
 20///////////////////////////////////////////////////////////////////////////////
 21//
 22//  STL container member functions
 23//
 24//      Lazy functions for STL container member functions
 25//
 26//      These functions provide a mechanism for the lazy evaluation of the
 27//      public member functions of the STL containers. For an overview of
 28//      what is meant by 'lazy evaluation', see the comments in operators.hpp
 29//      and functions.hpp.
 30//
 31//      Lazy functions are provided for all of the member functions of the
 32//      following containers:
 33//
 34//      deque - list - map - multimap - vector.
 35//
 36//      Indeed, should *your* class have member functions with the same names
 37//      and signatures as those listed below, then it will automatically be
 38//      supported. To summarize, lazy functions are provided for member
 39//      functions:
 40//
 41//          assign - at - back - begin - capacity - clear - empty - end -
 42//          erase - front - get_allocator - insert - key_comp - max_size -
 43//          pop_back - pop_front - push_back - push_front - rbegin - rend -
 44//          reserve - resize . size - splice - value_comp.
 45//
 46//      The lazy functions' names are the same as the corresponding member
 47//      function. Sample usage:
 48//
 49//      "Normal" version                 "Lazy" version
 50//      ----------------                 --------------
 51//      my_vector.at(5)                  phoenix::at(arg1, 5)
 52//      my_list.size()                   phoenix::size(arg1)
 53//      my_vector1.swap(my_vector2)      phoenix::swap(arg1, arg2)
 54//
 55//      Notice that member functions with names that clash with a
 56//      function in stl algorithms are absent. This will be provided
 57//      in Phoenix's algorithm module.
 58//
 59//      No support is provided here for lazy versions of operator+=,
 60//      operator[] etc. Such operators are not specific to STL containers and
 61//      lazy versions can therefore be found in operators.hpp.
 62//
 63///////////////////////////////////////////////////////////////////////////////
 64
 65///////////////////////////////////////////////////////////////////////////////
 66//
 67//  Lazy member function implementaions.
 68//
 69//      The structs below provide the guts of the implementation. Thereafter,
 70//      the corresponding lazy function itself is simply:
 71//
 72//          function<stl::assign> const assign = stl::assign();
 73//
 74//      The structs provide a nested "result" class template whose
 75//      "type" typedef enables the lazy function to ascertain the type
 76//      to be returned when it is invoked.
 77//
 78//      They also provide operator() member functions with signatures
 79//      corresponding to those of the underlying member function of
 80//      the STL container.
 81//
 82///////////////////////////////////////////////////////////////////////////////
 83    namespace stl
 84    {
 85        struct assign
 86        {
 87            template <
 88                typename C
 89              , typename Arg1 = fusion::void_
 90              , typename Arg2 = fusion::void_
 91              , typename Arg3 = fusion::void_
 92            >
 93            struct result
 94            {
 95                typedef typename add_reference<C>::type type;
 96            };
 97
 98            template <typename C, typename Arg1>
 99            C& operator()(C& c, Arg1 const& arg1) const
100            {
101                c.assign(arg1);
102                return c;
103            }
104
105            template <typename C, typename Arg1, typename Arg2>
106            C& operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
107            {
108                c.assign(arg1, arg2);
109                return c;
110            }
111
112            template <typename C, typename Arg1, typename Arg2, typename Arg3>
113            C& operator()(
114                C& c
115              , Arg1 const& arg1
116              , Arg2 const& arg2
117              , Arg3 const& arg3) const
118            {
119                return c.assign(arg1, arg2, arg3);
120            }
121        };
122
123        struct at
124        {
125            template <typename C, typename Index>
126            struct result
127            {
128                typedef typename const_qualified_reference_of<C>::type type;
129            };
130
131            template <typename C, typename Index>
132            typename result<C, Index>::type
133            operator()(C& c, Index const& i) const
134            {
135                return c.at(i);
136            }
137        };
138
139        struct back
140        {
141            template <typename C>
142            struct result
143            {
144                typedef 
145                    typename const_qualified_reference_of<C>::type
146                type;
147            };
148
149            template <typename C>
150            typename result<C>::type
151            operator()(C& c) const
152            {
153                return c.back();
154            }
155        };
156
157        struct begin
158        {
159            template <typename C>
160            struct result
161            {
162                typedef typename const_qualified_iterator_of<C>::type type;
163            };
164
165            template <typename C>
166            typename result<C>::type
167            operator()(C& c) const
168            {
169                return c.begin();
170            }
171        };
172
173        struct capacity
174        {
175            template <typename C>
176            struct result
177            {
178                typedef typename size_type_of<C>::type type;
179            };
180
181            template <typename C>
182            typename result<C>::type
183            operator()(C const& c) const
184            {
185                return c.capacity();
186            }
187        };
188
189        struct clear
190        {
191            template <typename C>
192            struct result
193            {
194                typedef void type;
195            };
196
197            template <typename C>
198            void operator()(C& c) const
199            {
200                return c.clear();
201            }
202        };
203
204        struct empty
205        {
206            template <typename C>
207            struct result
208            {
209                typedef bool type;
210            };
211
212            template <typename C>
213            bool operator()(C const& c) const
214            {
215                return c.empty();
216            }
217        };
218
219        struct end
220        {
221            template <typename C>
222            struct result
223            {
224                typedef typename const_qualified_iterator_of<C>::type type;
225            };
226
227            template <typename C>
228            typename result<C>::type
229            operator()(C& c) const
230            {
231                return c.end();
232            }
233        };
234
235        struct erase
236        {
237            //  This mouthful can differentiate between the generic erase
238            //  functions (Container == std::deque, std::list, std::vector) and
239            //  that specific to the two map-types, std::map and std::multimap.
240            //
241            //  where C is a std::deque, std::list, std::vector:
242            //
243            //      1) iterator C::erase(iterator where);
244            //      2) iterator C::erase(iterator first, iterator last);
245            //
246            //  where M is a std::map or std::multimap:
247            //
248            //      3) size_type M::erase(const Key& keyval);
249            //      4) void M::erase(iterator where);
250            //      5) void M::erase(iterator first, iterator last);
251
252            template <typename C, typename Arg1, typename Arg2 = fusion::void_>
253            struct result
254            {
255                //  BOOST_MSVC #if branch here in map_erase_result non-
256                //  standard behavior. The return type should be void but
257                //  VC7.1 prefers to return iterator_of<C>. As a result,
258                //  VC7.1 complains of error C2562:
259                //  boost::phoenix::stl::erase::operator() 'void' function
260                //  returning a value. Oh well... :*
261
262                typedef
263                    boost::mpl::eval_if<
264                        boost::is_same<Arg1, typename iterator_of<C>::type>
265#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1500)
266                      , iterator_of<C>
267#else
268                      , boost::mpl::identity<void>
269#endif
270                      , size_type_of<C>
271                    >
272                map_erase_result;
273
274                typedef typename
275                    boost::mpl::eval_if<
276                        has_mapped_type<C>
277                      , map_erase_result
278                      , iterator_of<C>
279                    >::type
280                type;
281            };
282
283            template <typename C, typename Arg1>
284            typename result<C, Arg1>::type
285            operator()(C& c, Arg1 const& arg1) const
286            {
287                return c.erase(arg1);
288            }
289
290            template <typename C, typename Arg1, typename Arg2>
291            typename result<C, Arg1, Arg2>::type
292            operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
293            {
294                return c.erase(arg1, arg2);
295            }
296        };
297
298        struct front
299        {
300            template <typename C>
301            struct result
302            {
303                typedef typename const_qualified_reference_of<C>::type type;
304            };
305
306            template <typename C>
307            typename result<C>::type
308            operator()(C& c) const
309            {
310                return c.front();
311            }
312        };
313
314        struct get_allocator
315        {
316            template <typename C>
317            struct result
318            {
319                typedef typename allocator_type_of<C>::type type;
320            };
321
322            template <typename C>
323            typename result<C>::type
324            operator()(C const& c) const
325            {
326                return c.get_allocator();
327            }
328        };
329
330        struct insert
331        {
332            //  This mouthful can differentiate between the generic insert
333            //  functions (Container == deque, list, vector) and those
334            //  specific to the two map-types, std::map and std::multimap.
335            //
336            //  where C is a std::deque, std::list, std::vector:
337            //
338            //      1) iterator C::insert(iterator where, value_type value);
339            //      2) void C::insert(
340            //          iterator where, size_type count, value_type value);
341            //      3) template <typename Iter>
342            //         void C::insert(iterator where, Iter first, Iter last);
343            //
344            //  where M is a std::map and MM is a std::multimap:
345            //
346            //      4) pair<iterator, bool> M::insert(value_type const&);
347            //      5) iterator MM::insert(value_type const&);
348            //
349            //  where M is a std::map or std::multimap:
350            //
351            //      6) template <typename Iter>
352            //         void M::insert(Iter first, Iter last);
353
354            template <
355                typename C
356              , typename Arg1
357              , typename Arg2 = fusion::void_
358              , typename Arg3 = fusion::void_
359            >
360            class result
361            {
362                struct pair_iterator_bool
363                {
364                    typedef typename std::pair<typename C::iterator, bool> type;
365                };
366
367                typedef
368                    boost::mpl::eval_if<
369                        map_insert_returns_pair<C>
370                      , pair_iterator_bool
371                      , iterator_of<C>
372                    >
373                choice_1;
374
375                typedef
376                    boost::mpl::eval_if<
377                        boost::mpl::and_<
378                            boost::is_same<Arg3, fusion::void_>
379                          , boost::mpl::not_<boost::is_same<Arg1, Arg2> > >
380                      , iterator_of<C>
381                      , boost::mpl::identity<void>
382                    >
383                choice_2;
384
385            public:
386
387                typedef typename
388                    boost::mpl::eval_if<
389                        boost::is_same<Arg2, fusion::void_>
390                      , choice_1
391                      , choice_2
392                    >::type
393                type;
394            };
395
396            template <typename C, typename Arg1>
397            typename result<C, Arg1>::type
398            operator()(C& c, Arg1 const& arg1) const
399            {
400                return c.insert(arg1);
401            }
402
403            template <typename C, typename Arg1, typename Arg2>
404            typename result<C, Arg1, Arg2>::type
405            operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
406            {
407                return c.insert(arg1, arg2);
408            }
409
410            template <typename C, typename Arg1, typename Arg2, typename Arg3>
411            typename result<C, Arg1, Arg2, Arg3>::type
412            operator()(
413                C& c, Arg1 const& arg1, Arg2 const& arg2, Arg3 const& arg3) const
414            {
415                return c.insert(arg1, arg2, arg3);
416            }
417        };
418
419        struct key_comp
420        {
421            template <typename C>
422            struct result
423            {
424                typedef typename key_compare_of<C>::type type;
425            };
426
427            template <typename C>
428            typename result<C>::type
429            operator()(C const& c) const
430            {
431                return c.key_comp();
432            }
433        };
434
435        struct max_size
436        {
437            template <typename C>
438            struct result
439            {
440                typedef typename size_type_of<C>::type type;
441            };
442
443            template <typename C>
444            typename result<C>::type
445            operator()(C const& c) const
446            {
447                return c.max_size();
448            }
449        };
450
451        struct pop_back
452        {
453            template <typename C>
454            struct result
455            {
456                typedef void type;
457            };
458
459            template <typename C>
460            void operator()(C& c) const
461            {
462                return c.pop_back();
463            }
464        };
465
466        struct pop_front
467        {
468            template <typename C>
469            struct result
470            {
471                typedef void type;
472            };
473
474            template <typename C>
475            void operator()(C& c) const
476            {
477                return c.pop_front();
478            }
479        };
480
481        struct push_back
482        {
483            template <typename C, typename Arg>
484            struct result
485            {
486                typedef void type;
487            };
488
489            template <typename C, typename Arg>
490            void operator()(C& c, Arg const& data) const
491            {
492                return c.push_back(data);
493            }
494        };
495
496        struct push_front
497        {
498            template <typename C, typename Arg>
499            struct result
500            {
501                typedef void type;
502            };
503
504            template <typename C, typename Arg>
505            void operator()(C& c, Arg const& data) const
506            {
507                return c.push_front(data);
508            }
509        };
510
511        struct rbegin
512        {
513            template <typename C>
514            struct result
515            {
516                typedef typename
517                    const_qualified_reverse_iterator_of<C>::type
518                type;
519            };
520
521            template <typename C>
522            typename result<C>::type
523            operator()(C& c) const
524            {
525                return c.rbegin();
526            }
527        };
528
529        struct rend
530        {
531            template <typename C>
532            struct result
533            {
534                typedef typename
535                    const_qualified_reverse_iterator_of<C>::type
536                type;
537            };
538
539            template <typename C>
540            typename result<C>::type
541            operator()(C& c) const
542            {
543                return c.rend();
544            }
545        };
546
547        struct reserve
548        {
549
550            template <typename C, typename Arg>
551            struct result
552            {
553                typedef void type;
554            };
555
556            template <typename C, typename Arg>
557            void operator()(C& c, Arg const& count) const
558            {
559                return c.reserve(count);
560            }
561        };
562
563        struct resize
564        {
565            template <typename C, typename Arg1, typename Arg2 = fusion::void_>
566            struct result
567            {
568                typedef void type;
569            };
570
571            template <typename C, typename Arg1>
572            void operator()(C& c, Arg1 const& arg1) const
573            {
574                return c.resize(arg1);
575            }
576
577            template <typename C, typename Arg1, typename Arg2>
578            void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
579            {
580                return c.resize(arg1, arg2);
581            }
582        };
583
584        struct size
585        {
586            template <typename C>
587            struct result
588            {
589                typedef typename size_type_of<C>::type type;
590            };
591
592            template <typename C>
593            typename result<C>::type
594            operator()(C const& c) const
595            {
596                return c.size();
597            }
598        };
599
600    struct splice
601    {
602        template <
603            typename C
604          , typename Arg1
605          , typename Arg2
606          , typename Arg3 = fusion::void_
607          , typename Arg4 = fusion::void_
608        >
609        struct result
610        {
611            typedef void type;
612        };
613
614        template <typename C, typename Arg1, typename Arg2>
615        void operator()(C& c, Arg1 const& arg1, Arg2& arg2) const
616        {
617            c.splice(arg1, arg2);
618        }
619
620        template <
621            typename C
622          , typename Arg1
623          , typename Arg2
624          , typename Arg3
625        >
626        void operator()(
627            C& c
628          , Arg1 const& arg1
629          , Arg2& arg2
630          , Arg3 const& arg3
631        ) const
632        {
633            c.splice(arg1, arg2, arg3);
634        }
635
636        template <
637            typename C
638          , typename Arg1
639          , typename Arg2
640          , typename Arg3
641          , typename Arg4
642        >
643        void operator()(
644            C& c
645          , Arg1 const& arg1
646          , Arg2& arg2
647          , Arg3 const& arg3
648          , Arg4 const& arg4
649        ) const
650        {
651            c.splice(arg1, arg2, arg3, arg4);
652        }
653    };
654
655    struct value_comp
656    {
657        template <typename C>
658        struct result
659        {
660            typedef typename value_compare_of<C>::type type;
661        };
662
663        template <typename C>
664        typename result<C>::type
665        operator()(C const& c) const
666        {
667            return c.value_comp();
668        }
669    };
670
671} // namespace stl
672
673///////////////////////////////////////////////////////////////////////////////
674//
675//  The lazy functions themselves.
676//
677///////////////////////////////////////////////////////////////////////////////
678function<stl::assign> const         assign = stl::assign();
679function<stl::at> const             at = stl::at();
680function<stl::back> const           back = stl::back();
681function<stl::begin> const          begin = stl::begin();
682function<stl::capacity> const       capacity = stl::capacity();
683function<stl::clear> const          clear = stl::clear();
684function<stl::empty> const          empty = stl::empty();
685function<stl::end> const            end = stl::end();
686function<stl::erase> const          erase = stl::erase();
687function<stl::front> const          front = stl::front();
688function<stl::get_allocator> const  get_allocator = stl::get_allocator();
689function<stl::insert> const         insert = stl::insert();
690function<stl::key_comp> const       key_comp = stl::key_comp();
691function<stl::max_size> const       max_size = stl::max_size();
692function<stl::pop_back> const       pop_back  = stl::pop_back();
693function<stl::pop_front> const      pop_front = stl::pop_front();
694function<stl::push_back> const      push_back  = stl::push_back();
695function<stl::push_front> const     push_front = stl::push_front();
696function<stl::rbegin> const         rbegin = stl::rbegin();
697function<stl::rend> const           rend = stl::rend();
698function<stl::reserve> const        reserve = stl::reserve();
699function<stl::resize> const         resize = stl::resize();
700function<stl::size> const           size = stl::size();
701function<stl::splice> const         splice = stl::splice();
702function<stl::value_comp> const     value_comp = stl::value_comp();
703
704}} // namespace boost::phoenix
705
706#endif // PHOENIX_STL_CONTAINERS_HPP