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