Imported Upstream version 1.51.0
[platform/upstream/boost.git] / boost / spirit / home / phoenix / stl / container / container.hpp
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
18 namespace 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 ///////////////////////////////////////////////////////////////////////////////
678 function<stl::assign> const         assign = stl::assign();
679 function<stl::at> const             at = stl::at();
680 function<stl::back> const           back = stl::back();
681 function<stl::begin> const          begin = stl::begin();
682 function<stl::capacity> const       capacity = stl::capacity();
683 function<stl::clear> const          clear = stl::clear();
684 function<stl::empty> const          empty = stl::empty();
685 function<stl::end> const            end = stl::end();
686 function<stl::erase> const          erase = stl::erase();
687 function<stl::front> const          front = stl::front();
688 function<stl::get_allocator> const  get_allocator = stl::get_allocator();
689 function<stl::insert> const         insert = stl::insert();
690 function<stl::key_comp> const       key_comp = stl::key_comp();
691 function<stl::max_size> const       max_size = stl::max_size();
692 function<stl::pop_back> const       pop_back  = stl::pop_back();
693 function<stl::pop_front> const      pop_front = stl::pop_front();
694 function<stl::push_back> const      push_back  = stl::push_back();
695 function<stl::push_front> const     push_front = stl::push_front();
696 function<stl::rbegin> const         rbegin = stl::rbegin();
697 function<stl::rend> const           rend = stl::rend();
698 function<stl::reserve> const        reserve = stl::reserve();
699 function<stl::resize> const         resize = stl::resize();
700 function<stl::size> const           size = stl::size();
701 function<stl::splice> const         splice = stl::splice();
702 function<stl::value_comp> const     value_comp = stl::value_comp();
703
704 }} // namespace boost::phoenix
705
706 #endif // PHOENIX_STL_CONTAINERS_HPP