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