1 /*=============================================================================
2 Copyright (c) 2004 Angus Leeming
3 Copyright (c) 2004 Joel de Guzman
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
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>
18 namespace boost { namespace phoenix
20 ///////////////////////////////////////////////////////////////////////////////
22 // STL container member functions
24 // Lazy functions for STL container member functions
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
31 // Lazy functions are provided for all of the member functions of the
32 // following containers:
34 // deque - list - map - multimap - vector.
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
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.
46 // The lazy functions' names are the same as the corresponding member
47 // function. Sample usage:
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)
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.
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.
63 ///////////////////////////////////////////////////////////////////////////////
65 ///////////////////////////////////////////////////////////////////////////////
67 // Lazy member function implementaions.
69 // The structs below provide the guts of the implementation. Thereafter,
70 // the corresponding lazy function itself is simply:
72 // function<stl::assign> const assign = stl::assign();
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.
78 // They also provide operator() member functions with signatures
79 // corresponding to those of the underlying member function of
82 ///////////////////////////////////////////////////////////////////////////////
89 , typename Arg1 = fusion::void_
90 , typename Arg2 = fusion::void_
91 , typename Arg3 = fusion::void_
95 typedef typename add_reference<C>::type type;
98 template <typename C, typename Arg1>
99 C& operator()(C& c, Arg1 const& arg1) const
105 template <typename C, typename Arg1, typename Arg2>
106 C& operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
108 c.assign(arg1, arg2);
112 template <typename C, typename Arg1, typename Arg2, typename Arg3>
117 , Arg3 const& arg3) const
119 return c.assign(arg1, arg2, arg3);
125 template <typename C, typename Index>
128 typedef typename const_qualified_reference_of<C>::type type;
131 template <typename C, typename Index>
132 typename result<C, Index>::type
133 operator()(C& c, Index const& i) const
141 template <typename C>
145 typename const_qualified_reference_of<C>::type
149 template <typename C>
150 typename result<C>::type
151 operator()(C& c) const
159 template <typename C>
162 typedef typename const_qualified_iterator_of<C>::type type;
165 template <typename C>
166 typename result<C>::type
167 operator()(C& c) const
175 template <typename C>
178 typedef typename size_type_of<C>::type type;
181 template <typename C>
182 typename result<C>::type
183 operator()(C const& c) const
191 template <typename C>
197 template <typename C>
198 void operator()(C& c) const
206 template <typename C>
212 template <typename C>
213 bool operator()(C const& c) const
221 template <typename C>
224 typedef typename const_qualified_iterator_of<C>::type type;
227 template <typename C>
228 typename result<C>::type
229 operator()(C& c) const
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.
241 // where C is a std::deque, std::list, std::vector:
243 // 1) iterator C::erase(iterator where);
244 // 2) iterator C::erase(iterator first, iterator last);
246 // where M is a std::map or std::multimap:
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);
252 template <typename C, typename Arg1, typename Arg2 = fusion::void_>
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... :*
264 boost::is_same<Arg1, typename iterator_of<C>::type>
265 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1500)
268 , boost::mpl::identity<void>
283 template <typename C, typename Arg1>
284 typename result<C, Arg1>::type
285 operator()(C& c, Arg1 const& arg1) const
287 return c.erase(arg1);
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
294 return c.erase(arg1, arg2);
300 template <typename C>
303 typedef typename const_qualified_reference_of<C>::type type;
306 template <typename C>
307 typename result<C>::type
308 operator()(C& c) const
316 template <typename C>
319 typedef typename allocator_type_of<C>::type type;
322 template <typename C>
323 typename result<C>::type
324 operator()(C const& c) const
326 return c.get_allocator();
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.
336 // where C is a std::deque, std::list, std::vector:
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);
344 // where M is a std::map and MM is a std::multimap:
346 // 4) pair<iterator, bool> M::insert(value_type const&);
347 // 5) iterator MM::insert(value_type const&);
349 // where M is a std::map or std::multimap:
351 // 6) template <typename Iter>
352 // void M::insert(Iter first, Iter last);
357 , typename Arg2 = fusion::void_
358 , typename Arg3 = fusion::void_
362 struct pair_iterator_bool
364 typedef typename std::pair<typename C::iterator, bool> type;
369 map_insert_returns_pair<C>
378 boost::is_same<Arg3, fusion::void_>
379 , boost::mpl::not_<boost::is_same<Arg1, Arg2> > >
381 , boost::mpl::identity<void>
389 boost::is_same<Arg2, fusion::void_>
396 template <typename C, typename Arg1>
397 typename result<C, Arg1>::type
398 operator()(C& c, Arg1 const& arg1) const
400 return c.insert(arg1);
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
407 return c.insert(arg1, arg2);
410 template <typename C, typename Arg1, typename Arg2, typename Arg3>
411 typename result<C, Arg1, Arg2, Arg3>::type
413 C& c, Arg1 const& arg1, Arg2 const& arg2, Arg3 const& arg3) const
415 return c.insert(arg1, arg2, arg3);
421 template <typename C>
424 typedef typename key_compare_of<C>::type type;
427 template <typename C>
428 typename result<C>::type
429 operator()(C const& c) const
437 template <typename C>
440 typedef typename size_type_of<C>::type type;
443 template <typename C>
444 typename result<C>::type
445 operator()(C const& c) const
453 template <typename C>
459 template <typename C>
460 void operator()(C& c) const
468 template <typename C>
474 template <typename C>
475 void operator()(C& c) const
477 return c.pop_front();
483 template <typename C, typename Arg>
489 template <typename C, typename Arg>
490 void operator()(C& c, Arg const& data) const
492 return c.push_back(data);
498 template <typename C, typename Arg>
504 template <typename C, typename Arg>
505 void operator()(C& c, Arg const& data) const
507 return c.push_front(data);
513 template <typename C>
517 const_qualified_reverse_iterator_of<C>::type
521 template <typename C>
522 typename result<C>::type
523 operator()(C& c) const
531 template <typename C>
535 const_qualified_reverse_iterator_of<C>::type
539 template <typename C>
540 typename result<C>::type
541 operator()(C& c) const
550 template <typename C, typename Arg>
556 template <typename C, typename Arg>
557 void operator()(C& c, Arg const& count) const
559 return c.reserve(count);
565 template <typename C, typename Arg1, typename Arg2 = fusion::void_>
571 template <typename C, typename Arg1>
572 void operator()(C& c, Arg1 const& arg1) const
574 return c.resize(arg1);
577 template <typename C, typename Arg1, typename Arg2>
578 void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
580 return c.resize(arg1, arg2);
586 template <typename C>
589 typedef typename size_type_of<C>::type type;
592 template <typename C>
593 typename result<C>::type
594 operator()(C const& c) const
606 , typename Arg3 = fusion::void_
607 , typename Arg4 = fusion::void_
614 template <typename C, typename Arg1, typename Arg2>
615 void operator()(C& c, Arg1 const& arg1, Arg2& arg2) const
617 c.splice(arg1, arg2);
633 c.splice(arg1, arg2, arg3);
651 c.splice(arg1, arg2, arg3, arg4);
657 template <typename C>
660 typedef typename value_compare_of<C>::type type;
663 template <typename C>
664 typename result<C>::type
665 operator()(C const& c) const
667 return c.value_comp();
673 ///////////////////////////////////////////////////////////////////////////////
675 // The lazy functions themselves.
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();
704 }} // namespace boost::phoenix
706 #endif // PHOENIX_STL_CONTAINERS_HPP