deque

00001 // Debugging deque implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003, 2004 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 #ifndef _GLIBCXX_DEBUG_DEQUE 00032 #define _GLIBCXX_DEBUG_DEQUE 1 00033 00034 #include <deque> 00035 #include <debug/safe_sequence.h> 00036 #include <debug/safe_iterator.h> 00037 00038 namespace __gnu_debug_def 00039 { 00040 template<typename _Tp, typename _Allocator = std::allocator<_Tp> > 00041 class deque 00042 : public _GLIBCXX_STD::deque<_Tp, _Allocator>, 00043 public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > 00044 { 00045 typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; 00046 typedef __gnu_debug::_Safe_sequence<deque> _Safe_base; 00047 00048 public: 00049 typedef typename _Allocator::reference reference; 00050 typedef typename _Allocator::const_reference const_reference; 00051 00052 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> 00053 iterator; 00054 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque> 00055 const_iterator; 00056 00057 typedef typename _Base::size_type size_type; 00058 typedef typename _Base::difference_type difference_type; 00059 00060 typedef _Tp value_type; 00061 typedef _Allocator allocator_type; 00062 typedef typename _Allocator::pointer pointer; 00063 typedef typename _Allocator::const_pointer const_pointer; 00064 typedef std::reverse_iterator<iterator> reverse_iterator; 00065 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00066 00067 // 23.2.1.1 construct/copy/destroy: 00068 explicit deque(const _Allocator& __a = _Allocator()) 00069 : _Base(__a) { } 00070 00071 explicit deque(size_type __n, const _Tp& __value = _Tp(), 00072 const _Allocator& __a = _Allocator()) 00073 : _Base(__n, __value, __a) { } 00074 00075 template<class _InputIterator> 00076 deque(_InputIterator __first, _InputIterator __last, 00077 const _Allocator& __a = _Allocator()) 00078 : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) 00079 { } 00080 00081 deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } 00082 00083 deque(const _Base& __x) : _Base(__x), _Safe_base() { } 00084 00085 ~deque() { } 00086 00087 deque<_Tp,_Allocator>& 00088 operator=(const deque<_Tp,_Allocator>& __x) 00089 { 00090 *static_cast<_Base*>(this) = __x; 00091 this->_M_invalidate_all(); 00092 return *this; 00093 } 00094 00095 template<class _InputIterator> 00096 void 00097 assign(_InputIterator __first, _InputIterator __last) 00098 { 00099 __glibcxx_check_valid_range(__first, __last); 00100 _Base::assign(__first, __last); 00101 this->_M_invalidate_all(); 00102 } 00103 00104 void 00105 assign(size_type __n, const _Tp& __t) 00106 { 00107 _Base::assign(__n, __t); 00108 this->_M_invalidate_all(); 00109 } 00110 00111 using _Base::get_allocator; 00112 00113 // iterators: 00114 iterator 00115 begin() 00116 { return iterator(_Base::begin(), this); } 00117 00118 const_iterator 00119 begin() const 00120 { return const_iterator(_Base::begin(), this); } 00121 00122 iterator 00123 end() 00124 { return iterator(_Base::end(), this); } 00125 00126 const_iterator 00127 end() const 00128 { return const_iterator(_Base::end(), this); } 00129 00130 reverse_iterator 00131 rbegin() 00132 { return reverse_iterator(end()); } 00133 00134 const_reverse_iterator 00135 rbegin() const 00136 { return const_reverse_iterator(end()); } 00137 00138 reverse_iterator 00139 rend() 00140 { return reverse_iterator(begin()); } 00141 00142 const_reverse_iterator 00143 rend() const 00144 { return const_reverse_iterator(begin()); } 00145 00146 // 23.2.1.2 capacity: 00147 using _Base::size; 00148 using _Base::max_size; 00149 00150 void 00151 resize(size_type __sz, _Tp __c = _Tp()) 00152 { 00153 typedef typename _Base::const_iterator _Base_const_iterator; 00154 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 00155 00156 bool __invalidate_all = __sz > this->size(); 00157 if (__sz < this->size()) 00158 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); 00159 00160 _Base::resize(__sz, __c); 00161 00162 if (__invalidate_all) 00163 this->_M_invalidate_all(); 00164 } 00165 00166 using _Base::empty; 00167 00168 // element access: 00169 reference 00170 operator[](size_type __n) 00171 { 00172 __glibcxx_check_subscript(__n); 00173 return _M_base()[__n]; 00174 } 00175 00176 const_reference 00177 operator[](size_type __n) const 00178 { 00179 __glibcxx_check_subscript(__n); 00180 return _M_base()[__n]; 00181 } 00182 00183 using _Base::at; 00184 00185 reference 00186 front() 00187 { 00188 __glibcxx_check_nonempty(); 00189 return _Base::front(); 00190 } 00191 00192 const_reference 00193 front() const 00194 { 00195 __glibcxx_check_nonempty(); 00196 return _Base::front(); 00197 } 00198 00199 reference 00200 back() 00201 { 00202 __glibcxx_check_nonempty(); 00203 return _Base::back(); 00204 } 00205 00206 const_reference 00207 back() const 00208 { 00209 __glibcxx_check_nonempty(); 00210 return _Base::back(); 00211 } 00212 00213 // 23.2.1.3 modifiers: 00214 void 00215 push_front(const _Tp& __x) 00216 { 00217 _Base::push_front(__x); 00218 this->_M_invalidate_all(); 00219 } 00220 00221 void 00222 push_back(const _Tp& __x) 00223 { 00224 _Base::push_back(__x); 00225 this->_M_invalidate_all(); 00226 } 00227 00228 iterator 00229 insert(iterator __position, const _Tp& __x) 00230 { 00231 __glibcxx_check_insert(__position); 00232 typename _Base::iterator __res = _Base::insert(__position.base(), __x); 00233 this->_M_invalidate_all(); 00234 return iterator(__res, this); 00235 } 00236 00237 void 00238 insert(iterator __position, size_type __n, const _Tp& __x) 00239 { 00240 __glibcxx_check_insert(__position); 00241 _Base::insert(__position.base(), __n, __x); 00242 this->_M_invalidate_all(); 00243 } 00244 00245 template<class _InputIterator> 00246 void 00247 insert(iterator __position, 00248 _InputIterator __first, _InputIterator __last) 00249 { 00250 __glibcxx_check_insert_range(__position, __first, __last); 00251 _Base::insert(__position.base(), __first, __last); 00252 this->_M_invalidate_all(); 00253 } 00254 00255 void 00256 pop_front() 00257 { 00258 __glibcxx_check_nonempty(); 00259 iterator __victim = begin(); 00260 __victim._M_invalidate(); 00261 _Base::pop_front(); 00262 } 00263 00264 void 00265 pop_back() 00266 { 00267 __glibcxx_check_nonempty(); 00268 iterator __victim = end(); 00269 --__victim; 00270 __victim._M_invalidate(); 00271 _Base::pop_back(); 00272 } 00273 00274 iterator 00275 erase(iterator __position) 00276 { 00277 __glibcxx_check_erase(__position); 00278 if (__position == begin() || __position == end()-1) 00279 { 00280 __position._M_invalidate(); 00281 return iterator(_Base::erase(__position.base()), this); 00282 } 00283 else 00284 { 00285 typename _Base::iterator __res = _Base::erase(__position.base()); 00286 this->_M_invalidate_all(); 00287 return iterator(__res, this); 00288 } 00289 } 00290 00291 iterator 00292 erase(iterator __first, iterator __last) 00293 { 00294 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00295 // 151. can't currently clear() empty container 00296 __glibcxx_check_erase_range(__first, __last); 00297 if (__first == begin() || __last == end()) 00298 { 00299 this->_M_detach_singular(); 00300 for (iterator __position = __first; __position != __last; ) 00301 { 00302 iterator __victim = __position++; 00303 __victim._M_invalidate(); 00304 } 00305 try 00306 { 00307 return iterator(_Base::erase(__first.base(), __last.base()), 00308 this); 00309 } 00310 catch (...) 00311 { 00312 this->_M_revalidate_singular(); 00313 __throw_exception_again; 00314 } 00315 } 00316 else 00317 { 00318 typename _Base::iterator __res = _Base::erase(__first.base(), 00319 __last.base()); 00320 this->_M_invalidate_all(); 00321 return iterator(__res, this); 00322 } 00323 } 00324 00325 void 00326 swap(deque<_Tp,_Allocator>& __x) 00327 { 00328 _Base::swap(__x); 00329 this->_M_swap(__x); 00330 } 00331 00332 void 00333 clear() 00334 { 00335 _Base::clear(); 00336 this->_M_invalidate_all(); 00337 } 00338 00339 _Base& 00340 _M_base() { return *this; } 00341 00342 const _Base& 00343 _M_base() const { return *this; } 00344 }; 00345 00346 template<typename _Tp, typename _Alloc> 00347 inline bool 00348 operator==(const deque<_Tp, _Alloc>& __lhs, 00349 const deque<_Tp, _Alloc>& __rhs) 00350 { return __lhs._M_base() == __rhs._M_base(); } 00351 00352 template<typename _Tp, typename _Alloc> 00353 inline bool 00354 operator!=(const deque<_Tp, _Alloc>& __lhs, 00355 const deque<_Tp, _Alloc>& __rhs) 00356 { return __lhs._M_base() != __rhs._M_base(); } 00357 00358 template<typename _Tp, typename _Alloc> 00359 inline bool 00360 operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) 00361 { return __lhs._M_base() < __rhs._M_base(); } 00362 00363 template<typename _Tp, typename _Alloc> 00364 inline bool 00365 operator<=(const deque<_Tp, _Alloc>& __lhs, 00366 const deque<_Tp, _Alloc>& __rhs) 00367 { return __lhs._M_base() <= __rhs._M_base(); } 00368 00369 template<typename _Tp, typename _Alloc> 00370 inline bool 00371 operator>=(const deque<_Tp, _Alloc>& __lhs, 00372 const deque<_Tp, _Alloc>& __rhs) 00373 { return __lhs._M_base() >= __rhs._M_base(); } 00374 00375 template<typename _Tp, typename _Alloc> 00376 inline bool 00377 operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) 00378 { return __lhs._M_base() > __rhs._M_base(); } 00379 00380 template<typename _Tp, typename _Alloc> 00381 inline void 00382 swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) 00383 { __lhs.swap(__rhs); } 00384 } // namespace __gnu_debug_def 00385 00386 #endif

Generated on Wed Jun 9 11:18:18 2004 for libstdc++-v3 Source by doxygen 1.3.7