1ffeaf689SAlexander Kabaev// Debugging list implementation -*- C++ -*-
2ffeaf689SAlexander Kabaev
3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2003, 2004, 2005, 2006
4ffeaf689SAlexander Kabaev// Free Software Foundation, Inc.
5ffeaf689SAlexander Kabaev//
6ffeaf689SAlexander Kabaev// This file is part of the GNU ISO C++ Library.  This library is free
7ffeaf689SAlexander Kabaev// software; you can redistribute it and/or modify it under the
8ffeaf689SAlexander Kabaev// terms of the GNU General Public License as published by the
9ffeaf689SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option)
10ffeaf689SAlexander Kabaev// any later version.
11ffeaf689SAlexander Kabaev
12ffeaf689SAlexander Kabaev// This library is distributed in the hope that it will be useful,
13ffeaf689SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of
14ffeaf689SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15ffeaf689SAlexander Kabaev// GNU General Public License for more details.
16ffeaf689SAlexander Kabaev
17ffeaf689SAlexander Kabaev// You should have received a copy of the GNU General Public License along
18ffeaf689SAlexander Kabaev// with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20ffeaf689SAlexander Kabaev// USA.
21ffeaf689SAlexander Kabaev
22ffeaf689SAlexander Kabaev// As a special exception, you may use this file as part of a free software
23ffeaf689SAlexander Kabaev// library without restriction.  Specifically, if other files instantiate
24ffeaf689SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile
25ffeaf689SAlexander Kabaev// this file and link it with other files to produce an executable, this
26ffeaf689SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by
27ffeaf689SAlexander Kabaev// the GNU General Public License.  This exception does not however
28ffeaf689SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by
29ffeaf689SAlexander Kabaev// the GNU General Public License.
30ffeaf689SAlexander Kabaev
31*f8a1b7d9SAlexander Kabaev// Free Software Foundation, Inc.
32*f8a1b7d9SAlexander Kabaev//
33*f8a1b7d9SAlexander Kabaev// This file is part of the GNU ISO C++ Library.  This library is free
34*f8a1b7d9SAlexander Kabaev// software; you can redistribute it and/or modify it under the
35*f8a1b7d9SAlexander Kabaev// terms of the GNU General Public License as published by the
36*f8a1b7d9SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option)
37*f8a1b7d9SAlexander Kabaev// any later version.
38*f8a1b7d9SAlexander Kabaev
39*f8a1b7d9SAlexander Kabaev// This library is distributed in the hope that it will be useful,
40*f8a1b7d9SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of
41*f8a1b7d9SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42*f8a1b7d9SAlexander Kabaev// GNU General Public License for more details.
43*f8a1b7d9SAlexander Kabaev
44*f8a1b7d9SAlexander Kabaev// You should have received a copy of the GNU General Public License along
45*f8a1b7d9SAlexander Kabaev// with this library; see the file COPYING.  If not, write to the Free
46*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
47*f8a1b7d9SAlexander Kabaev// USA.
48*f8a1b7d9SAlexander Kabaev
49*f8a1b7d9SAlexander Kabaev// As a special exception, you may use this file as part of a free software
50*f8a1b7d9SAlexander Kabaev// library without restriction.  Specifically, if other files instantiate
51*f8a1b7d9SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile
52*f8a1b7d9SAlexander Kabaev// this file and link it with other files to produce an executable, this
53*f8a1b7d9SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by
54*f8a1b7d9SAlexander Kabaev// the GNU General Public License.  This exception does not however
55*f8a1b7d9SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by
56*f8a1b7d9SAlexander Kabaev// the GNU General Public License.
57*f8a1b7d9SAlexander Kabaev
58*f8a1b7d9SAlexander Kabaev/** @file debug/list
59*f8a1b7d9SAlexander Kabaev *  This file is a GNU debug extension to the Standard C++ Library.
60*f8a1b7d9SAlexander Kabaev */
61*f8a1b7d9SAlexander Kabaev
62ffeaf689SAlexander Kabaev#ifndef _GLIBCXX_DEBUG_LIST
63ffeaf689SAlexander Kabaev#define _GLIBCXX_DEBUG_LIST 1
64ffeaf689SAlexander Kabaev
65ffeaf689SAlexander Kabaev#include <list>
66ffeaf689SAlexander Kabaev#include <bits/stl_algo.h>
67ffeaf689SAlexander Kabaev#include <debug/safe_sequence.h>
68ffeaf689SAlexander Kabaev#include <debug/safe_iterator.h>
69ffeaf689SAlexander Kabaev
70*f8a1b7d9SAlexander Kabaevnamespace std
71*f8a1b7d9SAlexander Kabaev{
72*f8a1b7d9SAlexander Kabaevnamespace __debug
73ffeaf689SAlexander Kabaev{
74ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
75ffeaf689SAlexander Kabaev    class list
76ffeaf689SAlexander Kabaev    : public _GLIBCXX_STD::list<_Tp, _Allocator>,
77ffeaf689SAlexander Kabaev      public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
78ffeaf689SAlexander Kabaev    {
79ffeaf689SAlexander Kabaev      typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base;
80ffeaf689SAlexander Kabaev      typedef __gnu_debug::_Safe_sequence<list>  _Safe_base;
81ffeaf689SAlexander Kabaev
82ffeaf689SAlexander Kabaev    public:
83*f8a1b7d9SAlexander Kabaev      typedef typename _Base::reference             reference;
84*f8a1b7d9SAlexander Kabaev      typedef typename _Base::const_reference       const_reference;
85ffeaf689SAlexander Kabaev
86ffeaf689SAlexander Kabaev      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list>
87ffeaf689SAlexander Kabaev						    iterator;
88ffeaf689SAlexander Kabaev      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list>
89ffeaf689SAlexander Kabaev						    const_iterator;
90ffeaf689SAlexander Kabaev
91ffeaf689SAlexander Kabaev      typedef typename _Base::size_type             size_type;
92ffeaf689SAlexander Kabaev      typedef typename _Base::difference_type       difference_type;
93ffeaf689SAlexander Kabaev
94ffeaf689SAlexander Kabaev      typedef _Tp				    value_type;
95ffeaf689SAlexander Kabaev      typedef _Allocator			    allocator_type;
96*f8a1b7d9SAlexander Kabaev      typedef typename _Base::pointer               pointer;
97*f8a1b7d9SAlexander Kabaev      typedef typename _Base::const_pointer         const_pointer;
98ffeaf689SAlexander Kabaev      typedef std::reverse_iterator<iterator>       reverse_iterator;
99ffeaf689SAlexander Kabaev      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
100ffeaf689SAlexander Kabaev
101ffeaf689SAlexander Kabaev      // 23.2.2.1 construct/copy/destroy:
102ffeaf689SAlexander Kabaev      explicit list(const _Allocator& __a = _Allocator())
103ffeaf689SAlexander Kabaev      : _Base(__a) { }
104ffeaf689SAlexander Kabaev
105ffeaf689SAlexander Kabaev      explicit list(size_type __n, const _Tp& __value = _Tp(),
106ffeaf689SAlexander Kabaev		    const _Allocator& __a = _Allocator())
107ffeaf689SAlexander Kabaev      : _Base(__n, __value, __a) { }
108ffeaf689SAlexander Kabaev
109ffeaf689SAlexander Kabaev      template<class _InputIterator>
110ffeaf689SAlexander Kabaev      list(_InputIterator __first, _InputIterator __last,
111ffeaf689SAlexander Kabaev	   const _Allocator& __a = _Allocator())
112ffeaf689SAlexander Kabaev      : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
113ffeaf689SAlexander Kabaev      { }
114ffeaf689SAlexander Kabaev
115ffeaf689SAlexander Kabaev
116ffeaf689SAlexander Kabaev      list(const list& __x) : _Base(__x), _Safe_base() { }
117ffeaf689SAlexander Kabaev
118ffeaf689SAlexander Kabaev      list(const _Base& __x) : _Base(__x), _Safe_base() { }
119ffeaf689SAlexander Kabaev
120ffeaf689SAlexander Kabaev      ~list() { }
121ffeaf689SAlexander Kabaev
122ffeaf689SAlexander Kabaev      list&
123ffeaf689SAlexander Kabaev      operator=(const list& __x)
124ffeaf689SAlexander Kabaev      {
125ffeaf689SAlexander Kabaev	static_cast<_Base&>(*this) = __x;
126ffeaf689SAlexander Kabaev	this->_M_invalidate_all();
127ffeaf689SAlexander Kabaev	return *this;
128ffeaf689SAlexander Kabaev      }
129ffeaf689SAlexander Kabaev
130ffeaf689SAlexander Kabaev      template<class _InputIterator>
131ffeaf689SAlexander Kabaev        void
132ffeaf689SAlexander Kabaev        assign(_InputIterator __first, _InputIterator __last)
133ffeaf689SAlexander Kabaev        {
134ffeaf689SAlexander Kabaev	  __glibcxx_check_valid_range(__first, __last);
135ffeaf689SAlexander Kabaev	  _Base::assign(__first, __last);
136ffeaf689SAlexander Kabaev	  this->_M_invalidate_all();
137ffeaf689SAlexander Kabaev	}
138ffeaf689SAlexander Kabaev
139ffeaf689SAlexander Kabaev      void
140ffeaf689SAlexander Kabaev      assign(size_type __n, const _Tp& __t)
141ffeaf689SAlexander Kabaev      {
142ffeaf689SAlexander Kabaev	_Base::assign(__n, __t);
143ffeaf689SAlexander Kabaev	this->_M_invalidate_all();
144ffeaf689SAlexander Kabaev      }
145ffeaf689SAlexander Kabaev
146ffeaf689SAlexander Kabaev      using _Base::get_allocator;
147ffeaf689SAlexander Kabaev
148ffeaf689SAlexander Kabaev      // iterators:
149ffeaf689SAlexander Kabaev      iterator
150ffeaf689SAlexander Kabaev      begin()
151ffeaf689SAlexander Kabaev      { return iterator(_Base::begin(), this); }
152ffeaf689SAlexander Kabaev
153ffeaf689SAlexander Kabaev      const_iterator
154ffeaf689SAlexander Kabaev      begin() const
155ffeaf689SAlexander Kabaev      { return const_iterator(_Base::begin(), this); }
156ffeaf689SAlexander Kabaev
157ffeaf689SAlexander Kabaev      iterator
158ffeaf689SAlexander Kabaev      end()
159ffeaf689SAlexander Kabaev      { return iterator(_Base::end(), this); }
160ffeaf689SAlexander Kabaev
161ffeaf689SAlexander Kabaev      const_iterator
162ffeaf689SAlexander Kabaev      end() const
163ffeaf689SAlexander Kabaev      { return const_iterator(_Base::end(), this); }
164ffeaf689SAlexander Kabaev
165ffeaf689SAlexander Kabaev      reverse_iterator
166ffeaf689SAlexander Kabaev      rbegin()
167ffeaf689SAlexander Kabaev      { return reverse_iterator(end()); }
168ffeaf689SAlexander Kabaev
169ffeaf689SAlexander Kabaev      const_reverse_iterator
170ffeaf689SAlexander Kabaev      rbegin() const
171ffeaf689SAlexander Kabaev      { return const_reverse_iterator(end()); }
172ffeaf689SAlexander Kabaev
173ffeaf689SAlexander Kabaev      reverse_iterator
174ffeaf689SAlexander Kabaev      rend()
175ffeaf689SAlexander Kabaev      { return reverse_iterator(begin()); }
176ffeaf689SAlexander Kabaev
177ffeaf689SAlexander Kabaev      const_reverse_iterator
178ffeaf689SAlexander Kabaev      rend() const
179ffeaf689SAlexander Kabaev      { return const_reverse_iterator(begin()); }
180ffeaf689SAlexander Kabaev
181ffeaf689SAlexander Kabaev      // 23.2.2.2 capacity:
182ffeaf689SAlexander Kabaev      using _Base::empty;
183ffeaf689SAlexander Kabaev      using _Base::size;
184ffeaf689SAlexander Kabaev      using _Base::max_size;
185ffeaf689SAlexander Kabaev
186ffeaf689SAlexander Kabaev      void
187ffeaf689SAlexander Kabaev      resize(size_type __sz, _Tp __c = _Tp())
188ffeaf689SAlexander Kabaev      {
189ffeaf689SAlexander Kabaev	this->_M_detach_singular();
190ffeaf689SAlexander Kabaev
191ffeaf689SAlexander Kabaev	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
192ffeaf689SAlexander Kabaev	iterator __victim = begin();
193ffeaf689SAlexander Kabaev	iterator __end = end();
194ffeaf689SAlexander Kabaev	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
195ffeaf689SAlexander Kabaev	  ++__victim;
196ffeaf689SAlexander Kabaev
197ffeaf689SAlexander Kabaev	while (__victim != __end)
198ffeaf689SAlexander Kabaev	  {
199ffeaf689SAlexander Kabaev	    iterator __real_victim = __victim++;
200ffeaf689SAlexander Kabaev	    __real_victim._M_invalidate();
201ffeaf689SAlexander Kabaev	  }
202ffeaf689SAlexander Kabaev
203ffeaf689SAlexander Kabaev	try
204ffeaf689SAlexander Kabaev	  {
205ffeaf689SAlexander Kabaev	    _Base::resize(__sz, __c);
206ffeaf689SAlexander Kabaev	  }
207ffeaf689SAlexander Kabaev	catch(...)
208ffeaf689SAlexander Kabaev	  {
209ffeaf689SAlexander Kabaev	    this->_M_revalidate_singular();
210ffeaf689SAlexander Kabaev	    __throw_exception_again;
211ffeaf689SAlexander Kabaev	  }
212ffeaf689SAlexander Kabaev      }
213ffeaf689SAlexander Kabaev
214ffeaf689SAlexander Kabaev      // element access:
215ffeaf689SAlexander Kabaev      reference
216ffeaf689SAlexander Kabaev      front()
217ffeaf689SAlexander Kabaev      {
218ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
219ffeaf689SAlexander Kabaev	return _Base::front();
220ffeaf689SAlexander Kabaev      }
221ffeaf689SAlexander Kabaev
222ffeaf689SAlexander Kabaev      const_reference
223ffeaf689SAlexander Kabaev      front() const
224ffeaf689SAlexander Kabaev      {
225ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
226ffeaf689SAlexander Kabaev	return _Base::front();
227ffeaf689SAlexander Kabaev      }
228ffeaf689SAlexander Kabaev
229ffeaf689SAlexander Kabaev      reference
230ffeaf689SAlexander Kabaev      back()
231ffeaf689SAlexander Kabaev      {
232ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
233ffeaf689SAlexander Kabaev	return _Base::back();
234ffeaf689SAlexander Kabaev      }
235ffeaf689SAlexander Kabaev
236ffeaf689SAlexander Kabaev      const_reference
237ffeaf689SAlexander Kabaev      back() const
238ffeaf689SAlexander Kabaev      {
239ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
240ffeaf689SAlexander Kabaev	return _Base::back();
241ffeaf689SAlexander Kabaev      }
242ffeaf689SAlexander Kabaev
243ffeaf689SAlexander Kabaev      // 23.2.2.3 modifiers:
244ffeaf689SAlexander Kabaev      using _Base::push_front;
245ffeaf689SAlexander Kabaev
246ffeaf689SAlexander Kabaev      void
247ffeaf689SAlexander Kabaev      pop_front()
248ffeaf689SAlexander Kabaev      {
249ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
250ffeaf689SAlexander Kabaev	iterator __victim = begin();
251ffeaf689SAlexander Kabaev	__victim._M_invalidate();
252ffeaf689SAlexander Kabaev	_Base::pop_front();
253ffeaf689SAlexander Kabaev      }
254ffeaf689SAlexander Kabaev
255ffeaf689SAlexander Kabaev      using _Base::push_back;
256ffeaf689SAlexander Kabaev
257ffeaf689SAlexander Kabaev      void
258ffeaf689SAlexander Kabaev      pop_back()
259ffeaf689SAlexander Kabaev      {
260ffeaf689SAlexander Kabaev	__glibcxx_check_nonempty();
261ffeaf689SAlexander Kabaev	iterator __victim = end();
262ffeaf689SAlexander Kabaev	--__victim;
263ffeaf689SAlexander Kabaev	__victim._M_invalidate();
264ffeaf689SAlexander Kabaev	_Base::pop_back();
265ffeaf689SAlexander Kabaev      }
266ffeaf689SAlexander Kabaev
267ffeaf689SAlexander Kabaev      iterator
268ffeaf689SAlexander Kabaev      insert(iterator __position, const _Tp& __x)
269ffeaf689SAlexander Kabaev      {
270ffeaf689SAlexander Kabaev	__glibcxx_check_insert(__position);
271ffeaf689SAlexander Kabaev	return iterator(_Base::insert(__position.base(), __x), this);
272ffeaf689SAlexander Kabaev      }
273ffeaf689SAlexander Kabaev
274ffeaf689SAlexander Kabaev      void
275ffeaf689SAlexander Kabaev      insert(iterator __position, size_type __n, const _Tp& __x)
276ffeaf689SAlexander Kabaev      {
277ffeaf689SAlexander Kabaev	__glibcxx_check_insert(__position);
278ffeaf689SAlexander Kabaev	_Base::insert(__position.base(), __n, __x);
279ffeaf689SAlexander Kabaev      }
280ffeaf689SAlexander Kabaev
281ffeaf689SAlexander Kabaev      template<class _InputIterator>
282ffeaf689SAlexander Kabaev        void
283ffeaf689SAlexander Kabaev        insert(iterator __position, _InputIterator __first,
284ffeaf689SAlexander Kabaev	       _InputIterator __last)
285ffeaf689SAlexander Kabaev        {
286ffeaf689SAlexander Kabaev	  __glibcxx_check_insert_range(__position, __first, __last);
287ffeaf689SAlexander Kabaev	  _Base::insert(__position.base(), __first, __last);
288ffeaf689SAlexander Kabaev	}
289ffeaf689SAlexander Kabaev
290ffeaf689SAlexander Kabaev      iterator
291ffeaf689SAlexander Kabaev      erase(iterator __position)
292ffeaf689SAlexander Kabaev      {
293ffeaf689SAlexander Kabaev	__glibcxx_check_erase(__position);
294ffeaf689SAlexander Kabaev	__position._M_invalidate();
295ffeaf689SAlexander Kabaev	return iterator(_Base::erase(__position.base()), this);
296ffeaf689SAlexander Kabaev      }
297ffeaf689SAlexander Kabaev
298ffeaf689SAlexander Kabaev      iterator
299ffeaf689SAlexander Kabaev      erase(iterator __position, iterator __last)
300ffeaf689SAlexander Kabaev      {
301ffeaf689SAlexander Kabaev	// _GLIBCXX_RESOLVE_LIB_DEFECTS
302ffeaf689SAlexander Kabaev	// 151. can't currently clear() empty container
303ffeaf689SAlexander Kabaev	__glibcxx_check_erase_range(__position, __last);
304ffeaf689SAlexander Kabaev	for (iterator __victim = __position; __victim != __last; )
305ffeaf689SAlexander Kabaev	  {
306ffeaf689SAlexander Kabaev	    iterator __old = __victim;
307ffeaf689SAlexander Kabaev	    ++__victim;
308ffeaf689SAlexander Kabaev	    __old._M_invalidate();
309ffeaf689SAlexander Kabaev	  }
310ffeaf689SAlexander Kabaev	return iterator(_Base::erase(__position.base(), __last.base()), this);
311ffeaf689SAlexander Kabaev      }
312ffeaf689SAlexander Kabaev
313ffeaf689SAlexander Kabaev      void
314ffeaf689SAlexander Kabaev      swap(list& __x)
315ffeaf689SAlexander Kabaev      {
316ffeaf689SAlexander Kabaev	_Base::swap(__x);
317ffeaf689SAlexander Kabaev	this->_M_swap(__x);
318ffeaf689SAlexander Kabaev      }
319ffeaf689SAlexander Kabaev
320ffeaf689SAlexander Kabaev      void
321ffeaf689SAlexander Kabaev      clear()
322ffeaf689SAlexander Kabaev      {
323ffeaf689SAlexander Kabaev	_Base::clear();
324ffeaf689SAlexander Kabaev	this->_M_invalidate_all();
325ffeaf689SAlexander Kabaev      }
326ffeaf689SAlexander Kabaev
327ffeaf689SAlexander Kabaev      // 23.2.2.4 list operations:
328ffeaf689SAlexander Kabaev      void
329ffeaf689SAlexander Kabaev      splice(iterator __position, list& __x)
330ffeaf689SAlexander Kabaev      {
331ffeaf689SAlexander Kabaev	_GLIBCXX_DEBUG_VERIFY(&__x != this,
332*f8a1b7d9SAlexander Kabaev			      _M_message(__gnu_debug::__msg_self_splice)
333ffeaf689SAlexander Kabaev			      ._M_sequence(*this, "this"));
334ffeaf689SAlexander Kabaev	this->splice(__position, __x, __x.begin(), __x.end());
335ffeaf689SAlexander Kabaev      }
336ffeaf689SAlexander Kabaev
337ffeaf689SAlexander Kabaev      void
338ffeaf689SAlexander Kabaev      splice(iterator __position, list& __x, iterator __i)
339ffeaf689SAlexander Kabaev      {
340ffeaf689SAlexander Kabaev	__glibcxx_check_insert(__position);
341*f8a1b7d9SAlexander Kabaev
342*f8a1b7d9SAlexander Kabaev	// We used to perform the splice_alloc check:  not anymore, redundant
343*f8a1b7d9SAlexander Kabaev	// after implementing the relevant bits of N1599.
344*f8a1b7d9SAlexander Kabaev
345ffeaf689SAlexander Kabaev	_GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
346*f8a1b7d9SAlexander Kabaev			      _M_message(__gnu_debug::__msg_splice_bad)
347ffeaf689SAlexander Kabaev			      ._M_iterator(__i, "__i"));
348ffeaf689SAlexander Kabaev	_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
349*f8a1b7d9SAlexander Kabaev			      _M_message(__gnu_debug::__msg_splice_other)
350ffeaf689SAlexander Kabaev			     ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
351ffeaf689SAlexander Kabaev
352ffeaf689SAlexander Kabaev	// _GLIBCXX_RESOLVE_LIB_DEFECTS
353ffeaf689SAlexander Kabaev	// 250. splicing invalidates iterators
354ffeaf689SAlexander Kabaev	this->_M_transfer_iter(__i);
355ffeaf689SAlexander Kabaev	_Base::splice(__position.base(), __x._M_base(), __i.base());
356ffeaf689SAlexander Kabaev      }
357ffeaf689SAlexander Kabaev
358ffeaf689SAlexander Kabaev      void
359ffeaf689SAlexander Kabaev      splice(iterator __position, list& __x, iterator __first, iterator __last)
360ffeaf689SAlexander Kabaev      {
361ffeaf689SAlexander Kabaev	__glibcxx_check_insert(__position);
362ffeaf689SAlexander Kabaev	__glibcxx_check_valid_range(__first, __last);
363ffeaf689SAlexander Kabaev	_GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
364*f8a1b7d9SAlexander Kabaev			      _M_message(__gnu_debug::__msg_splice_other)
365ffeaf689SAlexander Kabaev			      ._M_sequence(__x, "x")
366ffeaf689SAlexander Kabaev			      ._M_iterator(__first, "first"));
367*f8a1b7d9SAlexander Kabaev
368*f8a1b7d9SAlexander Kabaev	// We used to perform the splice_alloc check:  not anymore, redundant
369*f8a1b7d9SAlexander Kabaev	// after implementing the relevant bits of N1599.
370ffeaf689SAlexander Kabaev
371ffeaf689SAlexander Kabaev	for (iterator __tmp = __first; __tmp != __last; )
372ffeaf689SAlexander Kabaev	  {
373ffeaf689SAlexander Kabaev	    _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
374*f8a1b7d9SAlexander Kabaev				_M_message(__gnu_debug::__msg_splice_overlap)
375ffeaf689SAlexander Kabaev				  ._M_iterator(__tmp, "position")
376ffeaf689SAlexander Kabaev				  ._M_iterator(__first, "first")
377ffeaf689SAlexander Kabaev				  ._M_iterator(__last, "last"));
378ffeaf689SAlexander Kabaev	    iterator __victim = __tmp++;
379ffeaf689SAlexander Kabaev	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
380ffeaf689SAlexander Kabaev	    // 250. splicing invalidates iterators
381ffeaf689SAlexander Kabaev	    this->_M_transfer_iter(__victim);
382ffeaf689SAlexander Kabaev	  }
383ffeaf689SAlexander Kabaev
384ffeaf689SAlexander Kabaev	_Base::splice(__position.base(), __x._M_base(), __first.base(),
385ffeaf689SAlexander Kabaev		      __last.base());
386ffeaf689SAlexander Kabaev      }
387ffeaf689SAlexander Kabaev
388ffeaf689SAlexander Kabaev      void
389ffeaf689SAlexander Kabaev      remove(const _Tp& __value)
390ffeaf689SAlexander Kabaev      {
391ffeaf689SAlexander Kabaev	for (iterator __x = begin(); __x.base() != _Base::end(); )
392ffeaf689SAlexander Kabaev	  {
393ffeaf689SAlexander Kabaev	    if (*__x == __value)
394ffeaf689SAlexander Kabaev	      __x = erase(__x);
395ffeaf689SAlexander Kabaev	    else
396ffeaf689SAlexander Kabaev	      ++__x;
397ffeaf689SAlexander Kabaev	  }
398ffeaf689SAlexander Kabaev      }
399ffeaf689SAlexander Kabaev
400ffeaf689SAlexander Kabaev      template<class _Predicate>
401ffeaf689SAlexander Kabaev        void
402ffeaf689SAlexander Kabaev        remove_if(_Predicate __pred)
403ffeaf689SAlexander Kabaev        {
404ffeaf689SAlexander Kabaev	  for (iterator __x = begin(); __x.base() != _Base::end(); )
405ffeaf689SAlexander Kabaev	    {
406ffeaf689SAlexander Kabaev	      if (__pred(*__x))
407ffeaf689SAlexander Kabaev		__x = erase(__x);
408ffeaf689SAlexander Kabaev	      else
409ffeaf689SAlexander Kabaev		++__x;
410ffeaf689SAlexander Kabaev	    }
411ffeaf689SAlexander Kabaev	}
412ffeaf689SAlexander Kabaev
413ffeaf689SAlexander Kabaev      void
414ffeaf689SAlexander Kabaev      unique()
415ffeaf689SAlexander Kabaev      {
416ffeaf689SAlexander Kabaev	iterator __first = begin();
417ffeaf689SAlexander Kabaev	iterator __last = end();
418ffeaf689SAlexander Kabaev	if (__first == __last)
419ffeaf689SAlexander Kabaev	  return;
420ffeaf689SAlexander Kabaev	iterator __next = __first;
421ffeaf689SAlexander Kabaev	while (++__next != __last)
422ffeaf689SAlexander Kabaev	  {
423ffeaf689SAlexander Kabaev	    if (*__first == *__next)
424ffeaf689SAlexander Kabaev	      erase(__next);
425ffeaf689SAlexander Kabaev	    else
426ffeaf689SAlexander Kabaev	      __first = __next;
427ffeaf689SAlexander Kabaev	    __next = __first;
428ffeaf689SAlexander Kabaev	  }
429ffeaf689SAlexander Kabaev      }
430ffeaf689SAlexander Kabaev
431ffeaf689SAlexander Kabaev      template<class _BinaryPredicate>
432ffeaf689SAlexander Kabaev        void
433ffeaf689SAlexander Kabaev        unique(_BinaryPredicate __binary_pred)
434ffeaf689SAlexander Kabaev        {
435ffeaf689SAlexander Kabaev	  iterator __first = begin();
436ffeaf689SAlexander Kabaev	  iterator __last = end();
437ffeaf689SAlexander Kabaev	  if (__first == __last)
438ffeaf689SAlexander Kabaev	    return;
439ffeaf689SAlexander Kabaev	  iterator __next = __first;
440ffeaf689SAlexander Kabaev	  while (++__next != __last)
441ffeaf689SAlexander Kabaev	    {
442ffeaf689SAlexander Kabaev	      if (__binary_pred(*__first, *__next))
443ffeaf689SAlexander Kabaev		erase(__next);
444ffeaf689SAlexander Kabaev	      else
445ffeaf689SAlexander Kabaev		__first = __next;
446ffeaf689SAlexander Kabaev	      __next = __first;
447ffeaf689SAlexander Kabaev	    }
448ffeaf689SAlexander Kabaev	}
449ffeaf689SAlexander Kabaev
450ffeaf689SAlexander Kabaev      void
451ffeaf689SAlexander Kabaev      merge(list& __x)
452ffeaf689SAlexander Kabaev      {
453ffeaf689SAlexander Kabaev	__glibcxx_check_sorted(_Base::begin(), _Base::end());
454ffeaf689SAlexander Kabaev	__glibcxx_check_sorted(__x.begin().base(), __x.end().base());
455ffeaf689SAlexander Kabaev	for (iterator __tmp = __x.begin(); __tmp != __x.end(); )
456ffeaf689SAlexander Kabaev	  {
457ffeaf689SAlexander Kabaev	    iterator __victim = __tmp++;
458ffeaf689SAlexander Kabaev	    __victim._M_attach(&__x);
459ffeaf689SAlexander Kabaev	  }
460ffeaf689SAlexander Kabaev	_Base::merge(__x._M_base());
461ffeaf689SAlexander Kabaev      }
462ffeaf689SAlexander Kabaev
463ffeaf689SAlexander Kabaev      template<class _Compare>
464ffeaf689SAlexander Kabaev        void
465ffeaf689SAlexander Kabaev        merge(list& __x, _Compare __comp)
466ffeaf689SAlexander Kabaev        {
467ffeaf689SAlexander Kabaev	  __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp);
468ffeaf689SAlexander Kabaev	  __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
469ffeaf689SAlexander Kabaev				      __comp);
470ffeaf689SAlexander Kabaev	  for (iterator __tmp = __x.begin(); __tmp != __x.end(); )
471ffeaf689SAlexander Kabaev	    {
472ffeaf689SAlexander Kabaev	      iterator __victim = __tmp++;
473ffeaf689SAlexander Kabaev	      __victim._M_attach(&__x);
474ffeaf689SAlexander Kabaev	    }
475ffeaf689SAlexander Kabaev	  _Base::merge(__x._M_base(), __comp);
476ffeaf689SAlexander Kabaev	}
477ffeaf689SAlexander Kabaev
478ffeaf689SAlexander Kabaev      void
479ffeaf689SAlexander Kabaev      sort() { _Base::sort(); }
480ffeaf689SAlexander Kabaev
481ffeaf689SAlexander Kabaev      template<typename _StrictWeakOrdering>
482ffeaf689SAlexander Kabaev        void
483ffeaf689SAlexander Kabaev        sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
484ffeaf689SAlexander Kabaev
485ffeaf689SAlexander Kabaev      using _Base::reverse;
486ffeaf689SAlexander Kabaev
487ffeaf689SAlexander Kabaev      _Base&
488ffeaf689SAlexander Kabaev      _M_base()       { return *this; }
489ffeaf689SAlexander Kabaev
490ffeaf689SAlexander Kabaev      const _Base&
491ffeaf689SAlexander Kabaev      _M_base() const { return *this; }
492ffeaf689SAlexander Kabaev
493ffeaf689SAlexander Kabaev    private:
494ffeaf689SAlexander Kabaev      void
495ffeaf689SAlexander Kabaev      _M_invalidate_all()
496ffeaf689SAlexander Kabaev      {
497ffeaf689SAlexander Kabaev	typedef typename _Base::const_iterator _Base_const_iterator;
498ffeaf689SAlexander Kabaev	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
499ffeaf689SAlexander Kabaev	this->_M_invalidate_if(_Not_equal(_M_base().end()));
500ffeaf689SAlexander Kabaev      }
501ffeaf689SAlexander Kabaev    };
502ffeaf689SAlexander Kabaev
503ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
504ffeaf689SAlexander Kabaev    inline bool
505ffeaf689SAlexander Kabaev    operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
506ffeaf689SAlexander Kabaev    { return __lhs._M_base() == __rhs._M_base(); }
507ffeaf689SAlexander Kabaev
508ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
509ffeaf689SAlexander Kabaev    inline bool
510ffeaf689SAlexander Kabaev    operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
511ffeaf689SAlexander Kabaev    { return __lhs._M_base() != __rhs._M_base(); }
512ffeaf689SAlexander Kabaev
513ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
514ffeaf689SAlexander Kabaev    inline bool
515ffeaf689SAlexander Kabaev    operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
516ffeaf689SAlexander Kabaev    { return __lhs._M_base() < __rhs._M_base(); }
517ffeaf689SAlexander Kabaev
518ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
519ffeaf689SAlexander Kabaev    inline bool
520ffeaf689SAlexander Kabaev    operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
521ffeaf689SAlexander Kabaev    { return __lhs._M_base() <= __rhs._M_base(); }
522ffeaf689SAlexander Kabaev
523ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
524ffeaf689SAlexander Kabaev    inline bool
525ffeaf689SAlexander Kabaev    operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
526ffeaf689SAlexander Kabaev    { return __lhs._M_base() >= __rhs._M_base(); }
527ffeaf689SAlexander Kabaev
528ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
529ffeaf689SAlexander Kabaev    inline bool
530ffeaf689SAlexander Kabaev    operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
531ffeaf689SAlexander Kabaev    { return __lhs._M_base() > __rhs._M_base(); }
532ffeaf689SAlexander Kabaev
533ffeaf689SAlexander Kabaev  template<typename _Tp, typename _Alloc>
534ffeaf689SAlexander Kabaev    inline void
535ffeaf689SAlexander Kabaev    swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
536ffeaf689SAlexander Kabaev    { __lhs.swap(__rhs); }
537*f8a1b7d9SAlexander Kabaev} // namespace __debug
538*f8a1b7d9SAlexander Kabaev} // namespace std
539ffeaf689SAlexander Kabaev
540ffeaf689SAlexander Kabaev#endif
541