00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _GLIBCXX_DEBUG_VECTOR
00032 #define _GLIBCXX_DEBUG_VECTOR 1
00033
00034 #include <vector>
00035 #include <utility>
00036 #include <debug/safe_sequence.h>
00037 #include <debug/safe_iterator.h>
00038
00039 namespace __gnu_debug_def
00040 {
00041 template<typename _Tp,
00042 typename _Allocator = std::allocator<_Tp> >
00043 class vector
00044 : public _GLIBCXX_STD::vector<_Tp, _Allocator>,
00045 public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
00046 {
00047 typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base;
00048 typedef __gnu_debug::_Safe_sequence<vector> _Safe_base;
00049
00050 typedef typename _Base::const_iterator _Base_const_iterator;
00051 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00052
00053 public:
00054 typedef typename _Base::reference reference;
00055 typedef typename _Base::const_reference const_reference;
00056
00057 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector>
00058 iterator;
00059 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
00060 const_iterator;
00061
00062 typedef typename _Base::size_type size_type;
00063 typedef typename _Base::difference_type difference_type;
00064
00065 typedef _Tp value_type;
00066 typedef _Allocator allocator_type;
00067 typedef typename _Base::pointer pointer;
00068 typedef typename _Base::const_pointer const_pointer;
00069 typedef std::reverse_iterator<iterator> reverse_iterator;
00070 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00071
00072
00073 explicit vector(const _Allocator& __a = _Allocator())
00074 : _Base(__a), _M_guaranteed_capacity(0) { }
00075
00076 explicit vector(size_type __n, const _Tp& __value = _Tp(),
00077 const _Allocator& __a = _Allocator())
00078 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
00079
00080 template<class _InputIterator>
00081 vector(_InputIterator __first, _InputIterator __last,
00082 const _Allocator& __a = _Allocator())
00083 : _Base(__gnu_debug::__check_valid_range(__first, __last),
00084 __last, __a),
00085 _M_guaranteed_capacity(0)
00086 { _M_update_guaranteed_capacity(); }
00087
00088 vector(const vector<_Tp,_Allocator>& __x)
00089 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
00090
00092 vector(const _Base& __x)
00093 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
00094
00095 ~vector() { }
00096
00097 vector<_Tp,_Allocator>&
00098 operator=(const vector<_Tp,_Allocator>& __x)
00099 {
00100 static_cast<_Base&>(*this) = __x;
00101 this->_M_invalidate_all();
00102 _M_update_guaranteed_capacity();
00103 return *this;
00104 }
00105
00106 template<typename _InputIterator>
00107 void
00108 assign(_InputIterator __first, _InputIterator __last)
00109 {
00110 __glibcxx_check_valid_range(__first, __last);
00111 _Base::assign(__first, __last);
00112 this->_M_invalidate_all();
00113 _M_update_guaranteed_capacity();
00114 }
00115
00116 void
00117 assign(size_type __n, const _Tp& __u)
00118 {
00119 _Base::assign(__n, __u);
00120 this->_M_invalidate_all();
00121 _M_update_guaranteed_capacity();
00122 }
00123
00124 using _Base::get_allocator;
00125
00126
00127 iterator
00128 begin()
00129 { return iterator(_Base::begin(), this); }
00130
00131 const_iterator
00132 begin() const
00133 { return const_iterator(_Base::begin(), this); }
00134
00135 iterator
00136 end()
00137 { return iterator(_Base::end(), this); }
00138
00139 const_iterator
00140 end() const
00141 { return const_iterator(_Base::end(), this); }
00142
00143 reverse_iterator
00144 rbegin()
00145 { return reverse_iterator(end()); }
00146
00147 const_reverse_iterator
00148 rbegin() const
00149 { return const_reverse_iterator(end()); }
00150
00151 reverse_iterator
00152 rend()
00153 { return reverse_iterator(begin()); }
00154
00155 const_reverse_iterator
00156 rend() const
00157 { return const_reverse_iterator(begin()); }
00158
00159
00160 using _Base::size;
00161 using _Base::max_size;
00162
00163 void
00164 resize(size_type __sz, _Tp __c = _Tp())
00165 {
00166 bool __realloc = _M_requires_reallocation(__sz);
00167 if (__sz < this->size())
00168 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
00169 _Base::resize(__sz, __c);
00170 if (__realloc)
00171 this->_M_invalidate_all();
00172 }
00173
00174 using _Base::capacity;
00175 using _Base::empty;
00176
00177 void
00178 reserve(size_type __n)
00179 {
00180 bool __realloc = _M_requires_reallocation(__n);
00181 _Base::reserve(__n);
00182 if (__n > _M_guaranteed_capacity)
00183 _M_guaranteed_capacity = __n;
00184 if (__realloc)
00185 this->_M_invalidate_all();
00186 }
00187
00188
00189 reference
00190 operator[](size_type __n)
00191 {
00192 __glibcxx_check_subscript(__n);
00193 return _M_base()[__n];
00194 }
00195
00196 const_reference
00197 operator[](size_type __n) const
00198 {
00199 __glibcxx_check_subscript(__n);
00200 return _M_base()[__n];
00201 }
00202
00203 using _Base::at;
00204
00205 reference
00206 front()
00207 {
00208 __glibcxx_check_nonempty();
00209 return _Base::front();
00210 }
00211
00212 const_reference
00213 front() const
00214 {
00215 __glibcxx_check_nonempty();
00216 return _Base::front();
00217 }
00218
00219 reference
00220 back()
00221 {
00222 __glibcxx_check_nonempty();
00223 return _Base::back();
00224 }
00225
00226 const_reference
00227 back() const
00228 {
00229 __glibcxx_check_nonempty();
00230 return _Base::back();
00231 }
00232
00233
00234
00235 using _Base::data;
00236
00237
00238 void
00239 push_back(const _Tp& __x)
00240 {
00241 bool __realloc = _M_requires_reallocation(this->size() + 1);
00242 _Base::push_back(__x);
00243 if (__realloc)
00244 this->_M_invalidate_all();
00245 _M_update_guaranteed_capacity();
00246 }
00247
00248 void
00249 pop_back()
00250 {
00251 __glibcxx_check_nonempty();
00252 iterator __victim = end() - 1;
00253 __victim._M_invalidate();
00254 _Base::pop_back();
00255 }
00256
00257 iterator
00258 insert(iterator __position, const _Tp& __x)
00259 {
00260 __glibcxx_check_insert(__position);
00261 bool __realloc = _M_requires_reallocation(this->size() + 1);
00262 difference_type __offset = __position - begin();
00263 typename _Base::iterator __res = _Base::insert(__position.base(),__x);
00264 if (__realloc)
00265 this->_M_invalidate_all();
00266 else
00267 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00268 _M_update_guaranteed_capacity();
00269 return iterator(__res, this);
00270 }
00271
00272 void
00273 insert(iterator __position, size_type __n, const _Tp& __x)
00274 {
00275 __glibcxx_check_insert(__position);
00276 bool __realloc = _M_requires_reallocation(this->size() + __n);
00277 difference_type __offset = __position - begin();
00278 _Base::insert(__position.base(), __n, __x);
00279 if (__realloc)
00280 this->_M_invalidate_all();
00281 else
00282 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00283 _M_update_guaranteed_capacity();
00284 }
00285
00286 template<class _InputIterator>
00287 void
00288 insert(iterator __position,
00289 _InputIterator __first, _InputIterator __last)
00290 {
00291 __glibcxx_check_insert_range(__position, __first, __last);
00292
00293
00294
00295
00296 typename _Base::iterator __old_begin = _M_base().begin();
00297 difference_type __offset = __position - begin();
00298 _Base::insert(__position.base(), __first, __last);
00299
00300 if (_M_base().begin() != __old_begin)
00301 this->_M_invalidate_all();
00302 else
00303 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00304 _M_update_guaranteed_capacity();
00305 }
00306
00307 iterator
00308 erase(iterator __position)
00309 {
00310 __glibcxx_check_erase(__position);
00311 difference_type __offset = __position - begin();
00312 typename _Base::iterator __res = _Base::erase(__position.base());
00313 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00314 return iterator(__res, this);
00315 }
00316
00317 iterator
00318 erase(iterator __first, iterator __last)
00319 {
00320
00321
00322 __glibcxx_check_erase_range(__first, __last);
00323
00324 difference_type __offset = __first - begin();
00325 typename _Base::iterator __res = _Base::erase(__first.base(),
00326 __last.base());
00327 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00328 return iterator(__res, this);
00329 }
00330
00331 void
00332 swap(vector<_Tp,_Allocator>& __x)
00333 {
00334 _Base::swap(__x);
00335 this->_M_swap(__x);
00336 std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
00337 }
00338
00339 void
00340 clear()
00341 {
00342 _Base::clear();
00343 this->_M_invalidate_all();
00344 _M_guaranteed_capacity = 0;
00345 }
00346
00347 _Base&
00348 _M_base() { return *this; }
00349
00350 const _Base&
00351 _M_base() const { return *this; }
00352
00353 private:
00354 size_type _M_guaranteed_capacity;
00355
00356 bool
00357 _M_requires_reallocation(size_type __elements)
00358 {
00359 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00360 return __elements > this->capacity();
00361 #else
00362 return __elements > _M_guaranteed_capacity;
00363 #endif
00364 }
00365
00366 void
00367 _M_update_guaranteed_capacity()
00368 {
00369 if (this->size() > _M_guaranteed_capacity)
00370 _M_guaranteed_capacity = this->size();
00371 }
00372 };
00373
00374 template<typename _Tp, typename _Alloc>
00375 inline bool
00376 operator==(const vector<_Tp, _Alloc>& __lhs,
00377 const vector<_Tp, _Alloc>& __rhs)
00378 { return __lhs._M_base() == __rhs._M_base(); }
00379
00380 template<typename _Tp, typename _Alloc>
00381 inline bool
00382 operator!=(const vector<_Tp, _Alloc>& __lhs,
00383 const vector<_Tp, _Alloc>& __rhs)
00384 { return __lhs._M_base() != __rhs._M_base(); }
00385
00386 template<typename _Tp, typename _Alloc>
00387 inline bool
00388 operator<(const vector<_Tp, _Alloc>& __lhs,
00389 const vector<_Tp, _Alloc>& __rhs)
00390 { return __lhs._M_base() < __rhs._M_base(); }
00391
00392 template<typename _Tp, typename _Alloc>
00393 inline bool
00394 operator<=(const vector<_Tp, _Alloc>& __lhs,
00395 const vector<_Tp, _Alloc>& __rhs)
00396 { return __lhs._M_base() <= __rhs._M_base(); }
00397
00398 template<typename _Tp, typename _Alloc>
00399 inline bool
00400 operator>=(const vector<_Tp, _Alloc>& __lhs,
00401 const vector<_Tp, _Alloc>& __rhs)
00402 { return __lhs._M_base() >= __rhs._M_base(); }
00403
00404 template<typename _Tp, typename _Alloc>
00405 inline bool
00406 operator>(const vector<_Tp, _Alloc>& __lhs,
00407 const vector<_Tp, _Alloc>& __rhs)
00408 { return __lhs._M_base() > __rhs._M_base(); }
00409
00410 template<typename _Tp, typename _Alloc>
00411 inline void
00412 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00413 { __lhs.swap(__rhs); }
00414 }
00415
00416 #endif