xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/debug/list (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino// Debugging list implementation -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4*e4b17023SJohn Marino// Free Software Foundation, Inc.
5*e4b17023SJohn Marino//
6*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library.  This library is free
7*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the
8*e4b17023SJohn Marino// terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino// any later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino// GNU General Public License for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional
18*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version
19*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation.
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and
22*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program;
23*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>.
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino/** @file debug/list
27*e4b17023SJohn Marino *  This file is a GNU debug extension to the Standard C++ Library.
28*e4b17023SJohn Marino */
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino#ifndef _GLIBCXX_DEBUG_LIST
31*e4b17023SJohn Marino#define _GLIBCXX_DEBUG_LIST 1
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino#include <list>
34*e4b17023SJohn Marino#include <debug/safe_sequence.h>
35*e4b17023SJohn Marino#include <debug/safe_iterator.h>
36*e4b17023SJohn Marino
37*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
38*e4b17023SJohn Marino{
39*e4b17023SJohn Marinonamespace __debug
40*e4b17023SJohn Marino{
41*e4b17023SJohn Marino  /// Class std::list with safety/checking/debug instrumentation.
42*e4b17023SJohn Marino  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
43*e4b17023SJohn Marino    class list
44*e4b17023SJohn Marino    : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
45*e4b17023SJohn Marino      public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
46*e4b17023SJohn Marino    {
47*e4b17023SJohn Marino      typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
48*e4b17023SJohn Marino
49*e4b17023SJohn Marino      typedef typename _Base::iterator       _Base_iterator;
50*e4b17023SJohn Marino      typedef typename _Base::const_iterator _Base_const_iterator;
51*e4b17023SJohn Marino      typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
52*e4b17023SJohn Marino      typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
53*e4b17023SJohn Marino    public:
54*e4b17023SJohn Marino      typedef typename _Base::reference             reference;
55*e4b17023SJohn Marino      typedef typename _Base::const_reference       const_reference;
56*e4b17023SJohn Marino
57*e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
58*e4b17023SJohn Marino						    iterator;
59*e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
60*e4b17023SJohn Marino						    const_iterator;
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino      typedef typename _Base::size_type             size_type;
63*e4b17023SJohn Marino      typedef typename _Base::difference_type       difference_type;
64*e4b17023SJohn Marino
65*e4b17023SJohn Marino      typedef _Tp				    value_type;
66*e4b17023SJohn Marino      typedef _Allocator			    allocator_type;
67*e4b17023SJohn Marino      typedef typename _Base::pointer               pointer;
68*e4b17023SJohn Marino      typedef typename _Base::const_pointer         const_pointer;
69*e4b17023SJohn Marino      typedef std::reverse_iterator<iterator>       reverse_iterator;
70*e4b17023SJohn Marino      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
71*e4b17023SJohn Marino
72*e4b17023SJohn Marino      // 23.2.2.1 construct/copy/destroy:
73*e4b17023SJohn Marino      explicit
74*e4b17023SJohn Marino      list(const _Allocator& __a = _Allocator())
75*e4b17023SJohn Marino      : _Base(__a) { }
76*e4b17023SJohn Marino
77*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
78*e4b17023SJohn Marino      explicit
79*e4b17023SJohn Marino      list(size_type __n)
80*e4b17023SJohn Marino      : _Base(__n) { }
81*e4b17023SJohn Marino
82*e4b17023SJohn Marino      list(size_type __n, const _Tp& __value,
83*e4b17023SJohn Marino	   const _Allocator& __a = _Allocator())
84*e4b17023SJohn Marino      : _Base(__n, __value, __a) { }
85*e4b17023SJohn Marino#else
86*e4b17023SJohn Marino      explicit
87*e4b17023SJohn Marino      list(size_type __n, const _Tp& __value = _Tp(),
88*e4b17023SJohn Marino	   const _Allocator& __a = _Allocator())
89*e4b17023SJohn Marino      : _Base(__n, __value, __a) { }
90*e4b17023SJohn Marino#endif
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino      template<class _InputIterator>
93*e4b17023SJohn Marino      list(_InputIterator __first, _InputIterator __last,
94*e4b17023SJohn Marino	   const _Allocator& __a = _Allocator())
95*e4b17023SJohn Marino      : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
96*e4b17023SJohn Marino								   __last)),
97*e4b17023SJohn Marino              __gnu_debug::__base(__last), __a)
98*e4b17023SJohn Marino      { }
99*e4b17023SJohn Marino
100*e4b17023SJohn Marino
101*e4b17023SJohn Marino      list(const list& __x)
102*e4b17023SJohn Marino      : _Base(__x) { }
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino      list(const _Base& __x)
105*e4b17023SJohn Marino      : _Base(__x) { }
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
108*e4b17023SJohn Marino      list(list&& __x) noexcept
109*e4b17023SJohn Marino      : _Base(std::move(__x))
110*e4b17023SJohn Marino      { this->_M_swap(__x); }
111*e4b17023SJohn Marino
112*e4b17023SJohn Marino      list(initializer_list<value_type> __l,
113*e4b17023SJohn Marino           const allocator_type& __a = allocator_type())
114*e4b17023SJohn Marino        : _Base(__l, __a) { }
115*e4b17023SJohn Marino#endif
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino      ~list() _GLIBCXX_NOEXCEPT { }
118*e4b17023SJohn Marino
119*e4b17023SJohn Marino      list&
120*e4b17023SJohn Marino      operator=(const list& __x)
121*e4b17023SJohn Marino      {
122*e4b17023SJohn Marino	static_cast<_Base&>(*this) = __x;
123*e4b17023SJohn Marino	this->_M_invalidate_all();
124*e4b17023SJohn Marino	return *this;
125*e4b17023SJohn Marino      }
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
128*e4b17023SJohn Marino      list&
129*e4b17023SJohn Marino      operator=(list&& __x)
130*e4b17023SJohn Marino      {
131*e4b17023SJohn Marino	// NB: DR 1204.
132*e4b17023SJohn Marino	// NB: DR 675.
133*e4b17023SJohn Marino	clear();
134*e4b17023SJohn Marino	swap(__x);
135*e4b17023SJohn Marino      	return *this;
136*e4b17023SJohn Marino      }
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino      list&
139*e4b17023SJohn Marino      operator=(initializer_list<value_type> __l)
140*e4b17023SJohn Marino      {
141*e4b17023SJohn Marino	static_cast<_Base&>(*this) = __l;
142*e4b17023SJohn Marino	this->_M_invalidate_all();
143*e4b17023SJohn Marino	return *this;
144*e4b17023SJohn Marino      }
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino      void
147*e4b17023SJohn Marino      assign(initializer_list<value_type> __l)
148*e4b17023SJohn Marino      {
149*e4b17023SJohn Marino	_Base::assign(__l);
150*e4b17023SJohn Marino	this->_M_invalidate_all();
151*e4b17023SJohn Marino      }
152*e4b17023SJohn Marino#endif
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino      template<class _InputIterator>
155*e4b17023SJohn Marino        void
156*e4b17023SJohn Marino        assign(_InputIterator __first, _InputIterator __last)
157*e4b17023SJohn Marino        {
158*e4b17023SJohn Marino	  __glibcxx_check_valid_range(__first, __last);
159*e4b17023SJohn Marino	  _Base::assign(__gnu_debug::__base(__first),
160*e4b17023SJohn Marino			__gnu_debug::__base(__last));
161*e4b17023SJohn Marino	  this->_M_invalidate_all();
162*e4b17023SJohn Marino	}
163*e4b17023SJohn Marino
164*e4b17023SJohn Marino      void
165*e4b17023SJohn Marino      assign(size_type __n, const _Tp& __t)
166*e4b17023SJohn Marino      {
167*e4b17023SJohn Marino	_Base::assign(__n, __t);
168*e4b17023SJohn Marino	this->_M_invalidate_all();
169*e4b17023SJohn Marino      }
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino      using _Base::get_allocator;
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino      // iterators:
174*e4b17023SJohn Marino      iterator
175*e4b17023SJohn Marino      begin() _GLIBCXX_NOEXCEPT
176*e4b17023SJohn Marino      { return iterator(_Base::begin(), this); }
177*e4b17023SJohn Marino
178*e4b17023SJohn Marino      const_iterator
179*e4b17023SJohn Marino      begin() const _GLIBCXX_NOEXCEPT
180*e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino      iterator
183*e4b17023SJohn Marino      end() _GLIBCXX_NOEXCEPT
184*e4b17023SJohn Marino      { return iterator(_Base::end(), this); }
185*e4b17023SJohn Marino
186*e4b17023SJohn Marino      const_iterator
187*e4b17023SJohn Marino      end() const _GLIBCXX_NOEXCEPT
188*e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
189*e4b17023SJohn Marino
190*e4b17023SJohn Marino      reverse_iterator
191*e4b17023SJohn Marino      rbegin() _GLIBCXX_NOEXCEPT
192*e4b17023SJohn Marino      { return reverse_iterator(end()); }
193*e4b17023SJohn Marino
194*e4b17023SJohn Marino      const_reverse_iterator
195*e4b17023SJohn Marino      rbegin() const _GLIBCXX_NOEXCEPT
196*e4b17023SJohn Marino      { return const_reverse_iterator(end()); }
197*e4b17023SJohn Marino
198*e4b17023SJohn Marino      reverse_iterator
199*e4b17023SJohn Marino      rend() _GLIBCXX_NOEXCEPT
200*e4b17023SJohn Marino      { return reverse_iterator(begin()); }
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino      const_reverse_iterator
203*e4b17023SJohn Marino      rend() const _GLIBCXX_NOEXCEPT
204*e4b17023SJohn Marino      { return const_reverse_iterator(begin()); }
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
207*e4b17023SJohn Marino      const_iterator
208*e4b17023SJohn Marino      cbegin() const noexcept
209*e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
210*e4b17023SJohn Marino
211*e4b17023SJohn Marino      const_iterator
212*e4b17023SJohn Marino      cend() const noexcept
213*e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
214*e4b17023SJohn Marino
215*e4b17023SJohn Marino      const_reverse_iterator
216*e4b17023SJohn Marino      crbegin() const noexcept
217*e4b17023SJohn Marino      { return const_reverse_iterator(end()); }
218*e4b17023SJohn Marino
219*e4b17023SJohn Marino      const_reverse_iterator
220*e4b17023SJohn Marino      crend() const noexcept
221*e4b17023SJohn Marino      { return const_reverse_iterator(begin()); }
222*e4b17023SJohn Marino#endif
223*e4b17023SJohn Marino
224*e4b17023SJohn Marino      // 23.2.2.2 capacity:
225*e4b17023SJohn Marino      using _Base::empty;
226*e4b17023SJohn Marino      using _Base::size;
227*e4b17023SJohn Marino      using _Base::max_size;
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
230*e4b17023SJohn Marino      void
231*e4b17023SJohn Marino      resize(size_type __sz)
232*e4b17023SJohn Marino      {
233*e4b17023SJohn Marino	this->_M_detach_singular();
234*e4b17023SJohn Marino
235*e4b17023SJohn Marino	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
236*e4b17023SJohn Marino	_Base_iterator __victim = _Base::begin();
237*e4b17023SJohn Marino	_Base_iterator __end = _Base::end();
238*e4b17023SJohn Marino	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
239*e4b17023SJohn Marino	  ++__victim;
240*e4b17023SJohn Marino
241*e4b17023SJohn Marino	for (; __victim != __end; ++__victim)
242*e4b17023SJohn Marino	  {
243*e4b17023SJohn Marino	    this->_M_invalidate_if(_Equal(__victim));
244*e4b17023SJohn Marino	  }
245*e4b17023SJohn Marino
246*e4b17023SJohn Marino	__try
247*e4b17023SJohn Marino	  {
248*e4b17023SJohn Marino	    _Base::resize(__sz);
249*e4b17023SJohn Marino	  }
250*e4b17023SJohn Marino	__catch(...)
251*e4b17023SJohn Marino	  {
252*e4b17023SJohn Marino	    this->_M_revalidate_singular();
253*e4b17023SJohn Marino	    __throw_exception_again;
254*e4b17023SJohn Marino	  }
255*e4b17023SJohn Marino      }
256*e4b17023SJohn Marino
257*e4b17023SJohn Marino      void
258*e4b17023SJohn Marino      resize(size_type __sz, const _Tp& __c)
259*e4b17023SJohn Marino      {
260*e4b17023SJohn Marino	this->_M_detach_singular();
261*e4b17023SJohn Marino
262*e4b17023SJohn Marino	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
263*e4b17023SJohn Marino	_Base_iterator __victim = _Base::begin();
264*e4b17023SJohn Marino	_Base_iterator __end = _Base::end();
265*e4b17023SJohn Marino	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
266*e4b17023SJohn Marino	  ++__victim;
267*e4b17023SJohn Marino
268*e4b17023SJohn Marino	for (; __victim != __end; ++__victim)
269*e4b17023SJohn Marino	  {
270*e4b17023SJohn Marino	    this->_M_invalidate_if(_Equal(__victim));
271*e4b17023SJohn Marino	  }
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino	__try
274*e4b17023SJohn Marino	  {
275*e4b17023SJohn Marino	    _Base::resize(__sz, __c);
276*e4b17023SJohn Marino	  }
277*e4b17023SJohn Marino	__catch(...)
278*e4b17023SJohn Marino	  {
279*e4b17023SJohn Marino	    this->_M_revalidate_singular();
280*e4b17023SJohn Marino	    __throw_exception_again;
281*e4b17023SJohn Marino	  }
282*e4b17023SJohn Marino      }
283*e4b17023SJohn Marino#else
284*e4b17023SJohn Marino      void
285*e4b17023SJohn Marino      resize(size_type __sz, _Tp __c = _Tp())
286*e4b17023SJohn Marino      {
287*e4b17023SJohn Marino	this->_M_detach_singular();
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
290*e4b17023SJohn Marino	_Base_iterator __victim = _Base::begin();
291*e4b17023SJohn Marino	_Base_iterator __end = _Base::end();
292*e4b17023SJohn Marino	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
293*e4b17023SJohn Marino	  ++__victim;
294*e4b17023SJohn Marino
295*e4b17023SJohn Marino	for (; __victim != __end; ++__victim)
296*e4b17023SJohn Marino	  {
297*e4b17023SJohn Marino	    this->_M_invalidate_if(_Equal(__victim));
298*e4b17023SJohn Marino	  }
299*e4b17023SJohn Marino
300*e4b17023SJohn Marino	__try
301*e4b17023SJohn Marino	  {
302*e4b17023SJohn Marino	    _Base::resize(__sz, __c);
303*e4b17023SJohn Marino	  }
304*e4b17023SJohn Marino	__catch(...)
305*e4b17023SJohn Marino	  {
306*e4b17023SJohn Marino	    this->_M_revalidate_singular();
307*e4b17023SJohn Marino	    __throw_exception_again;
308*e4b17023SJohn Marino	  }
309*e4b17023SJohn Marino      }
310*e4b17023SJohn Marino#endif
311*e4b17023SJohn Marino
312*e4b17023SJohn Marino      // element access:
313*e4b17023SJohn Marino      reference
314*e4b17023SJohn Marino      front()
315*e4b17023SJohn Marino      {
316*e4b17023SJohn Marino	__glibcxx_check_nonempty();
317*e4b17023SJohn Marino	return _Base::front();
318*e4b17023SJohn Marino      }
319*e4b17023SJohn Marino
320*e4b17023SJohn Marino      const_reference
321*e4b17023SJohn Marino      front() const
322*e4b17023SJohn Marino      {
323*e4b17023SJohn Marino	__glibcxx_check_nonempty();
324*e4b17023SJohn Marino	return _Base::front();
325*e4b17023SJohn Marino      }
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino      reference
328*e4b17023SJohn Marino      back()
329*e4b17023SJohn Marino      {
330*e4b17023SJohn Marino	__glibcxx_check_nonempty();
331*e4b17023SJohn Marino	return _Base::back();
332*e4b17023SJohn Marino      }
333*e4b17023SJohn Marino
334*e4b17023SJohn Marino      const_reference
335*e4b17023SJohn Marino      back() const
336*e4b17023SJohn Marino      {
337*e4b17023SJohn Marino	__glibcxx_check_nonempty();
338*e4b17023SJohn Marino	return _Base::back();
339*e4b17023SJohn Marino      }
340*e4b17023SJohn Marino
341*e4b17023SJohn Marino      // 23.2.2.3 modifiers:
342*e4b17023SJohn Marino      using _Base::push_front;
343*e4b17023SJohn Marino
344*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
345*e4b17023SJohn Marino      using _Base::emplace_front;
346*e4b17023SJohn Marino#endif
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino      void
349*e4b17023SJohn Marino      pop_front()
350*e4b17023SJohn Marino      {
351*e4b17023SJohn Marino	__glibcxx_check_nonempty();
352*e4b17023SJohn Marino	this->_M_invalidate_if(_Equal(_Base::begin()));
353*e4b17023SJohn Marino	_Base::pop_front();
354*e4b17023SJohn Marino      }
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino      using _Base::push_back;
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
359*e4b17023SJohn Marino      using _Base::emplace_back;
360*e4b17023SJohn Marino#endif
361*e4b17023SJohn Marino
362*e4b17023SJohn Marino      void
363*e4b17023SJohn Marino      pop_back()
364*e4b17023SJohn Marino      {
365*e4b17023SJohn Marino	__glibcxx_check_nonempty();
366*e4b17023SJohn Marino	this->_M_invalidate_if(_Equal(--_Base::end()));
367*e4b17023SJohn Marino	_Base::pop_back();
368*e4b17023SJohn Marino      }
369*e4b17023SJohn Marino
370*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
371*e4b17023SJohn Marino      template<typename... _Args>
372*e4b17023SJohn Marino        iterator
373*e4b17023SJohn Marino        emplace(iterator __position, _Args&&... __args)
374*e4b17023SJohn Marino	{
375*e4b17023SJohn Marino	  __glibcxx_check_insert(__position);
376*e4b17023SJohn Marino	  return iterator(_Base::emplace(__position.base(),
377*e4b17023SJohn Marino					std::forward<_Args>(__args)...), this);
378*e4b17023SJohn Marino	}
379*e4b17023SJohn Marino#endif
380*e4b17023SJohn Marino
381*e4b17023SJohn Marino      iterator
382*e4b17023SJohn Marino      insert(iterator __position, const _Tp& __x)
383*e4b17023SJohn Marino      {
384*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
385*e4b17023SJohn Marino	return iterator(_Base::insert(__position.base(), __x), this);
386*e4b17023SJohn Marino      }
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
389*e4b17023SJohn Marino      iterator
390*e4b17023SJohn Marino      insert(iterator __position, _Tp&& __x)
391*e4b17023SJohn Marino      { return emplace(__position, std::move(__x)); }
392*e4b17023SJohn Marino
393*e4b17023SJohn Marino      void
394*e4b17023SJohn Marino      insert(iterator __p, initializer_list<value_type> __l)
395*e4b17023SJohn Marino      {
396*e4b17023SJohn Marino	__glibcxx_check_insert(__p);
397*e4b17023SJohn Marino	_Base::insert(__p.base(), __l);
398*e4b17023SJohn Marino      }
399*e4b17023SJohn Marino#endif
400*e4b17023SJohn Marino
401*e4b17023SJohn Marino      void
402*e4b17023SJohn Marino      insert(iterator __position, size_type __n, const _Tp& __x)
403*e4b17023SJohn Marino      {
404*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
405*e4b17023SJohn Marino	_Base::insert(__position.base(), __n, __x);
406*e4b17023SJohn Marino      }
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino      template<class _InputIterator>
409*e4b17023SJohn Marino        void
410*e4b17023SJohn Marino        insert(iterator __position, _InputIterator __first,
411*e4b17023SJohn Marino	       _InputIterator __last)
412*e4b17023SJohn Marino        {
413*e4b17023SJohn Marino	  __glibcxx_check_insert_range(__position, __first, __last);
414*e4b17023SJohn Marino	  _Base::insert(__position.base(), __gnu_debug::__base(__first),
415*e4b17023SJohn Marino					   __gnu_debug::__base(__last));
416*e4b17023SJohn Marino	}
417*e4b17023SJohn Marino
418*e4b17023SJohn Marino    private:
419*e4b17023SJohn Marino      _Base_iterator
420*e4b17023SJohn Marino      _M_erase(_Base_iterator __position)
421*e4b17023SJohn Marino      {
422*e4b17023SJohn Marino	this->_M_invalidate_if(_Equal(__position));
423*e4b17023SJohn Marino	return _Base::erase(__position);
424*e4b17023SJohn Marino      }
425*e4b17023SJohn Marino    public:
426*e4b17023SJohn Marino      iterator
427*e4b17023SJohn Marino      erase(iterator __position)
428*e4b17023SJohn Marino      {
429*e4b17023SJohn Marino	__glibcxx_check_erase(__position);
430*e4b17023SJohn Marino	return iterator(_M_erase(__position.base()), this);
431*e4b17023SJohn Marino      }
432*e4b17023SJohn Marino
433*e4b17023SJohn Marino      iterator
434*e4b17023SJohn Marino      erase(iterator __position, iterator __last)
435*e4b17023SJohn Marino      {
436*e4b17023SJohn Marino	// _GLIBCXX_RESOLVE_LIB_DEFECTS
437*e4b17023SJohn Marino	// 151. can't currently clear() empty container
438*e4b17023SJohn Marino	__glibcxx_check_erase_range(__position, __last);
439*e4b17023SJohn Marino	for (_Base_iterator __victim = __position.base();
440*e4b17023SJohn Marino	     __victim != __last.base(); ++__victim)
441*e4b17023SJohn Marino	  {
442*e4b17023SJohn Marino	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
443*e4b17023SJohn Marino			          _M_message(__gnu_debug::__msg_valid_range)
444*e4b17023SJohn Marino				  ._M_iterator(__position, "position")
445*e4b17023SJohn Marino				  ._M_iterator(__last, "last"));
446*e4b17023SJohn Marino	    this->_M_invalidate_if(_Equal(__victim));
447*e4b17023SJohn Marino	  }
448*e4b17023SJohn Marino	return iterator(_Base::erase(__position.base(), __last.base()), this);
449*e4b17023SJohn Marino      }
450*e4b17023SJohn Marino
451*e4b17023SJohn Marino      void
452*e4b17023SJohn Marino      swap(list& __x)
453*e4b17023SJohn Marino      {
454*e4b17023SJohn Marino	_Base::swap(__x);
455*e4b17023SJohn Marino	this->_M_swap(__x);
456*e4b17023SJohn Marino      }
457*e4b17023SJohn Marino
458*e4b17023SJohn Marino      void
459*e4b17023SJohn Marino      clear() _GLIBCXX_NOEXCEPT
460*e4b17023SJohn Marino      {
461*e4b17023SJohn Marino	_Base::clear();
462*e4b17023SJohn Marino	this->_M_invalidate_all();
463*e4b17023SJohn Marino      }
464*e4b17023SJohn Marino
465*e4b17023SJohn Marino      // 23.2.2.4 list operations:
466*e4b17023SJohn Marino      void
467*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
468*e4b17023SJohn Marino      splice(iterator __position, list&& __x)
469*e4b17023SJohn Marino#else
470*e4b17023SJohn Marino      splice(iterator __position, list& __x)
471*e4b17023SJohn Marino#endif
472*e4b17023SJohn Marino      {
473*e4b17023SJohn Marino	_GLIBCXX_DEBUG_VERIFY(&__x != this,
474*e4b17023SJohn Marino			      _M_message(__gnu_debug::__msg_self_splice)
475*e4b17023SJohn Marino			      ._M_sequence(*this, "this"));
476*e4b17023SJohn Marino	this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
477*e4b17023SJohn Marino	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
478*e4b17023SJohn Marino      }
479*e4b17023SJohn Marino
480*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
481*e4b17023SJohn Marino      void
482*e4b17023SJohn Marino      splice(iterator __position, list& __x)
483*e4b17023SJohn Marino      { splice(__position, std::move(__x)); }
484*e4b17023SJohn Marino#endif
485*e4b17023SJohn Marino
486*e4b17023SJohn Marino      void
487*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
488*e4b17023SJohn Marino      splice(iterator __position, list&& __x, iterator __i)
489*e4b17023SJohn Marino#else
490*e4b17023SJohn Marino      splice(iterator __position, list& __x, iterator __i)
491*e4b17023SJohn Marino#endif
492*e4b17023SJohn Marino      {
493*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
494*e4b17023SJohn Marino
495*e4b17023SJohn Marino	// We used to perform the splice_alloc check:  not anymore, redundant
496*e4b17023SJohn Marino	// after implementing the relevant bits of N1599.
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino	_GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
499*e4b17023SJohn Marino			      _M_message(__gnu_debug::__msg_splice_bad)
500*e4b17023SJohn Marino			      ._M_iterator(__i, "__i"));
501*e4b17023SJohn Marino	_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
502*e4b17023SJohn Marino			      _M_message(__gnu_debug::__msg_splice_other)
503*e4b17023SJohn Marino			     ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
504*e4b17023SJohn Marino
505*e4b17023SJohn Marino	// _GLIBCXX_RESOLVE_LIB_DEFECTS
506*e4b17023SJohn Marino	// 250. splicing invalidates iterators
507*e4b17023SJohn Marino	this->_M_transfer_from_if(__x, _Equal(__i.base()));
508*e4b17023SJohn Marino	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
509*e4b17023SJohn Marino		      __i.base());
510*e4b17023SJohn Marino      }
511*e4b17023SJohn Marino
512*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
513*e4b17023SJohn Marino      void
514*e4b17023SJohn Marino      splice(iterator __position, list& __x, iterator __i)
515*e4b17023SJohn Marino      { splice(__position, std::move(__x), __i); }
516*e4b17023SJohn Marino#endif
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino      void
519*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
520*e4b17023SJohn Marino      splice(iterator __position, list&& __x, iterator __first,
521*e4b17023SJohn Marino	     iterator __last)
522*e4b17023SJohn Marino#else
523*e4b17023SJohn Marino      splice(iterator __position, list& __x, iterator __first,
524*e4b17023SJohn Marino	     iterator __last)
525*e4b17023SJohn Marino#endif
526*e4b17023SJohn Marino      {
527*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
528*e4b17023SJohn Marino	__glibcxx_check_valid_range(__first, __last);
529*e4b17023SJohn Marino	_GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
530*e4b17023SJohn Marino			      _M_message(__gnu_debug::__msg_splice_other)
531*e4b17023SJohn Marino			      ._M_sequence(__x, "x")
532*e4b17023SJohn Marino			      ._M_iterator(__first, "first"));
533*e4b17023SJohn Marino
534*e4b17023SJohn Marino	// We used to perform the splice_alloc check:  not anymore, redundant
535*e4b17023SJohn Marino	// after implementing the relevant bits of N1599.
536*e4b17023SJohn Marino
537*e4b17023SJohn Marino	for (_Base_iterator __tmp = __first.base();
538*e4b17023SJohn Marino	     __tmp != __last.base(); ++__tmp)
539*e4b17023SJohn Marino	  {
540*e4b17023SJohn Marino	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
541*e4b17023SJohn Marino				  _M_message(__gnu_debug::__msg_valid_range)
542*e4b17023SJohn Marino				  ._M_iterator(__first, "first")
543*e4b17023SJohn Marino				  ._M_iterator(__last, "last"));
544*e4b17023SJohn Marino	    _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
545*e4b17023SJohn Marino				_M_message(__gnu_debug::__msg_splice_overlap)
546*e4b17023SJohn Marino				  ._M_iterator(__tmp, "position")
547*e4b17023SJohn Marino				  ._M_iterator(__first, "first")
548*e4b17023SJohn Marino				  ._M_iterator(__last, "last"));
549*e4b17023SJohn Marino	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
550*e4b17023SJohn Marino	    // 250. splicing invalidates iterators
551*e4b17023SJohn Marino	    this->_M_transfer_from_if(__x, _Equal(__tmp));
552*e4b17023SJohn Marino	  }
553*e4b17023SJohn Marino
554*e4b17023SJohn Marino	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
555*e4b17023SJohn Marino		      __first.base(), __last.base());
556*e4b17023SJohn Marino      }
557*e4b17023SJohn Marino
558*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
559*e4b17023SJohn Marino      void
560*e4b17023SJohn Marino      splice(iterator __position, list& __x, iterator __first, iterator __last)
561*e4b17023SJohn Marino      { splice(__position, std::move(__x), __first, __last); }
562*e4b17023SJohn Marino#endif
563*e4b17023SJohn Marino
564*e4b17023SJohn Marino      void
565*e4b17023SJohn Marino      remove(const _Tp& __value)
566*e4b17023SJohn Marino      {
567*e4b17023SJohn Marino	for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
568*e4b17023SJohn Marino	  {
569*e4b17023SJohn Marino	    if (*__x == __value)
570*e4b17023SJohn Marino	      __x = _M_erase(__x);
571*e4b17023SJohn Marino	    else
572*e4b17023SJohn Marino	      ++__x;
573*e4b17023SJohn Marino	  }
574*e4b17023SJohn Marino      }
575*e4b17023SJohn Marino
576*e4b17023SJohn Marino      template<class _Predicate>
577*e4b17023SJohn Marino        void
578*e4b17023SJohn Marino        remove_if(_Predicate __pred)
579*e4b17023SJohn Marino        {
580*e4b17023SJohn Marino	  for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
581*e4b17023SJohn Marino	    {
582*e4b17023SJohn Marino	      if (__pred(*__x))
583*e4b17023SJohn Marino		__x = _M_erase(__x);
584*e4b17023SJohn Marino	      else
585*e4b17023SJohn Marino		++__x;
586*e4b17023SJohn Marino	    }
587*e4b17023SJohn Marino	}
588*e4b17023SJohn Marino
589*e4b17023SJohn Marino      void
590*e4b17023SJohn Marino      unique()
591*e4b17023SJohn Marino      {
592*e4b17023SJohn Marino	_Base_iterator __first = _Base::begin();
593*e4b17023SJohn Marino	_Base_iterator __last = _Base::end();
594*e4b17023SJohn Marino	if (__first == __last)
595*e4b17023SJohn Marino	  return;
596*e4b17023SJohn Marino	_Base_iterator __next = __first; ++__next;
597*e4b17023SJohn Marino	while (__next != __last)
598*e4b17023SJohn Marino	  {
599*e4b17023SJohn Marino	    if (*__first == *__next)
600*e4b17023SJohn Marino	      __next = _M_erase(__next);
601*e4b17023SJohn Marino	    else
602*e4b17023SJohn Marino	      __first = __next++;
603*e4b17023SJohn Marino	  }
604*e4b17023SJohn Marino      }
605*e4b17023SJohn Marino
606*e4b17023SJohn Marino      template<class _BinaryPredicate>
607*e4b17023SJohn Marino        void
608*e4b17023SJohn Marino        unique(_BinaryPredicate __binary_pred)
609*e4b17023SJohn Marino        {
610*e4b17023SJohn Marino	  _Base_iterator __first = _Base::begin();
611*e4b17023SJohn Marino	  _Base_iterator __last = _Base::end();
612*e4b17023SJohn Marino	  if (__first == __last)
613*e4b17023SJohn Marino	    return;
614*e4b17023SJohn Marino	  _Base_iterator __next = __first; ++__next;
615*e4b17023SJohn Marino	  while (__next != __last)
616*e4b17023SJohn Marino	    {
617*e4b17023SJohn Marino	      if (__binary_pred(*__first, *__next))
618*e4b17023SJohn Marino		__next = _M_erase(__next);
619*e4b17023SJohn Marino	      else
620*e4b17023SJohn Marino		__first = __next++;
621*e4b17023SJohn Marino	    }
622*e4b17023SJohn Marino	}
623*e4b17023SJohn Marino
624*e4b17023SJohn Marino      void
625*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
626*e4b17023SJohn Marino      merge(list&& __x)
627*e4b17023SJohn Marino#else
628*e4b17023SJohn Marino      merge(list& __x)
629*e4b17023SJohn Marino#endif
630*e4b17023SJohn Marino      {
631*e4b17023SJohn Marino	// _GLIBCXX_RESOLVE_LIB_DEFECTS
632*e4b17023SJohn Marino	// 300. list::merge() specification incomplete
633*e4b17023SJohn Marino	if (this != &__x)
634*e4b17023SJohn Marino	  {
635*e4b17023SJohn Marino	    __glibcxx_check_sorted(_Base::begin(), _Base::end());
636*e4b17023SJohn Marino	    __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
637*e4b17023SJohn Marino	    this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
638*e4b17023SJohn Marino	    _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
639*e4b17023SJohn Marino	  }
640*e4b17023SJohn Marino      }
641*e4b17023SJohn Marino
642*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
643*e4b17023SJohn Marino      void
644*e4b17023SJohn Marino      merge(list& __x)
645*e4b17023SJohn Marino      { merge(std::move(__x)); }
646*e4b17023SJohn Marino#endif
647*e4b17023SJohn Marino
648*e4b17023SJohn Marino      template<class _Compare>
649*e4b17023SJohn Marino        void
650*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
651*e4b17023SJohn Marino        merge(list&& __x, _Compare __comp)
652*e4b17023SJohn Marino#else
653*e4b17023SJohn Marino        merge(list& __x, _Compare __comp)
654*e4b17023SJohn Marino#endif
655*e4b17023SJohn Marino        {
656*e4b17023SJohn Marino	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
657*e4b17023SJohn Marino	  // 300. list::merge() specification incomplete
658*e4b17023SJohn Marino	  if (this != &__x)
659*e4b17023SJohn Marino	    {
660*e4b17023SJohn Marino	      __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
661*e4b17023SJohn Marino					  __comp);
662*e4b17023SJohn Marino	      __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
663*e4b17023SJohn Marino					  __comp);
664*e4b17023SJohn Marino	      this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
665*e4b17023SJohn Marino	      _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
666*e4b17023SJohn Marino	    }
667*e4b17023SJohn Marino	}
668*e4b17023SJohn Marino
669*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
670*e4b17023SJohn Marino      template<typename _Compare>
671*e4b17023SJohn Marino        void
672*e4b17023SJohn Marino        merge(list& __x, _Compare __comp)
673*e4b17023SJohn Marino        { merge(std::move(__x), __comp); }
674*e4b17023SJohn Marino#endif
675*e4b17023SJohn Marino
676*e4b17023SJohn Marino      void
677*e4b17023SJohn Marino      sort() { _Base::sort(); }
678*e4b17023SJohn Marino
679*e4b17023SJohn Marino      template<typename _StrictWeakOrdering>
680*e4b17023SJohn Marino        void
681*e4b17023SJohn Marino        sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
682*e4b17023SJohn Marino
683*e4b17023SJohn Marino      using _Base::reverse;
684*e4b17023SJohn Marino
685*e4b17023SJohn Marino      _Base&
686*e4b17023SJohn Marino      _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
687*e4b17023SJohn Marino
688*e4b17023SJohn Marino      const _Base&
689*e4b17023SJohn Marino      _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
690*e4b17023SJohn Marino
691*e4b17023SJohn Marino    private:
692*e4b17023SJohn Marino      void
693*e4b17023SJohn Marino      _M_invalidate_all()
694*e4b17023SJohn Marino      {
695*e4b17023SJohn Marino	this->_M_invalidate_if(_Not_equal(_Base::end()));
696*e4b17023SJohn Marino      }
697*e4b17023SJohn Marino    };
698*e4b17023SJohn Marino
699*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
700*e4b17023SJohn Marino    inline bool
701*e4b17023SJohn Marino    operator==(const list<_Tp, _Alloc>& __lhs,
702*e4b17023SJohn Marino	       const list<_Tp, _Alloc>& __rhs)
703*e4b17023SJohn Marino    { return __lhs._M_base() == __rhs._M_base(); }
704*e4b17023SJohn Marino
705*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
706*e4b17023SJohn Marino    inline bool
707*e4b17023SJohn Marino    operator!=(const list<_Tp, _Alloc>& __lhs,
708*e4b17023SJohn Marino	       const list<_Tp, _Alloc>& __rhs)
709*e4b17023SJohn Marino    { return __lhs._M_base() != __rhs._M_base(); }
710*e4b17023SJohn Marino
711*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
712*e4b17023SJohn Marino    inline bool
713*e4b17023SJohn Marino    operator<(const list<_Tp, _Alloc>& __lhs,
714*e4b17023SJohn Marino	      const list<_Tp, _Alloc>& __rhs)
715*e4b17023SJohn Marino    { return __lhs._M_base() < __rhs._M_base(); }
716*e4b17023SJohn Marino
717*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
718*e4b17023SJohn Marino    inline bool
719*e4b17023SJohn Marino    operator<=(const list<_Tp, _Alloc>& __lhs,
720*e4b17023SJohn Marino	       const list<_Tp, _Alloc>& __rhs)
721*e4b17023SJohn Marino    { return __lhs._M_base() <= __rhs._M_base(); }
722*e4b17023SJohn Marino
723*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
724*e4b17023SJohn Marino    inline bool
725*e4b17023SJohn Marino    operator>=(const list<_Tp, _Alloc>& __lhs,
726*e4b17023SJohn Marino	       const list<_Tp, _Alloc>& __rhs)
727*e4b17023SJohn Marino    { return __lhs._M_base() >= __rhs._M_base(); }
728*e4b17023SJohn Marino
729*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
730*e4b17023SJohn Marino    inline bool
731*e4b17023SJohn Marino    operator>(const list<_Tp, _Alloc>& __lhs,
732*e4b17023SJohn Marino	      const list<_Tp, _Alloc>& __rhs)
733*e4b17023SJohn Marino    { return __lhs._M_base() > __rhs._M_base(); }
734*e4b17023SJohn Marino
735*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
736*e4b17023SJohn Marino    inline void
737*e4b17023SJohn Marino    swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
738*e4b17023SJohn Marino    { __lhs.swap(__rhs); }
739*e4b17023SJohn Marino
740*e4b17023SJohn Marino} // namespace __debug
741*e4b17023SJohn Marino} // namespace std
742*e4b17023SJohn Marino
743*e4b17023SJohn Marino#endif
744