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

source code of boost/libs/phoenix/include/boost/phoenix/stl/container/container.hpp