1*e4b17023SJohn Marino// Debugging vector 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/vector 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_VECTOR 31*e4b17023SJohn Marino#define _GLIBCXX_DEBUG_VECTOR 1 32*e4b17023SJohn Marino 33*e4b17023SJohn Marino#include <vector> 34*e4b17023SJohn Marino#include <utility> 35*e4b17023SJohn Marino#include <debug/safe_sequence.h> 36*e4b17023SJohn Marino#include <debug/safe_iterator.h> 37*e4b17023SJohn Marino 38*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 39*e4b17023SJohn Marino{ 40*e4b17023SJohn Marinonamespace __debug 41*e4b17023SJohn Marino{ 42*e4b17023SJohn Marino /// Class std::vector with safety/checking/debug instrumentation. 43*e4b17023SJohn Marino template<typename _Tp, 44*e4b17023SJohn Marino typename _Allocator = std::allocator<_Tp> > 45*e4b17023SJohn Marino class vector 46*e4b17023SJohn Marino : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, 47*e4b17023SJohn Marino public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > 48*e4b17023SJohn Marino { 49*e4b17023SJohn Marino typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; 50*e4b17023SJohn Marino 51*e4b17023SJohn Marino typedef typename _Base::iterator _Base_iterator; 52*e4b17023SJohn Marino typedef typename _Base::const_iterator _Base_const_iterator; 53*e4b17023SJohn Marino typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; 54*e4b17023SJohn Marino 55*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 56*e4b17023SJohn Marino typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; 57*e4b17023SJohn Marino#endif 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino public: 60*e4b17023SJohn Marino typedef typename _Base::reference reference; 61*e4b17023SJohn Marino typedef typename _Base::const_reference const_reference; 62*e4b17023SJohn Marino 63*e4b17023SJohn Marino typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector> 64*e4b17023SJohn Marino iterator; 65*e4b17023SJohn Marino typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector> 66*e4b17023SJohn Marino const_iterator; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino typedef typename _Base::size_type size_type; 69*e4b17023SJohn Marino typedef typename _Base::difference_type difference_type; 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino typedef _Tp value_type; 72*e4b17023SJohn Marino typedef _Allocator allocator_type; 73*e4b17023SJohn Marino typedef typename _Base::pointer pointer; 74*e4b17023SJohn Marino typedef typename _Base::const_pointer const_pointer; 75*e4b17023SJohn Marino typedef std::reverse_iterator<iterator> reverse_iterator; 76*e4b17023SJohn Marino typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino // 23.2.4.1 construct/copy/destroy: 79*e4b17023SJohn Marino explicit 80*e4b17023SJohn Marino vector(const _Allocator& __a = _Allocator()) 81*e4b17023SJohn Marino : _Base(__a), _M_guaranteed_capacity(0) { } 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 84*e4b17023SJohn Marino explicit 85*e4b17023SJohn Marino vector(size_type __n) 86*e4b17023SJohn Marino : _Base(__n), _M_guaranteed_capacity(__n) { } 87*e4b17023SJohn Marino 88*e4b17023SJohn Marino vector(size_type __n, const _Tp& __value, 89*e4b17023SJohn Marino const _Allocator& __a = _Allocator()) 90*e4b17023SJohn Marino : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } 91*e4b17023SJohn Marino#else 92*e4b17023SJohn Marino explicit 93*e4b17023SJohn Marino vector(size_type __n, const _Tp& __value = _Tp(), 94*e4b17023SJohn Marino const _Allocator& __a = _Allocator()) 95*e4b17023SJohn Marino : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } 96*e4b17023SJohn Marino#endif 97*e4b17023SJohn Marino 98*e4b17023SJohn Marino template<class _InputIterator> 99*e4b17023SJohn Marino vector(_InputIterator __first, _InputIterator __last, 100*e4b17023SJohn Marino const _Allocator& __a = _Allocator()) 101*e4b17023SJohn Marino : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, 102*e4b17023SJohn Marino __last)), 103*e4b17023SJohn Marino __gnu_debug::__base(__last), __a), 104*e4b17023SJohn Marino _M_guaranteed_capacity(0) 105*e4b17023SJohn Marino { _M_update_guaranteed_capacity(); } 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino vector(const vector& __x) 108*e4b17023SJohn Marino : _Base(__x), _M_guaranteed_capacity(__x.size()) { } 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino /// Construction from a release-mode vector 111*e4b17023SJohn Marino vector(const _Base& __x) 112*e4b17023SJohn Marino : _Base(__x), _M_guaranteed_capacity(__x.size()) { } 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 115*e4b17023SJohn Marino vector(vector&& __x) noexcept 116*e4b17023SJohn Marino : _Base(std::move(__x)), 117*e4b17023SJohn Marino _M_guaranteed_capacity(this->size()) 118*e4b17023SJohn Marino { 119*e4b17023SJohn Marino this->_M_swap(__x); 120*e4b17023SJohn Marino __x._M_guaranteed_capacity = 0; 121*e4b17023SJohn Marino } 122*e4b17023SJohn Marino 123*e4b17023SJohn Marino vector(const vector& __x, const allocator_type& __a) 124*e4b17023SJohn Marino : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { } 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino vector(vector&& __x, const allocator_type& __a) 127*e4b17023SJohn Marino : _Base(std::move(__x), __a), 128*e4b17023SJohn Marino _M_guaranteed_capacity(this->size()) 129*e4b17023SJohn Marino { 130*e4b17023SJohn Marino __x._M_invalidate_all(); 131*e4b17023SJohn Marino __x._M_guaranteed_capacity = 0; 132*e4b17023SJohn Marino } 133*e4b17023SJohn Marino 134*e4b17023SJohn Marino vector(initializer_list<value_type> __l, 135*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 136*e4b17023SJohn Marino : _Base(__l, __a), 137*e4b17023SJohn Marino _M_guaranteed_capacity(__l.size()) { } 138*e4b17023SJohn Marino#endif 139*e4b17023SJohn Marino 140*e4b17023SJohn Marino ~vector() _GLIBCXX_NOEXCEPT { } 141*e4b17023SJohn Marino 142*e4b17023SJohn Marino vector& 143*e4b17023SJohn Marino operator=(const vector& __x) 144*e4b17023SJohn Marino { 145*e4b17023SJohn Marino static_cast<_Base&>(*this) = __x; 146*e4b17023SJohn Marino this->_M_invalidate_all(); 147*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 148*e4b17023SJohn Marino return *this; 149*e4b17023SJohn Marino } 150*e4b17023SJohn Marino 151*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 152*e4b17023SJohn Marino vector& 153*e4b17023SJohn Marino operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 154*e4b17023SJohn Marino { 155*e4b17023SJohn Marino _Base::operator=(std::move(__x)); 156*e4b17023SJohn Marino this->_M_invalidate_all(); 157*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 158*e4b17023SJohn Marino __x._M_invalidate_all(); 159*e4b17023SJohn Marino __x._M_guaranteed_capacity = 0; 160*e4b17023SJohn Marino return *this; 161*e4b17023SJohn Marino } 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino vector& 164*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 165*e4b17023SJohn Marino { 166*e4b17023SJohn Marino static_cast<_Base&>(*this) = __l; 167*e4b17023SJohn Marino this->_M_invalidate_all(); 168*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 169*e4b17023SJohn Marino return *this; 170*e4b17023SJohn Marino } 171*e4b17023SJohn Marino#endif 172*e4b17023SJohn Marino 173*e4b17023SJohn Marino template<typename _InputIterator> 174*e4b17023SJohn Marino void 175*e4b17023SJohn Marino assign(_InputIterator __first, _InputIterator __last) 176*e4b17023SJohn Marino { 177*e4b17023SJohn Marino __glibcxx_check_valid_range(__first, __last); 178*e4b17023SJohn Marino _Base::assign(__gnu_debug::__base(__first), 179*e4b17023SJohn Marino __gnu_debug::__base(__last)); 180*e4b17023SJohn Marino this->_M_invalidate_all(); 181*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 182*e4b17023SJohn Marino } 183*e4b17023SJohn Marino 184*e4b17023SJohn Marino void 185*e4b17023SJohn Marino assign(size_type __n, const _Tp& __u) 186*e4b17023SJohn Marino { 187*e4b17023SJohn Marino _Base::assign(__n, __u); 188*e4b17023SJohn Marino this->_M_invalidate_all(); 189*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 190*e4b17023SJohn Marino } 191*e4b17023SJohn Marino 192*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 193*e4b17023SJohn Marino void 194*e4b17023SJohn Marino assign(initializer_list<value_type> __l) 195*e4b17023SJohn Marino { 196*e4b17023SJohn Marino _Base::assign(__l); 197*e4b17023SJohn Marino this->_M_invalidate_all(); 198*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 199*e4b17023SJohn Marino } 200*e4b17023SJohn Marino#endif 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino using _Base::get_allocator; 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino // iterators: 205*e4b17023SJohn Marino iterator 206*e4b17023SJohn Marino begin() _GLIBCXX_NOEXCEPT 207*e4b17023SJohn Marino { return iterator(_Base::begin(), this); } 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino const_iterator 210*e4b17023SJohn Marino begin() const _GLIBCXX_NOEXCEPT 211*e4b17023SJohn Marino { return const_iterator(_Base::begin(), this); } 212*e4b17023SJohn Marino 213*e4b17023SJohn Marino iterator 214*e4b17023SJohn Marino end() _GLIBCXX_NOEXCEPT 215*e4b17023SJohn Marino { return iterator(_Base::end(), this); } 216*e4b17023SJohn Marino 217*e4b17023SJohn Marino const_iterator 218*e4b17023SJohn Marino end() const _GLIBCXX_NOEXCEPT 219*e4b17023SJohn Marino { return const_iterator(_Base::end(), this); } 220*e4b17023SJohn Marino 221*e4b17023SJohn Marino reverse_iterator 222*e4b17023SJohn Marino rbegin() _GLIBCXX_NOEXCEPT 223*e4b17023SJohn Marino { return reverse_iterator(end()); } 224*e4b17023SJohn Marino 225*e4b17023SJohn Marino const_reverse_iterator 226*e4b17023SJohn Marino rbegin() const _GLIBCXX_NOEXCEPT 227*e4b17023SJohn Marino { return const_reverse_iterator(end()); } 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino reverse_iterator 230*e4b17023SJohn Marino rend() _GLIBCXX_NOEXCEPT 231*e4b17023SJohn Marino { return reverse_iterator(begin()); } 232*e4b17023SJohn Marino 233*e4b17023SJohn Marino const_reverse_iterator 234*e4b17023SJohn Marino rend() const _GLIBCXX_NOEXCEPT 235*e4b17023SJohn Marino { return const_reverse_iterator(begin()); } 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 238*e4b17023SJohn Marino const_iterator 239*e4b17023SJohn Marino cbegin() const noexcept 240*e4b17023SJohn Marino { return const_iterator(_Base::begin(), this); } 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino const_iterator 243*e4b17023SJohn Marino cend() const noexcept 244*e4b17023SJohn Marino { return const_iterator(_Base::end(), this); } 245*e4b17023SJohn Marino 246*e4b17023SJohn Marino const_reverse_iterator 247*e4b17023SJohn Marino crbegin() const noexcept 248*e4b17023SJohn Marino { return const_reverse_iterator(end()); } 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino const_reverse_iterator 251*e4b17023SJohn Marino crend() const noexcept 252*e4b17023SJohn Marino { return const_reverse_iterator(begin()); } 253*e4b17023SJohn Marino#endif 254*e4b17023SJohn Marino 255*e4b17023SJohn Marino // 23.2.4.2 capacity: 256*e4b17023SJohn Marino using _Base::size; 257*e4b17023SJohn Marino using _Base::max_size; 258*e4b17023SJohn Marino 259*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 260*e4b17023SJohn Marino void 261*e4b17023SJohn Marino resize(size_type __sz) 262*e4b17023SJohn Marino { 263*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(__sz); 264*e4b17023SJohn Marino if (__sz < this->size()) 265*e4b17023SJohn Marino this->_M_invalidate_after_nth(__sz); 266*e4b17023SJohn Marino _Base::resize(__sz); 267*e4b17023SJohn Marino if (__realloc) 268*e4b17023SJohn Marino this->_M_invalidate_all(); 269*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 270*e4b17023SJohn Marino } 271*e4b17023SJohn Marino 272*e4b17023SJohn Marino void 273*e4b17023SJohn Marino resize(size_type __sz, const _Tp& __c) 274*e4b17023SJohn Marino { 275*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(__sz); 276*e4b17023SJohn Marino if (__sz < this->size()) 277*e4b17023SJohn Marino this->_M_invalidate_after_nth(__sz); 278*e4b17023SJohn Marino _Base::resize(__sz, __c); 279*e4b17023SJohn Marino if (__realloc) 280*e4b17023SJohn Marino this->_M_invalidate_all(); 281*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 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 bool __realloc = _M_requires_reallocation(__sz); 288*e4b17023SJohn Marino if (__sz < this->size()) 289*e4b17023SJohn Marino this->_M_invalidate_after_nth(__sz); 290*e4b17023SJohn Marino _Base::resize(__sz, __c); 291*e4b17023SJohn Marino if (__realloc) 292*e4b17023SJohn Marino this->_M_invalidate_all(); 293*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 294*e4b17023SJohn Marino } 295*e4b17023SJohn Marino#endif 296*e4b17023SJohn Marino 297*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 298*e4b17023SJohn Marino void 299*e4b17023SJohn Marino shrink_to_fit() 300*e4b17023SJohn Marino { 301*e4b17023SJohn Marino if (_Base::_M_shrink_to_fit()) 302*e4b17023SJohn Marino { 303*e4b17023SJohn Marino _M_guaranteed_capacity = _Base::capacity(); 304*e4b17023SJohn Marino this->_M_invalidate_all(); 305*e4b17023SJohn Marino } 306*e4b17023SJohn Marino } 307*e4b17023SJohn Marino#endif 308*e4b17023SJohn Marino 309*e4b17023SJohn Marino size_type 310*e4b17023SJohn Marino capacity() const _GLIBCXX_NOEXCEPT 311*e4b17023SJohn Marino { 312*e4b17023SJohn Marino#ifdef _GLIBCXX_DEBUG_PEDANTIC 313*e4b17023SJohn Marino return _M_guaranteed_capacity; 314*e4b17023SJohn Marino#else 315*e4b17023SJohn Marino return _Base::capacity(); 316*e4b17023SJohn Marino#endif 317*e4b17023SJohn Marino } 318*e4b17023SJohn Marino 319*e4b17023SJohn Marino using _Base::empty; 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino void 322*e4b17023SJohn Marino reserve(size_type __n) 323*e4b17023SJohn Marino { 324*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(__n); 325*e4b17023SJohn Marino _Base::reserve(__n); 326*e4b17023SJohn Marino if (__n > _M_guaranteed_capacity) 327*e4b17023SJohn Marino _M_guaranteed_capacity = __n; 328*e4b17023SJohn Marino if (__realloc) 329*e4b17023SJohn Marino this->_M_invalidate_all(); 330*e4b17023SJohn Marino } 331*e4b17023SJohn Marino 332*e4b17023SJohn Marino // element access: 333*e4b17023SJohn Marino reference 334*e4b17023SJohn Marino operator[](size_type __n) 335*e4b17023SJohn Marino { 336*e4b17023SJohn Marino __glibcxx_check_subscript(__n); 337*e4b17023SJohn Marino return _M_base()[__n]; 338*e4b17023SJohn Marino } 339*e4b17023SJohn Marino 340*e4b17023SJohn Marino const_reference 341*e4b17023SJohn Marino operator[](size_type __n) const 342*e4b17023SJohn Marino { 343*e4b17023SJohn Marino __glibcxx_check_subscript(__n); 344*e4b17023SJohn Marino return _M_base()[__n]; 345*e4b17023SJohn Marino } 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino using _Base::at; 348*e4b17023SJohn Marino 349*e4b17023SJohn Marino reference 350*e4b17023SJohn Marino front() 351*e4b17023SJohn Marino { 352*e4b17023SJohn Marino __glibcxx_check_nonempty(); 353*e4b17023SJohn Marino return _Base::front(); 354*e4b17023SJohn Marino } 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino const_reference 357*e4b17023SJohn Marino front() const 358*e4b17023SJohn Marino { 359*e4b17023SJohn Marino __glibcxx_check_nonempty(); 360*e4b17023SJohn Marino return _Base::front(); 361*e4b17023SJohn Marino } 362*e4b17023SJohn Marino 363*e4b17023SJohn Marino reference 364*e4b17023SJohn Marino back() 365*e4b17023SJohn Marino { 366*e4b17023SJohn Marino __glibcxx_check_nonempty(); 367*e4b17023SJohn Marino return _Base::back(); 368*e4b17023SJohn Marino } 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino const_reference 371*e4b17023SJohn Marino back() const 372*e4b17023SJohn Marino { 373*e4b17023SJohn Marino __glibcxx_check_nonempty(); 374*e4b17023SJohn Marino return _Base::back(); 375*e4b17023SJohn Marino } 376*e4b17023SJohn Marino 377*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 378*e4b17023SJohn Marino // DR 464. Suggestion for new member functions in standard containers. 379*e4b17023SJohn Marino using _Base::data; 380*e4b17023SJohn Marino 381*e4b17023SJohn Marino // 23.2.4.3 modifiers: 382*e4b17023SJohn Marino void 383*e4b17023SJohn Marino push_back(const _Tp& __x) 384*e4b17023SJohn Marino { 385*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(this->size() + 1); 386*e4b17023SJohn Marino _Base::push_back(__x); 387*e4b17023SJohn Marino if (__realloc) 388*e4b17023SJohn Marino this->_M_invalidate_all(); 389*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 390*e4b17023SJohn Marino } 391*e4b17023SJohn Marino 392*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 393*e4b17023SJohn Marino template<typename _Up = _Tp> 394*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 395*e4b17023SJohn Marino void>::__type 396*e4b17023SJohn Marino push_back(_Tp&& __x) 397*e4b17023SJohn Marino { emplace_back(std::move(__x)); } 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino template<typename... _Args> 400*e4b17023SJohn Marino void 401*e4b17023SJohn Marino emplace_back(_Args&&... __args) 402*e4b17023SJohn Marino { 403*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(this->size() + 1); 404*e4b17023SJohn Marino _Base::emplace_back(std::forward<_Args>(__args)...); 405*e4b17023SJohn Marino if (__realloc) 406*e4b17023SJohn Marino this->_M_invalidate_all(); 407*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 408*e4b17023SJohn Marino } 409*e4b17023SJohn Marino#endif 410*e4b17023SJohn Marino 411*e4b17023SJohn Marino void 412*e4b17023SJohn Marino pop_back() 413*e4b17023SJohn Marino { 414*e4b17023SJohn Marino __glibcxx_check_nonempty(); 415*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(--_Base::end())); 416*e4b17023SJohn Marino _Base::pop_back(); 417*e4b17023SJohn Marino } 418*e4b17023SJohn Marino 419*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 420*e4b17023SJohn Marino template<typename... _Args> 421*e4b17023SJohn Marino iterator 422*e4b17023SJohn Marino emplace(iterator __position, _Args&&... __args) 423*e4b17023SJohn Marino { 424*e4b17023SJohn Marino __glibcxx_check_insert(__position); 425*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(this->size() + 1); 426*e4b17023SJohn Marino difference_type __offset = __position.base() - _Base::begin(); 427*e4b17023SJohn Marino _Base_iterator __res = _Base::emplace(__position.base(), 428*e4b17023SJohn Marino std::forward<_Args>(__args)...); 429*e4b17023SJohn Marino if (__realloc) 430*e4b17023SJohn Marino this->_M_invalidate_all(); 431*e4b17023SJohn Marino else 432*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 433*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 434*e4b17023SJohn Marino return iterator(__res, this); 435*e4b17023SJohn Marino } 436*e4b17023SJohn Marino#endif 437*e4b17023SJohn Marino 438*e4b17023SJohn Marino iterator 439*e4b17023SJohn Marino insert(iterator __position, const _Tp& __x) 440*e4b17023SJohn Marino { 441*e4b17023SJohn Marino __glibcxx_check_insert(__position); 442*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(this->size() + 1); 443*e4b17023SJohn Marino difference_type __offset = __position.base() - _Base::begin(); 444*e4b17023SJohn Marino _Base_iterator __res = _Base::insert(__position.base(), __x); 445*e4b17023SJohn Marino if (__realloc) 446*e4b17023SJohn Marino this->_M_invalidate_all(); 447*e4b17023SJohn Marino else 448*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 449*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 450*e4b17023SJohn Marino return iterator(__res, this); 451*e4b17023SJohn Marino } 452*e4b17023SJohn Marino 453*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 454*e4b17023SJohn Marino template<typename _Up = _Tp> 455*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 456*e4b17023SJohn Marino iterator>::__type 457*e4b17023SJohn Marino insert(iterator __position, _Tp&& __x) 458*e4b17023SJohn Marino { return emplace(__position, std::move(__x)); } 459*e4b17023SJohn Marino 460*e4b17023SJohn Marino void 461*e4b17023SJohn Marino insert(iterator __position, initializer_list<value_type> __l) 462*e4b17023SJohn Marino { this->insert(__position, __l.begin(), __l.end()); } 463*e4b17023SJohn Marino#endif 464*e4b17023SJohn Marino 465*e4b17023SJohn Marino void 466*e4b17023SJohn Marino insert(iterator __position, size_type __n, const _Tp& __x) 467*e4b17023SJohn Marino { 468*e4b17023SJohn Marino __glibcxx_check_insert(__position); 469*e4b17023SJohn Marino bool __realloc = _M_requires_reallocation(this->size() + __n); 470*e4b17023SJohn Marino difference_type __offset = __position.base() - _Base::begin(); 471*e4b17023SJohn Marino _Base::insert(__position.base(), __n, __x); 472*e4b17023SJohn Marino if (__realloc) 473*e4b17023SJohn Marino this->_M_invalidate_all(); 474*e4b17023SJohn Marino else 475*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 476*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 477*e4b17023SJohn Marino } 478*e4b17023SJohn Marino 479*e4b17023SJohn Marino template<class _InputIterator> 480*e4b17023SJohn Marino void 481*e4b17023SJohn Marino insert(iterator __position, 482*e4b17023SJohn Marino _InputIterator __first, _InputIterator __last) 483*e4b17023SJohn Marino { 484*e4b17023SJohn Marino __glibcxx_check_insert_range(__position, __first, __last); 485*e4b17023SJohn Marino 486*e4b17023SJohn Marino /* Hard to guess if invalidation will occur, because __last 487*e4b17023SJohn Marino - __first can't be calculated in all cases, so we just 488*e4b17023SJohn Marino punt here by checking if it did occur. */ 489*e4b17023SJohn Marino _Base_iterator __old_begin = _M_base().begin(); 490*e4b17023SJohn Marino difference_type __offset = __position.base() - _Base::begin(); 491*e4b17023SJohn Marino _Base::insert(__position.base(), __gnu_debug::__base(__first), 492*e4b17023SJohn Marino __gnu_debug::__base(__last)); 493*e4b17023SJohn Marino 494*e4b17023SJohn Marino if (_M_base().begin() != __old_begin) 495*e4b17023SJohn Marino this->_M_invalidate_all(); 496*e4b17023SJohn Marino else 497*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 498*e4b17023SJohn Marino _M_update_guaranteed_capacity(); 499*e4b17023SJohn Marino } 500*e4b17023SJohn Marino 501*e4b17023SJohn Marino iterator 502*e4b17023SJohn Marino erase(iterator __position) 503*e4b17023SJohn Marino { 504*e4b17023SJohn Marino __glibcxx_check_erase(__position); 505*e4b17023SJohn Marino difference_type __offset = __position.base() - _Base::begin(); 506*e4b17023SJohn Marino _Base_iterator __res = _Base::erase(__position.base()); 507*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 508*e4b17023SJohn Marino return iterator(__res, this); 509*e4b17023SJohn Marino } 510*e4b17023SJohn Marino 511*e4b17023SJohn Marino iterator 512*e4b17023SJohn Marino erase(iterator __first, iterator __last) 513*e4b17023SJohn Marino { 514*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 515*e4b17023SJohn Marino // 151. can't currently clear() empty container 516*e4b17023SJohn Marino __glibcxx_check_erase_range(__first, __last); 517*e4b17023SJohn Marino 518*e4b17023SJohn Marino if (__first.base() != __last.base()) 519*e4b17023SJohn Marino { 520*e4b17023SJohn Marino difference_type __offset = __first.base() - _Base::begin(); 521*e4b17023SJohn Marino _Base_iterator __res = _Base::erase(__first.base(), 522*e4b17023SJohn Marino __last.base()); 523*e4b17023SJohn Marino this->_M_invalidate_after_nth(__offset); 524*e4b17023SJohn Marino return iterator(__res, this); 525*e4b17023SJohn Marino } 526*e4b17023SJohn Marino else 527*e4b17023SJohn Marino return __first; 528*e4b17023SJohn Marino } 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino void 531*e4b17023SJohn Marino swap(vector& __x) 532*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 533*e4b17023SJohn Marino noexcept(_Alloc_traits::_S_nothrow_swap()) 534*e4b17023SJohn Marino#endif 535*e4b17023SJohn Marino { 536*e4b17023SJohn Marino _Base::swap(__x); 537*e4b17023SJohn Marino this->_M_swap(__x); 538*e4b17023SJohn Marino std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); 539*e4b17023SJohn Marino } 540*e4b17023SJohn Marino 541*e4b17023SJohn Marino void 542*e4b17023SJohn Marino clear() _GLIBCXX_NOEXCEPT 543*e4b17023SJohn Marino { 544*e4b17023SJohn Marino _Base::clear(); 545*e4b17023SJohn Marino this->_M_invalidate_all(); 546*e4b17023SJohn Marino _M_guaranteed_capacity = 0; 547*e4b17023SJohn Marino } 548*e4b17023SJohn Marino 549*e4b17023SJohn Marino _Base& 550*e4b17023SJohn Marino _M_base() _GLIBCXX_NOEXCEPT { return *this; } 551*e4b17023SJohn Marino 552*e4b17023SJohn Marino const _Base& 553*e4b17023SJohn Marino _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino private: 556*e4b17023SJohn Marino size_type _M_guaranteed_capacity; 557*e4b17023SJohn Marino 558*e4b17023SJohn Marino bool 559*e4b17023SJohn Marino _M_requires_reallocation(size_type __elements) 560*e4b17023SJohn Marino { return __elements > this->capacity(); } 561*e4b17023SJohn Marino 562*e4b17023SJohn Marino void 563*e4b17023SJohn Marino _M_update_guaranteed_capacity() 564*e4b17023SJohn Marino { 565*e4b17023SJohn Marino if (this->size() > _M_guaranteed_capacity) 566*e4b17023SJohn Marino _M_guaranteed_capacity = this->size(); 567*e4b17023SJohn Marino } 568*e4b17023SJohn Marino 569*e4b17023SJohn Marino void 570*e4b17023SJohn Marino _M_invalidate_after_nth(difference_type __n) 571*e4b17023SJohn Marino { 572*e4b17023SJohn Marino typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 573*e4b17023SJohn Marino this->_M_invalidate_if(_After_nth(__n, _Base::begin())); 574*e4b17023SJohn Marino } 575*e4b17023SJohn Marino }; 576*e4b17023SJohn Marino 577*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 578*e4b17023SJohn Marino inline bool 579*e4b17023SJohn Marino operator==(const vector<_Tp, _Alloc>& __lhs, 580*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 581*e4b17023SJohn Marino { return __lhs._M_base() == __rhs._M_base(); } 582*e4b17023SJohn Marino 583*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 584*e4b17023SJohn Marino inline bool 585*e4b17023SJohn Marino operator!=(const vector<_Tp, _Alloc>& __lhs, 586*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 587*e4b17023SJohn Marino { return __lhs._M_base() != __rhs._M_base(); } 588*e4b17023SJohn Marino 589*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 590*e4b17023SJohn Marino inline bool 591*e4b17023SJohn Marino operator<(const vector<_Tp, _Alloc>& __lhs, 592*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 593*e4b17023SJohn Marino { return __lhs._M_base() < __rhs._M_base(); } 594*e4b17023SJohn Marino 595*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 596*e4b17023SJohn Marino inline bool 597*e4b17023SJohn Marino operator<=(const vector<_Tp, _Alloc>& __lhs, 598*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 599*e4b17023SJohn Marino { return __lhs._M_base() <= __rhs._M_base(); } 600*e4b17023SJohn Marino 601*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 602*e4b17023SJohn Marino inline bool 603*e4b17023SJohn Marino operator>=(const vector<_Tp, _Alloc>& __lhs, 604*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 605*e4b17023SJohn Marino { return __lhs._M_base() >= __rhs._M_base(); } 606*e4b17023SJohn Marino 607*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 608*e4b17023SJohn Marino inline bool 609*e4b17023SJohn Marino operator>(const vector<_Tp, _Alloc>& __lhs, 610*e4b17023SJohn Marino const vector<_Tp, _Alloc>& __rhs) 611*e4b17023SJohn Marino { return __lhs._M_base() > __rhs._M_base(); } 612*e4b17023SJohn Marino 613*e4b17023SJohn Marino template<typename _Tp, typename _Alloc> 614*e4b17023SJohn Marino inline void 615*e4b17023SJohn Marino swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 616*e4b17023SJohn Marino { __lhs.swap(__rhs); } 617*e4b17023SJohn Marino 618*e4b17023SJohn Marino} // namespace __debug 619*e4b17023SJohn Marino 620*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__ 621*e4b17023SJohn Marino // DR 1182. 622*e4b17023SJohn Marino /// std::hash specialization for vector<bool>. 623*e4b17023SJohn Marino template<typename _Alloc> 624*e4b17023SJohn Marino struct hash<__debug::vector<bool, _Alloc>> 625*e4b17023SJohn Marino : public __hash_base<size_t, __debug::vector<bool, _Alloc>> 626*e4b17023SJohn Marino { 627*e4b17023SJohn Marino size_t 628*e4b17023SJohn Marino operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept 629*e4b17023SJohn Marino { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() 630*e4b17023SJohn Marino (__b._M_base()); } 631*e4b17023SJohn Marino }; 632*e4b17023SJohn Marino#endif 633*e4b17023SJohn Marino 634*e4b17023SJohn Marino} // namespace std 635*e4b17023SJohn Marino 636*e4b17023SJohn Marino#endif 637