1 // Profiling list implementation -*- C++ -*-
3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file profile/list
26 * This file is a GNU profile extension to the Standard C++ Library.
29 #ifndef _GLIBCXX_PROFILE_LIST
30 #define _GLIBCXX_PROFILE_LIST 1
38 /// Class std::list wrapper with performance instrumentation.
39 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
41 : public _GLIBCXX_STD_D::list<_Tp, _Allocator>
43 typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
46 typedef typename _Base::reference reference;
47 typedef typename _Base::const_reference const_reference;
49 typedef typename _Base::iterator iterator;
50 typedef typename _Base::const_iterator const_iterator;
52 typedef typename _Base::size_type size_type;
53 typedef typename _Base::difference_type difference_type;
55 typedef _Tp value_type;
56 typedef _Allocator allocator_type;
57 typedef typename _Base::pointer pointer;
58 typedef typename _Base::const_pointer const_pointer;
59 typedef std::reverse_iterator<iterator> reverse_iterator;
60 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
62 // 23.2.2.1 construct/copy/destroy:
63 explicit list(const _Allocator& __a = _Allocator())
66 explicit list(size_type __n, const _Tp& __value = _Tp(),
67 const _Allocator& __a = _Allocator())
68 : _Base(__n, __value, __a) { }
70 template<class _InputIterator>
71 list(_InputIterator __first, _InputIterator __last,
72 const _Allocator& __a = _Allocator())
73 : _Base(__first, __last, __a)
79 list(const _Base& __x)
82 #ifdef __GXX_EXPERIMENTAL_CXX0X__
84 : _Base(std::forward<list>(__x))
87 list(initializer_list<value_type> __l,
88 const allocator_type& __a = allocator_type())
95 operator=(const list& __x)
97 static_cast<_Base&>(*this) = __x;
101 #ifdef __GXX_EXPERIMENTAL_CXX0X__
103 operator=(list&& __x)
115 operator=(initializer_list<value_type> __l)
117 static_cast<_Base&>(*this) = __l;
122 assign(initializer_list<value_type> __l)
123 { _Base::assign(__l); }
126 template<class _InputIterator>
128 assign(_InputIterator __first, _InputIterator __last)
129 { _Base::assign(__first, __last); }
132 assign(size_type __n, const _Tp& __t)
133 { _Base::assign(__n, __t); }
135 using _Base::get_allocator;
140 { return iterator(_Base::begin()); }
144 { return const_iterator(_Base::begin()); }
148 { return iterator(_Base::end()); }
152 { return const_iterator(_Base::end()); }
156 { return reverse_iterator(end()); }
158 const_reverse_iterator
160 { return const_reverse_iterator(end()); }
164 { return reverse_iterator(begin()); }
166 const_reverse_iterator
168 { return const_reverse_iterator(begin()); }
170 #ifdef __GXX_EXPERIMENTAL_CXX0X__
173 { return const_iterator(_Base::begin()); }
177 { return const_iterator(_Base::end()); }
179 const_reverse_iterator
181 { return const_reverse_iterator(end()); }
183 const_reverse_iterator
185 { return const_reverse_iterator(begin()); }
188 // 23.2.2.2 capacity:
191 using _Base::max_size;
194 resize(size_type __sz, _Tp __c = _Tp())
195 { _Base::resize(__sz, __c); }
200 { return _Base::front(); }
204 { return _Base::front(); }
208 { return _Base::back(); }
212 { return _Base::back(); }
214 // 23.2.2.3 modifiers:
215 using _Base::push_front;
217 #ifdef __GXX_EXPERIMENTAL_CXX0X__
218 using _Base::emplace_front;
224 iterator __victim = begin();
228 using _Base::push_back;
230 #ifdef __GXX_EXPERIMENTAL_CXX0X__
231 using _Base::emplace_back;
237 iterator __victim = end();
242 #ifdef __GXX_EXPERIMENTAL_CXX0X__
243 template<typename... _Args>
245 emplace(iterator __position, _Args&&... __args)
247 return iterator(_Base::emplace(__position,
248 std::forward<_Args>(__args)...));
253 insert(iterator __position, const _Tp& __x)
254 { return iterator(_Base::insert(__position, __x)); }
256 #ifdef __GXX_EXPERIMENTAL_CXX0X__
258 insert(iterator __position, _Tp&& __x)
259 { return emplace(__position, std::move(__x)); }
262 insert(iterator __p, initializer_list<value_type> __l)
263 { _Base::insert(__p, __l); }
267 insert(iterator __position, size_type __n, const _Tp& __x)
268 { _Base::insert(__position, __n, __x); }
270 template<class _InputIterator>
272 insert(iterator __position, _InputIterator __first,
273 _InputIterator __last)
274 { _Base::insert(__position, __first, __last); }
277 erase(iterator __position)
278 { return iterator(_Base::erase(__position)); }
281 erase(iterator __position, iterator __last)
283 // _GLIBCXX_RESOLVE_LIB_DEFECTS
284 // 151. can't currently clear() empty container
285 return iterator(_Base::erase(__position, __last));
290 { _Base::swap(__x); }
296 // 23.2.2.4 list operations:
298 #ifdef __GXX_EXPERIMENTAL_CXX0X__
299 splice(iterator __position, list&& __x)
301 splice(iterator __position, list& __x)
303 { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }
305 #ifdef __GXX_EXPERIMENTAL_CXX0X__
307 splice(iterator __position, list& __x)
308 { this->splice(__position, std::move(__x)); }
312 #ifdef __GXX_EXPERIMENTAL_CXX0X__
313 splice(iterator __position, list&& __x, iterator __i)
315 splice(iterator __position, list& __x, iterator __i)
318 // We used to perform the splice_alloc check: not anymore, redundant
319 // after implementing the relevant bits of N1599.
321 // _GLIBCXX_RESOLVE_LIB_DEFECTS
322 _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
326 #ifdef __GXX_EXPERIMENTAL_CXX0X__
328 splice(iterator __position, list& __x, iterator __i)
329 { this->splice(__position, std::move(__x), __i); }
333 #ifdef __GXX_EXPERIMENTAL_CXX0X__
334 splice(iterator __position, list&& __x, iterator __first,
337 splice(iterator __position, list& __x, iterator __first,
341 // We used to perform the splice_alloc check: not anymore, redundant
342 // after implementing the relevant bits of N1599.
344 _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
348 #ifdef __GXX_EXPERIMENTAL_CXX0X__
350 splice(iterator __position, list& __x, iterator __first, iterator __last)
351 { this->splice(__position, std::move(__x), __first, __last); }
355 remove(const _Tp& __value)
357 for (iterator __x = begin(); __x != _Base::end(); )
366 template<class _Predicate>
368 remove_if(_Predicate __pred)
370 for (iterator __x = begin(); __x != _Base::end(); )
382 iterator __first = begin();
383 iterator __last = end();
384 if (__first == __last)
386 iterator __next = __first;
387 while (++__next != __last)
389 if (*__first == *__next)
397 template<class _BinaryPredicate>
399 unique(_BinaryPredicate __binary_pred)
401 iterator __first = begin();
402 iterator __last = end();
403 if (__first == __last)
405 iterator __next = __first;
406 while (++__next != __last)
408 if (__binary_pred(*__first, *__next))
417 #ifdef __GXX_EXPERIMENTAL_CXX0X__
423 // _GLIBCXX_RESOLVE_LIB_DEFECTS
424 // 300. list::merge() specification incomplete
426 _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
429 #ifdef __GXX_EXPERIMENTAL_CXX0X__
432 { this->merge(std::move(__x)); }
435 template<class _Compare>
437 #ifdef __GXX_EXPERIMENTAL_CXX0X__
438 merge(list&& __x, _Compare __comp)
440 merge(list& __x, _Compare __comp)
443 // _GLIBCXX_RESOLVE_LIB_DEFECTS
444 // 300. list::merge() specification incomplete
446 _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
449 #ifdef __GXX_EXPERIMENTAL_CXX0X__
450 template<typename _Compare>
452 merge(list& __x, _Compare __comp)
453 { this->merge(std::move(__x), __comp); }
457 sort() { _Base::sort(); }
459 template<typename _StrictWeakOrdering>
461 sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
463 using _Base::reverse;
466 _M_base() { return *this; }
469 _M_base() const { return *this; }
473 template<typename _Tp, typename _Alloc>
475 operator==(const list<_Tp, _Alloc>& __lhs,
476 const list<_Tp, _Alloc>& __rhs)
477 { return __lhs._M_base() == __rhs._M_base(); }
479 template<typename _Tp, typename _Alloc>
481 operator!=(const list<_Tp, _Alloc>& __lhs,
482 const list<_Tp, _Alloc>& __rhs)
483 { return __lhs._M_base() != __rhs._M_base(); }
485 template<typename _Tp, typename _Alloc>
487 operator<(const list<_Tp, _Alloc>& __lhs,
488 const list<_Tp, _Alloc>& __rhs)
489 { return __lhs._M_base() < __rhs._M_base(); }
491 template<typename _Tp, typename _Alloc>
493 operator<=(const list<_Tp, _Alloc>& __lhs,
494 const list<_Tp, _Alloc>& __rhs)
495 { return __lhs._M_base() <= __rhs._M_base(); }
497 template<typename _Tp, typename _Alloc>
499 operator>=(const list<_Tp, _Alloc>& __lhs,
500 const list<_Tp, _Alloc>& __rhs)
501 { return __lhs._M_base() >= __rhs._M_base(); }
503 template<typename _Tp, typename _Alloc>
505 operator>(const list<_Tp, _Alloc>& __lhs,
506 const list<_Tp, _Alloc>& __rhs)
507 { return __lhs._M_base() > __rhs._M_base(); }
509 template<typename _Tp, typename _Alloc>
511 swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
512 { __lhs.swap(__rhs); }
514 } // namespace __profile