1*404b540aSrobert// Debugging vector implementation -*- C++ -*- 2*404b540aSrobert 3*404b540aSrobert// Copyright (C) 2003, 2004, 2005 4*404b540aSrobert// Free Software Foundation, Inc. 5*404b540aSrobert// 6*404b540aSrobert// This file is part of the GNU ISO C++ Library. This library is free 7*404b540aSrobert// software; you can redistribute it and/or modify it under the 8*404b540aSrobert// terms of the GNU General Public License as published by the 9*404b540aSrobert// Free Software Foundation; either version 2, or (at your option) 10*404b540aSrobert// any later version. 11*404b540aSrobert 12*404b540aSrobert// This library is distributed in the hope that it will be useful, 13*404b540aSrobert// but WITHOUT ANY WARRANTY; without even the implied warranty of 14*404b540aSrobert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*404b540aSrobert// GNU General Public License for more details. 16*404b540aSrobert 17*404b540aSrobert// You should have received a copy of the GNU General Public License along 18*404b540aSrobert// with this library; see the file COPYING. If not, write to the Free 19*404b540aSrobert// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20*404b540aSrobert// USA. 21*404b540aSrobert 22*404b540aSrobert// As a special exception, you may use this file as part of a free software 23*404b540aSrobert// library without restriction. Specifically, if other files instantiate 24*404b540aSrobert// templates or use macros or inline functions from this file, or you compile 25*404b540aSrobert// this file and link it with other files to produce an executable, this 26*404b540aSrobert// file does not by itself cause the resulting executable to be covered by 27*404b540aSrobert// the GNU General Public License. This exception does not however 28*404b540aSrobert// invalidate any other reasons why the executable file might be covered by 29*404b540aSrobert// the GNU General Public License. 30*404b540aSrobert 31*404b540aSrobert/** @file debug/vector 32*404b540aSrobert * This file is a GNU debug extension to the Standard C++ Library. 33*404b540aSrobert */ 34*404b540aSrobert 35*404b540aSrobert#ifndef _GLIBCXX_DEBUG_VECTOR 36*404b540aSrobert#define _GLIBCXX_DEBUG_VECTOR 1 37*404b540aSrobert 38*404b540aSrobert#include <vector> 39*404b540aSrobert#include <utility> 40*404b540aSrobert#include <debug/safe_sequence.h> 41*404b540aSrobert#include <debug/safe_iterator.h> 42*404b540aSrobert 43*404b540aSrobertnamespace std 44*404b540aSrobert{ 45*404b540aSrobertnamespace __debug 46*404b540aSrobert{ 47*404b540aSrobert template<typename _Tp, 48*404b540aSrobert typename _Allocator = std::allocator<_Tp> > 49*404b540aSrobert class vector 50*404b540aSrobert : public _GLIBCXX_STD::vector<_Tp, _Allocator>, 51*404b540aSrobert public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > 52*404b540aSrobert { 53*404b540aSrobert typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base; 54*404b540aSrobert typedef __gnu_debug::_Safe_sequence<vector> _Safe_base; 55*404b540aSrobert 56*404b540aSrobert typedef typename _Base::const_iterator _Base_const_iterator; 57*404b540aSrobert typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 58*404b540aSrobert 59*404b540aSrobert public: 60*404b540aSrobert typedef typename _Base::reference reference; 61*404b540aSrobert typedef typename _Base::const_reference const_reference; 62*404b540aSrobert 63*404b540aSrobert typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector> 64*404b540aSrobert iterator; 65*404b540aSrobert typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector> 66*404b540aSrobert const_iterator; 67*404b540aSrobert 68*404b540aSrobert typedef typename _Base::size_type size_type; 69*404b540aSrobert typedef typename _Base::difference_type difference_type; 70*404b540aSrobert 71*404b540aSrobert typedef _Tp value_type; 72*404b540aSrobert typedef _Allocator allocator_type; 73*404b540aSrobert typedef typename _Base::pointer pointer; 74*404b540aSrobert typedef typename _Base::const_pointer const_pointer; 75*404b540aSrobert typedef std::reverse_iterator<iterator> reverse_iterator; 76*404b540aSrobert typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 77*404b540aSrobert 78*404b540aSrobert // 23.2.4.1 construct/copy/destroy: 79*404b540aSrobert explicit vector(const _Allocator& __a = _Allocator()) 80*404b540aSrobert : _Base(__a), _M_guaranteed_capacity(0) { } 81*404b540aSrobert 82*404b540aSrobert explicit vector(size_type __n, const _Tp& __value = _Tp(), 83*404b540aSrobert const _Allocator& __a = _Allocator()) 84*404b540aSrobert : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } 85*404b540aSrobert 86*404b540aSrobert template<class _InputIterator> 87*404b540aSrobert vector(_InputIterator __first, _InputIterator __last, 88*404b540aSrobert const _Allocator& __a = _Allocator()) 89*404b540aSrobert : _Base(__gnu_debug::__check_valid_range(__first, __last), 90*404b540aSrobert __last, __a), 91*404b540aSrobert _M_guaranteed_capacity(0) 92*404b540aSrobert { _M_update_guaranteed_capacity(); } 93*404b540aSrobert 94*404b540aSrobert vector(const vector<_Tp,_Allocator>& __x) 95*404b540aSrobert : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } 96*404b540aSrobert 97*404b540aSrobert /// Construction from a release-mode vector 98*404b540aSrobert vector(const _Base& __x) 99*404b540aSrobert : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } 100*404b540aSrobert 101*404b540aSrobert ~vector() { } 102*404b540aSrobert 103*404b540aSrobert vector<_Tp,_Allocator>& 104*404b540aSrobert operator=(const vector<_Tp,_Allocator>& __x) 105*404b540aSrobert { 106*404b540aSrobert static_cast<_Base&>(*this) = __x; 107*404b540aSrobert this->_M_invalidate_all(); 108*404b540aSrobert _M_update_guaranteed_capacity(); 109*404b540aSrobert return *this; 110*404b540aSrobert } 111*404b540aSrobert 112*404b540aSrobert template<typename _InputIterator> 113*404b540aSrobert void 114*404b540aSrobert assign(_InputIterator __first, _InputIterator __last) 115*404b540aSrobert { 116*404b540aSrobert __glibcxx_check_valid_range(__first, __last); 117*404b540aSrobert _Base::assign(__first, __last); 118*404b540aSrobert this->_M_invalidate_all(); 119*404b540aSrobert _M_update_guaranteed_capacity(); 120*404b540aSrobert } 121*404b540aSrobert 122*404b540aSrobert void 123*404b540aSrobert assign(size_type __n, const _Tp& __u) 124*404b540aSrobert { 125*404b540aSrobert _Base::assign(__n, __u); 126*404b540aSrobert this->_M_invalidate_all(); 127*404b540aSrobert _M_update_guaranteed_capacity(); 128*404b540aSrobert } 129*404b540aSrobert 130*404b540aSrobert using _Base::get_allocator; 131*404b540aSrobert 132*404b540aSrobert // iterators: 133*404b540aSrobert iterator 134*404b540aSrobert begin() 135*404b540aSrobert { return iterator(_Base::begin(), this); } 136*404b540aSrobert 137*404b540aSrobert const_iterator 138*404b540aSrobert begin() const 139*404b540aSrobert { return const_iterator(_Base::begin(), this); } 140*404b540aSrobert 141*404b540aSrobert iterator 142*404b540aSrobert end() 143*404b540aSrobert { return iterator(_Base::end(), this); } 144*404b540aSrobert 145*404b540aSrobert const_iterator 146*404b540aSrobert end() const 147*404b540aSrobert { return const_iterator(_Base::end(), this); } 148*404b540aSrobert 149*404b540aSrobert reverse_iterator 150*404b540aSrobert rbegin() 151*404b540aSrobert { return reverse_iterator(end()); } 152*404b540aSrobert 153*404b540aSrobert const_reverse_iterator 154*404b540aSrobert rbegin() const 155*404b540aSrobert { return const_reverse_iterator(end()); } 156*404b540aSrobert 157*404b540aSrobert reverse_iterator 158*404b540aSrobert rend() 159*404b540aSrobert { return reverse_iterator(begin()); } 160*404b540aSrobert 161*404b540aSrobert const_reverse_iterator 162*404b540aSrobert rend() const 163*404b540aSrobert { return const_reverse_iterator(begin()); } 164*404b540aSrobert 165*404b540aSrobert // 23.2.4.2 capacity: 166*404b540aSrobert using _Base::size; 167*404b540aSrobert using _Base::max_size; 168*404b540aSrobert 169*404b540aSrobert void 170*404b540aSrobert resize(size_type __sz, _Tp __c = _Tp()) 171*404b540aSrobert { 172*404b540aSrobert bool __realloc = _M_requires_reallocation(__sz); 173*404b540aSrobert if (__sz < this->size()) 174*404b540aSrobert this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); 175*404b540aSrobert _Base::resize(__sz, __c); 176*404b540aSrobert if (__realloc) 177*404b540aSrobert this->_M_invalidate_all(); 178*404b540aSrobert } 179*404b540aSrobert 180*404b540aSrobert using _Base::capacity; 181*404b540aSrobert using _Base::empty; 182*404b540aSrobert 183*404b540aSrobert void 184*404b540aSrobert reserve(size_type __n) 185*404b540aSrobert { 186*404b540aSrobert bool __realloc = _M_requires_reallocation(__n); 187*404b540aSrobert _Base::reserve(__n); 188*404b540aSrobert if (__n > _M_guaranteed_capacity) 189*404b540aSrobert _M_guaranteed_capacity = __n; 190*404b540aSrobert if (__realloc) 191*404b540aSrobert this->_M_invalidate_all(); 192*404b540aSrobert } 193*404b540aSrobert 194*404b540aSrobert // element access: 195*404b540aSrobert reference 196*404b540aSrobert operator[](size_type __n) 197*404b540aSrobert { 198*404b540aSrobert __glibcxx_check_subscript(__n); 199*404b540aSrobert return _M_base()[__n]; 200*404b540aSrobert } 201*404b540aSrobert 202*404b540aSrobert const_reference 203*404b540aSrobert operator[](size_type __n) const 204*404b540aSrobert { 205*404b540aSrobert __glibcxx_check_subscript(__n); 206*404b540aSrobert return _M_base()[__n]; 207*404b540aSrobert } 208*404b540aSrobert 209*404b540aSrobert using _Base::at; 210*404b540aSrobert 211*404b540aSrobert reference 212*404b540aSrobert front() 213*404b540aSrobert { 214*404b540aSrobert __glibcxx_check_nonempty(); 215*404b540aSrobert return _Base::front(); 216*404b540aSrobert } 217*404b540aSrobert 218*404b540aSrobert const_reference 219*404b540aSrobert front() const 220*404b540aSrobert { 221*404b540aSrobert __glibcxx_check_nonempty(); 222*404b540aSrobert return _Base::front(); 223*404b540aSrobert } 224*404b540aSrobert 225*404b540aSrobert reference 226*404b540aSrobert back() 227*404b540aSrobert { 228*404b540aSrobert __glibcxx_check_nonempty(); 229*404b540aSrobert return _Base::back(); 230*404b540aSrobert } 231*404b540aSrobert 232*404b540aSrobert const_reference 233*404b540aSrobert back() const 234*404b540aSrobert { 235*404b540aSrobert __glibcxx_check_nonempty(); 236*404b540aSrobert return _Base::back(); 237*404b540aSrobert } 238*404b540aSrobert 239*404b540aSrobert // _GLIBCXX_RESOLVE_LIB_DEFECTS 240*404b540aSrobert // DR 464. Suggestion for new member functions in standard containers. 241*404b540aSrobert using _Base::data; 242*404b540aSrobert 243*404b540aSrobert // 23.2.4.3 modifiers: 244*404b540aSrobert void 245*404b540aSrobert push_back(const _Tp& __x) 246*404b540aSrobert { 247*404b540aSrobert bool __realloc = _M_requires_reallocation(this->size() + 1); 248*404b540aSrobert _Base::push_back(__x); 249*404b540aSrobert if (__realloc) 250*404b540aSrobert this->_M_invalidate_all(); 251*404b540aSrobert _M_update_guaranteed_capacity(); 252*404b540aSrobert } 253*404b540aSrobert 254*404b540aSrobert void 255*404b540aSrobert pop_back() 256*404b540aSrobert { 257*404b540aSrobert __glibcxx_check_nonempty(); 258*404b540aSrobert iterator __victim = end() - 1; 259*404b540aSrobert __victim._M_invalidate(); 260*404b540aSrobert _Base::pop_back(); 261*404b540aSrobert } 262*404b540aSrobert 263*404b540aSrobert iterator 264*404b540aSrobert insert(iterator __position, const _Tp& __x) 265*404b540aSrobert { 266*404b540aSrobert __glibcxx_check_insert(__position); 267*404b540aSrobert bool __realloc = _M_requires_reallocation(this->size() + 1); 268*404b540aSrobert difference_type __offset = __position - begin(); 269*404b540aSrobert typename _Base::iterator __res = _Base::insert(__position.base(),__x); 270*404b540aSrobert if (__realloc) 271*404b540aSrobert this->_M_invalidate_all(); 272*404b540aSrobert else 273*404b540aSrobert this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 274*404b540aSrobert _M_update_guaranteed_capacity(); 275*404b540aSrobert return iterator(__res, this); 276*404b540aSrobert } 277*404b540aSrobert 278*404b540aSrobert void 279*404b540aSrobert insert(iterator __position, size_type __n, const _Tp& __x) 280*404b540aSrobert { 281*404b540aSrobert __glibcxx_check_insert(__position); 282*404b540aSrobert bool __realloc = _M_requires_reallocation(this->size() + __n); 283*404b540aSrobert difference_type __offset = __position - begin(); 284*404b540aSrobert _Base::insert(__position.base(), __n, __x); 285*404b540aSrobert if (__realloc) 286*404b540aSrobert this->_M_invalidate_all(); 287*404b540aSrobert else 288*404b540aSrobert this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 289*404b540aSrobert _M_update_guaranteed_capacity(); 290*404b540aSrobert } 291*404b540aSrobert 292*404b540aSrobert template<class _InputIterator> 293*404b540aSrobert void 294*404b540aSrobert insert(iterator __position, 295*404b540aSrobert _InputIterator __first, _InputIterator __last) 296*404b540aSrobert { 297*404b540aSrobert __glibcxx_check_insert_range(__position, __first, __last); 298*404b540aSrobert 299*404b540aSrobert /* Hard to guess if invalidation will occur, because __last 300*404b540aSrobert - __first can't be calculated in all cases, so we just 301*404b540aSrobert punt here by checking if it did occur. */ 302*404b540aSrobert typename _Base::iterator __old_begin = _M_base().begin(); 303*404b540aSrobert difference_type __offset = __position - begin(); 304*404b540aSrobert _Base::insert(__position.base(), __first, __last); 305*404b540aSrobert 306*404b540aSrobert if (_M_base().begin() != __old_begin) 307*404b540aSrobert this->_M_invalidate_all(); 308*404b540aSrobert else 309*404b540aSrobert this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 310*404b540aSrobert _M_update_guaranteed_capacity(); 311*404b540aSrobert } 312*404b540aSrobert 313*404b540aSrobert iterator 314*404b540aSrobert erase(iterator __position) 315*404b540aSrobert { 316*404b540aSrobert __glibcxx_check_erase(__position); 317*404b540aSrobert difference_type __offset = __position - begin(); 318*404b540aSrobert typename _Base::iterator __res = _Base::erase(__position.base()); 319*404b540aSrobert this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 320*404b540aSrobert return iterator(__res, this); 321*404b540aSrobert } 322*404b540aSrobert 323*404b540aSrobert iterator 324*404b540aSrobert erase(iterator __first, iterator __last) 325*404b540aSrobert { 326*404b540aSrobert // _GLIBCXX_RESOLVE_LIB_DEFECTS 327*404b540aSrobert // 151. can't currently clear() empty container 328*404b540aSrobert __glibcxx_check_erase_range(__first, __last); 329*404b540aSrobert 330*404b540aSrobert difference_type __offset = __first - begin(); 331*404b540aSrobert typename _Base::iterator __res = _Base::erase(__first.base(), 332*404b540aSrobert __last.base()); 333*404b540aSrobert this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); 334*404b540aSrobert return iterator(__res, this); 335*404b540aSrobert } 336*404b540aSrobert 337*404b540aSrobert void 338*404b540aSrobert swap(vector<_Tp,_Allocator>& __x) 339*404b540aSrobert { 340*404b540aSrobert _Base::swap(__x); 341*404b540aSrobert this->_M_swap(__x); 342*404b540aSrobert std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); 343*404b540aSrobert } 344*404b540aSrobert 345*404b540aSrobert void 346*404b540aSrobert clear() 347*404b540aSrobert { 348*404b540aSrobert _Base::clear(); 349*404b540aSrobert this->_M_invalidate_all(); 350*404b540aSrobert _M_guaranteed_capacity = 0; 351*404b540aSrobert } 352*404b540aSrobert 353*404b540aSrobert _Base& 354*404b540aSrobert _M_base() { return *this; } 355*404b540aSrobert 356*404b540aSrobert const _Base& 357*404b540aSrobert _M_base() const { return *this; } 358*404b540aSrobert 359*404b540aSrobert private: 360*404b540aSrobert size_type _M_guaranteed_capacity; 361*404b540aSrobert 362*404b540aSrobert bool 363*404b540aSrobert _M_requires_reallocation(size_type __elements) 364*404b540aSrobert { 365*404b540aSrobert#ifdef _GLIBCXX_DEBUG_PEDANTIC 366*404b540aSrobert return __elements > this->capacity(); 367*404b540aSrobert#else 368*404b540aSrobert return __elements > _M_guaranteed_capacity; 369*404b540aSrobert#endif 370*404b540aSrobert } 371*404b540aSrobert 372*404b540aSrobert void 373*404b540aSrobert _M_update_guaranteed_capacity() 374*404b540aSrobert { 375*404b540aSrobert if (this->size() > _M_guaranteed_capacity) 376*404b540aSrobert _M_guaranteed_capacity = this->size(); 377*404b540aSrobert } 378*404b540aSrobert }; 379*404b540aSrobert 380*404b540aSrobert template<typename _Tp, typename _Alloc> 381*404b540aSrobert inline bool 382*404b540aSrobert operator==(const vector<_Tp, _Alloc>& __lhs, 383*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 384*404b540aSrobert { return __lhs._M_base() == __rhs._M_base(); } 385*404b540aSrobert 386*404b540aSrobert template<typename _Tp, typename _Alloc> 387*404b540aSrobert inline bool 388*404b540aSrobert operator!=(const vector<_Tp, _Alloc>& __lhs, 389*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 390*404b540aSrobert { return __lhs._M_base() != __rhs._M_base(); } 391*404b540aSrobert 392*404b540aSrobert template<typename _Tp, typename _Alloc> 393*404b540aSrobert inline bool 394*404b540aSrobert operator<(const vector<_Tp, _Alloc>& __lhs, 395*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 396*404b540aSrobert { return __lhs._M_base() < __rhs._M_base(); } 397*404b540aSrobert 398*404b540aSrobert template<typename _Tp, typename _Alloc> 399*404b540aSrobert inline bool 400*404b540aSrobert operator<=(const vector<_Tp, _Alloc>& __lhs, 401*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 402*404b540aSrobert { return __lhs._M_base() <= __rhs._M_base(); } 403*404b540aSrobert 404*404b540aSrobert template<typename _Tp, typename _Alloc> 405*404b540aSrobert inline bool 406*404b540aSrobert operator>=(const vector<_Tp, _Alloc>& __lhs, 407*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 408*404b540aSrobert { return __lhs._M_base() >= __rhs._M_base(); } 409*404b540aSrobert 410*404b540aSrobert template<typename _Tp, typename _Alloc> 411*404b540aSrobert inline bool 412*404b540aSrobert operator>(const vector<_Tp, _Alloc>& __lhs, 413*404b540aSrobert const vector<_Tp, _Alloc>& __rhs) 414*404b540aSrobert { return __lhs._M_base() > __rhs._M_base(); } 415*404b540aSrobert 416*404b540aSrobert template<typename _Tp, typename _Alloc> 417*404b540aSrobert inline void 418*404b540aSrobert swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 419*404b540aSrobert { __lhs.swap(__rhs); } 420*404b540aSrobert} // namespace __debug 421*404b540aSrobert} // namespace std 422*404b540aSrobert 423*404b540aSrobert#endif 424