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 <debug/safe_sequence.h>
00036 #include <debug/safe_iterator.h>
00037 #include <utility>
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 _Allocator::pointer pointer;
00068 typedef typename _Allocator::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
00091
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 void
00235 push_back(const _Tp& __x)
00236 {
00237 bool __realloc = _M_requires_reallocation(this->size() + 1);
00238 _Base::push_back(__x);
00239 if (__realloc)
00240 this->_M_invalidate_all();
00241 _M_update_guaranteed_capacity();
00242 }
00243
00244 void
00245 pop_back()
00246 {
00247 __glibcxx_check_nonempty();
00248 iterator __victim = end() - 1;
00249 __victim._M_invalidate();
00250 _Base::pop_back();
00251 }
00252
00253 iterator
00254 insert(iterator __position, const _Tp& __x)
00255 {
00256 __glibcxx_check_insert(__position);
00257 bool __realloc = _M_requires_reallocation(this->size() + 1);
00258 difference_type __offset = __position - begin();
00259 typename _Base::iterator __res = _Base::insert(__position.base(),__x);
00260 if (__realloc)
00261 this->_M_invalidate_all();
00262 else
00263 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00264 _M_update_guaranteed_capacity();
00265 return iterator(__res, this);
00266 }
00267
00268 void
00269 insert(iterator __position, size_type __n, const _Tp& __x)
00270 {
00271 __glibcxx_check_insert(__position);
00272 bool __realloc = _M_requires_reallocation(this->size() + __n);
00273 difference_type __offset = __position - begin();
00274 _Base::insert(__position.base(), __n, __x);
00275 if (__realloc)
00276 this->_M_invalidate_all();
00277 else
00278 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00279 _M_update_guaranteed_capacity();
00280 }
00281
00282 template<class _InputIterator>
00283 void
00284 insert(iterator __position,
00285 _InputIterator __first, _InputIterator __last)
00286 {
00287 __glibcxx_check_insert_range(__position, __first, __last);
00288
00289
00290
00291
00292 typename _Base::iterator __old_begin = _M_base().begin();
00293 difference_type __offset = __position - begin();
00294 _Base::insert(__position.base(), __first, __last);
00295
00296 if (_M_base().begin() != __old_begin)
00297 this->_M_invalidate_all();
00298 else
00299 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00300 _M_update_guaranteed_capacity();
00301 }
00302
00303 iterator
00304 erase(iterator __position)
00305 {
00306 __glibcxx_check_erase(__position);
00307 difference_type __offset = __position - begin();
00308 typename _Base::iterator __res = _Base::erase(__position.base());
00309 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00310 return iterator(__res, this);
00311 }
00312
00313 iterator
00314 erase(iterator __first, iterator __last)
00315 {
00316
00317
00318 __glibcxx_check_erase_range(__first, __last);
00319
00320 difference_type __offset = __first - begin();
00321 typename _Base::iterator __res = _Base::erase(__first.base(),
00322 __last.base());
00323 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00324 return iterator(__res, this);
00325 }
00326
00327 void
00328 swap(vector<_Tp,_Allocator>& __x)
00329 {
00330 _Base::swap(__x);
00331 this->_M_swap(__x);
00332 std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
00333 }
00334
00335 void
00336 clear()
00337 {
00338 _Base::clear();
00339 this->_M_invalidate_all();
00340 _M_guaranteed_capacity = 0;
00341 }
00342
00343 _Base&
00344 _M_base() { return *this; }
00345
00346 const _Base&
00347 _M_base() const { return *this; }
00348
00349 private:
00350 size_type _M_guaranteed_capacity;
00351
00352 bool
00353 _M_requires_reallocation(size_type __elements)
00354 {
00355 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00356 return __elements > this->capacity();
00357 #else
00358 return __elements > _M_guaranteed_capacity;
00359 #endif
00360 }
00361
00362 void
00363 _M_update_guaranteed_capacity()
00364 {
00365 if (this->size() > _M_guaranteed_capacity)
00366 _M_guaranteed_capacity = this->size();
00367 }
00368 };
00369
00370 template<typename _Tp, typename _Alloc>
00371 inline bool
00372 operator==(const vector<_Tp, _Alloc>& __lhs,
00373 const vector<_Tp, _Alloc>& __rhs)
00374 { return __lhs._M_base() == __rhs._M_base(); }
00375
00376 template<typename _Tp, typename _Alloc>
00377 inline bool
00378 operator!=(const vector<_Tp, _Alloc>& __lhs,
00379 const vector<_Tp, _Alloc>& __rhs)
00380 { return __lhs._M_base() != __rhs._M_base(); }
00381
00382 template<typename _Tp, typename _Alloc>
00383 inline bool
00384 operator<(const vector<_Tp, _Alloc>& __lhs,
00385 const vector<_Tp, _Alloc>& __rhs)
00386 { return __lhs._M_base() < __rhs._M_base(); }
00387
00388 template<typename _Tp, typename _Alloc>
00389 inline bool
00390 operator<=(const vector<_Tp, _Alloc>& __lhs,
00391 const vector<_Tp, _Alloc>& __rhs)
00392 { return __lhs._M_base() <= __rhs._M_base(); }
00393
00394 template<typename _Tp, typename _Alloc>
00395 inline bool
00396 operator>=(const vector<_Tp, _Alloc>& __lhs,
00397 const vector<_Tp, _Alloc>& __rhs)
00398 { return __lhs._M_base() >= __rhs._M_base(); }
00399
00400 template<typename _Tp, typename _Alloc>
00401 inline bool
00402 operator>(const vector<_Tp, _Alloc>& __lhs,
00403 const vector<_Tp, _Alloc>& __rhs)
00404 { return __lhs._M_base() > __rhs._M_base(); }
00405
00406 template<typename _Tp, typename _Alloc>
00407 inline void
00408 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00409 { __lhs.swap(__rhs); }
00410 }
00411
00412 #endif