1*404b540aSrobert// Debugging deque 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/deque 32*404b540aSrobert * This file is a GNU debug extension to the Standard C++ Library. 33*404b540aSrobert */ 34*404b540aSrobert 35*404b540aSrobert#ifndef _GLIBCXX_DEBUG_DEQUE 36*404b540aSrobert#define _GLIBCXX_DEBUG_DEQUE 1 37*404b540aSrobert 38*404b540aSrobert#include <deque> 39*404b540aSrobert#include <debug/safe_sequence.h> 40*404b540aSrobert#include <debug/safe_iterator.h> 41*404b540aSrobert 42*404b540aSrobertnamespace std 43*404b540aSrobert{ 44*404b540aSrobertnamespace __debug 45*404b540aSrobert{ 46*404b540aSrobert template<typename _Tp, typename _Allocator = std::allocator<_Tp> > 47*404b540aSrobert class deque 48*404b540aSrobert : public _GLIBCXX_STD::deque<_Tp, _Allocator>, 49*404b540aSrobert public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > 50*404b540aSrobert { 51*404b540aSrobert typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; 52*404b540aSrobert typedef __gnu_debug::_Safe_sequence<deque> _Safe_base; 53*404b540aSrobert 54*404b540aSrobert public: 55*404b540aSrobert typedef typename _Base::reference reference; 56*404b540aSrobert typedef typename _Base::const_reference const_reference; 57*404b540aSrobert 58*404b540aSrobert typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> 59*404b540aSrobert iterator; 60*404b540aSrobert typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque> 61*404b540aSrobert const_iterator; 62*404b540aSrobert 63*404b540aSrobert typedef typename _Base::size_type size_type; 64*404b540aSrobert typedef typename _Base::difference_type difference_type; 65*404b540aSrobert 66*404b540aSrobert typedef _Tp value_type; 67*404b540aSrobert typedef _Allocator allocator_type; 68*404b540aSrobert typedef typename _Base::pointer pointer; 69*404b540aSrobert typedef typename _Base::const_pointer const_pointer; 70*404b540aSrobert typedef std::reverse_iterator<iterator> reverse_iterator; 71*404b540aSrobert typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 72*404b540aSrobert 73*404b540aSrobert // 23.2.1.1 construct/copy/destroy: 74*404b540aSrobert explicit deque(const _Allocator& __a = _Allocator()) 75*404b540aSrobert : _Base(__a) { } 76*404b540aSrobert 77*404b540aSrobert explicit deque(size_type __n, const _Tp& __value = _Tp(), 78*404b540aSrobert const _Allocator& __a = _Allocator()) 79*404b540aSrobert : _Base(__n, __value, __a) { } 80*404b540aSrobert 81*404b540aSrobert template<class _InputIterator> 82*404b540aSrobert deque(_InputIterator __first, _InputIterator __last, 83*404b540aSrobert const _Allocator& __a = _Allocator()) 84*404b540aSrobert : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) 85*404b540aSrobert { } 86*404b540aSrobert 87*404b540aSrobert deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } 88*404b540aSrobert 89*404b540aSrobert deque(const _Base& __x) : _Base(__x), _Safe_base() { } 90*404b540aSrobert 91*404b540aSrobert ~deque() { } 92*404b540aSrobert 93*404b540aSrobert deque<_Tp,_Allocator>& 94*404b540aSrobert operator=(const deque<_Tp,_Allocator>& __x) 95*404b540aSrobert { 96*404b540aSrobert *static_cast<_Base*>(this) = __x; 97*404b540aSrobert this->_M_invalidate_all(); 98*404b540aSrobert return *this; 99*404b540aSrobert } 100*404b540aSrobert 101*404b540aSrobert template<class _InputIterator> 102*404b540aSrobert void 103*404b540aSrobert assign(_InputIterator __first, _InputIterator __last) 104*404b540aSrobert { 105*404b540aSrobert __glibcxx_check_valid_range(__first, __last); 106*404b540aSrobert _Base::assign(__first, __last); 107*404b540aSrobert this->_M_invalidate_all(); 108*404b540aSrobert } 109*404b540aSrobert 110*404b540aSrobert void 111*404b540aSrobert assign(size_type __n, const _Tp& __t) 112*404b540aSrobert { 113*404b540aSrobert _Base::assign(__n, __t); 114*404b540aSrobert this->_M_invalidate_all(); 115*404b540aSrobert } 116*404b540aSrobert 117*404b540aSrobert using _Base::get_allocator; 118*404b540aSrobert 119*404b540aSrobert // iterators: 120*404b540aSrobert iterator 121*404b540aSrobert begin() 122*404b540aSrobert { return iterator(_Base::begin(), this); } 123*404b540aSrobert 124*404b540aSrobert const_iterator 125*404b540aSrobert begin() const 126*404b540aSrobert { return const_iterator(_Base::begin(), this); } 127*404b540aSrobert 128*404b540aSrobert iterator 129*404b540aSrobert end() 130*404b540aSrobert { return iterator(_Base::end(), this); } 131*404b540aSrobert 132*404b540aSrobert const_iterator 133*404b540aSrobert end() const 134*404b540aSrobert { return const_iterator(_Base::end(), this); } 135*404b540aSrobert 136*404b540aSrobert reverse_iterator 137*404b540aSrobert rbegin() 138*404b540aSrobert { return reverse_iterator(end()); } 139*404b540aSrobert 140*404b540aSrobert const_reverse_iterator 141*404b540aSrobert rbegin() const 142*404b540aSrobert { return const_reverse_iterator(end()); } 143*404b540aSrobert 144*404b540aSrobert reverse_iterator 145*404b540aSrobert rend() 146*404b540aSrobert { return reverse_iterator(begin()); } 147*404b540aSrobert 148*404b540aSrobert const_reverse_iterator 149*404b540aSrobert rend() const 150*404b540aSrobert { return const_reverse_iterator(begin()); } 151*404b540aSrobert 152*404b540aSrobert // 23.2.1.2 capacity: 153*404b540aSrobert using _Base::size; 154*404b540aSrobert using _Base::max_size; 155*404b540aSrobert 156*404b540aSrobert void 157*404b540aSrobert resize(size_type __sz, _Tp __c = _Tp()) 158*404b540aSrobert { 159*404b540aSrobert typedef typename _Base::const_iterator _Base_const_iterator; 160*404b540aSrobert typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 161*404b540aSrobert 162*404b540aSrobert bool __invalidate_all = __sz > this->size(); 163*404b540aSrobert if (__sz < this->size()) 164*404b540aSrobert this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); 165*404b540aSrobert 166*404b540aSrobert _Base::resize(__sz, __c); 167*404b540aSrobert 168*404b540aSrobert if (__invalidate_all) 169*404b540aSrobert this->_M_invalidate_all(); 170*404b540aSrobert } 171*404b540aSrobert 172*404b540aSrobert using _Base::empty; 173*404b540aSrobert 174*404b540aSrobert // element access: 175*404b540aSrobert reference 176*404b540aSrobert operator[](size_type __n) 177*404b540aSrobert { 178*404b540aSrobert __glibcxx_check_subscript(__n); 179*404b540aSrobert return _M_base()[__n]; 180*404b540aSrobert } 181*404b540aSrobert 182*404b540aSrobert const_reference 183*404b540aSrobert operator[](size_type __n) const 184*404b540aSrobert { 185*404b540aSrobert __glibcxx_check_subscript(__n); 186*404b540aSrobert return _M_base()[__n]; 187*404b540aSrobert } 188*404b540aSrobert 189*404b540aSrobert using _Base::at; 190*404b540aSrobert 191*404b540aSrobert reference 192*404b540aSrobert front() 193*404b540aSrobert { 194*404b540aSrobert __glibcxx_check_nonempty(); 195*404b540aSrobert return _Base::front(); 196*404b540aSrobert } 197*404b540aSrobert 198*404b540aSrobert const_reference 199*404b540aSrobert front() const 200*404b540aSrobert { 201*404b540aSrobert __glibcxx_check_nonempty(); 202*404b540aSrobert return _Base::front(); 203*404b540aSrobert } 204*404b540aSrobert 205*404b540aSrobert reference 206*404b540aSrobert back() 207*404b540aSrobert { 208*404b540aSrobert __glibcxx_check_nonempty(); 209*404b540aSrobert return _Base::back(); 210*404b540aSrobert } 211*404b540aSrobert 212*404b540aSrobert const_reference 213*404b540aSrobert back() const 214*404b540aSrobert { 215*404b540aSrobert __glibcxx_check_nonempty(); 216*404b540aSrobert return _Base::back(); 217*404b540aSrobert } 218*404b540aSrobert 219*404b540aSrobert // 23.2.1.3 modifiers: 220*404b540aSrobert void 221*404b540aSrobert push_front(const _Tp& __x) 222*404b540aSrobert { 223*404b540aSrobert _Base::push_front(__x); 224*404b540aSrobert this->_M_invalidate_all(); 225*404b540aSrobert } 226*404b540aSrobert 227*404b540aSrobert void 228*404b540aSrobert push_back(const _Tp& __x) 229*404b540aSrobert { 230*404b540aSrobert _Base::push_back(__x); 231*404b540aSrobert this->_M_invalidate_all(); 232*404b540aSrobert } 233*404b540aSrobert 234*404b540aSrobert iterator 235*404b540aSrobert insert(iterator __position, const _Tp& __x) 236*404b540aSrobert { 237*404b540aSrobert __glibcxx_check_insert(__position); 238*404b540aSrobert typename _Base::iterator __res = _Base::insert(__position.base(), __x); 239*404b540aSrobert this->_M_invalidate_all(); 240*404b540aSrobert return iterator(__res, this); 241*404b540aSrobert } 242*404b540aSrobert 243*404b540aSrobert void 244*404b540aSrobert insert(iterator __position, size_type __n, const _Tp& __x) 245*404b540aSrobert { 246*404b540aSrobert __glibcxx_check_insert(__position); 247*404b540aSrobert _Base::insert(__position.base(), __n, __x); 248*404b540aSrobert this->_M_invalidate_all(); 249*404b540aSrobert } 250*404b540aSrobert 251*404b540aSrobert template<class _InputIterator> 252*404b540aSrobert void 253*404b540aSrobert insert(iterator __position, 254*404b540aSrobert _InputIterator __first, _InputIterator __last) 255*404b540aSrobert { 256*404b540aSrobert __glibcxx_check_insert_range(__position, __first, __last); 257*404b540aSrobert _Base::insert(__position.base(), __first, __last); 258*404b540aSrobert this->_M_invalidate_all(); 259*404b540aSrobert } 260*404b540aSrobert 261*404b540aSrobert void 262*404b540aSrobert pop_front() 263*404b540aSrobert { 264*404b540aSrobert __glibcxx_check_nonempty(); 265*404b540aSrobert iterator __victim = begin(); 266*404b540aSrobert __victim._M_invalidate(); 267*404b540aSrobert _Base::pop_front(); 268*404b540aSrobert } 269*404b540aSrobert 270*404b540aSrobert void 271*404b540aSrobert pop_back() 272*404b540aSrobert { 273*404b540aSrobert __glibcxx_check_nonempty(); 274*404b540aSrobert iterator __victim = end(); 275*404b540aSrobert --__victim; 276*404b540aSrobert __victim._M_invalidate(); 277*404b540aSrobert _Base::pop_back(); 278*404b540aSrobert } 279*404b540aSrobert 280*404b540aSrobert iterator 281*404b540aSrobert erase(iterator __position) 282*404b540aSrobert { 283*404b540aSrobert __glibcxx_check_erase(__position); 284*404b540aSrobert if (__position == begin() || __position == end()-1) 285*404b540aSrobert { 286*404b540aSrobert __position._M_invalidate(); 287*404b540aSrobert return iterator(_Base::erase(__position.base()), this); 288*404b540aSrobert } 289*404b540aSrobert else 290*404b540aSrobert { 291*404b540aSrobert typename _Base::iterator __res = _Base::erase(__position.base()); 292*404b540aSrobert this->_M_invalidate_all(); 293*404b540aSrobert return iterator(__res, this); 294*404b540aSrobert } 295*404b540aSrobert } 296*404b540aSrobert 297*404b540aSrobert iterator 298*404b540aSrobert erase(iterator __first, iterator __last) 299*404b540aSrobert { 300*404b540aSrobert // _GLIBCXX_RESOLVE_LIB_DEFECTS 301*404b540aSrobert // 151. can't currently clear() empty container 302*404b540aSrobert __glibcxx_check_erase_range(__first, __last); 303*404b540aSrobert if (__first == begin() || __last == end()) 304*404b540aSrobert { 305*404b540aSrobert this->_M_detach_singular(); 306*404b540aSrobert for (iterator __position = __first; __position != __last; ) 307*404b540aSrobert { 308*404b540aSrobert iterator __victim = __position++; 309*404b540aSrobert __victim._M_invalidate(); 310*404b540aSrobert } 311*404b540aSrobert try 312*404b540aSrobert { 313*404b540aSrobert return iterator(_Base::erase(__first.base(), __last.base()), 314*404b540aSrobert this); 315*404b540aSrobert } 316*404b540aSrobert catch (...) 317*404b540aSrobert { 318*404b540aSrobert this->_M_revalidate_singular(); 319*404b540aSrobert __throw_exception_again; 320*404b540aSrobert } 321*404b540aSrobert } 322*404b540aSrobert else 323*404b540aSrobert { 324*404b540aSrobert typename _Base::iterator __res = _Base::erase(__first.base(), 325*404b540aSrobert __last.base()); 326*404b540aSrobert this->_M_invalidate_all(); 327*404b540aSrobert return iterator(__res, this); 328*404b540aSrobert } 329*404b540aSrobert } 330*404b540aSrobert 331*404b540aSrobert void 332*404b540aSrobert swap(deque<_Tp,_Allocator>& __x) 333*404b540aSrobert { 334*404b540aSrobert _Base::swap(__x); 335*404b540aSrobert this->_M_swap(__x); 336*404b540aSrobert } 337*404b540aSrobert 338*404b540aSrobert void 339*404b540aSrobert clear() 340*404b540aSrobert { 341*404b540aSrobert _Base::clear(); 342*404b540aSrobert this->_M_invalidate_all(); 343*404b540aSrobert } 344*404b540aSrobert 345*404b540aSrobert _Base& 346*404b540aSrobert _M_base() { return *this; } 347*404b540aSrobert 348*404b540aSrobert const _Base& 349*404b540aSrobert _M_base() const { return *this; } 350*404b540aSrobert }; 351*404b540aSrobert 352*404b540aSrobert template<typename _Tp, typename _Alloc> 353*404b540aSrobert inline bool 354*404b540aSrobert operator==(const deque<_Tp, _Alloc>& __lhs, 355*404b540aSrobert const deque<_Tp, _Alloc>& __rhs) 356*404b540aSrobert { return __lhs._M_base() == __rhs._M_base(); } 357*404b540aSrobert 358*404b540aSrobert template<typename _Tp, typename _Alloc> 359*404b540aSrobert inline bool 360*404b540aSrobert operator!=(const deque<_Tp, _Alloc>& __lhs, 361*404b540aSrobert const deque<_Tp, _Alloc>& __rhs) 362*404b540aSrobert { return __lhs._M_base() != __rhs._M_base(); } 363*404b540aSrobert 364*404b540aSrobert template<typename _Tp, typename _Alloc> 365*404b540aSrobert inline bool 366*404b540aSrobert operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) 367*404b540aSrobert { return __lhs._M_base() < __rhs._M_base(); } 368*404b540aSrobert 369*404b540aSrobert template<typename _Tp, typename _Alloc> 370*404b540aSrobert inline bool 371*404b540aSrobert operator<=(const deque<_Tp, _Alloc>& __lhs, 372*404b540aSrobert const deque<_Tp, _Alloc>& __rhs) 373*404b540aSrobert { return __lhs._M_base() <= __rhs._M_base(); } 374*404b540aSrobert 375*404b540aSrobert template<typename _Tp, typename _Alloc> 376*404b540aSrobert inline bool 377*404b540aSrobert operator>=(const deque<_Tp, _Alloc>& __lhs, 378*404b540aSrobert const deque<_Tp, _Alloc>& __rhs) 379*404b540aSrobert { return __lhs._M_base() >= __rhs._M_base(); } 380*404b540aSrobert 381*404b540aSrobert template<typename _Tp, typename _Alloc> 382*404b540aSrobert inline bool 383*404b540aSrobert operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) 384*404b540aSrobert { return __lhs._M_base() > __rhs._M_base(); } 385*404b540aSrobert 386*404b540aSrobert template<typename _Tp, typename _Alloc> 387*404b540aSrobert inline void 388*404b540aSrobert swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) 389*404b540aSrobert { __lhs.swap(__rhs); } 390*404b540aSrobert} // namespace __debug 391*404b540aSrobert} // namespace std 392*404b540aSrobert 393*404b540aSrobert#endif 394