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 #ifndef _GLIBCXX_DEBUG_VECTOR
00031 #define _GLIBCXX_DEBUG_VECTOR 1
00032
00033 #include <vector>
00034 #include <utility>
00035 #include <debug/safe_sequence.h>
00036 #include <debug/safe_iterator.h>
00037
00038 namespace std
00039 {
00040 namespace __debug
00041 {
00042
00043 template<typename _Tp,
00044 typename _Allocator = std::allocator<_Tp> >
00045 class vector
00046 : public _GLIBCXX_STD_D::vector<_Tp, _Allocator>,
00047 public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
00048 {
00049 typedef _GLIBCXX_STD_D::vector<_Tp, _Allocator> _Base;
00050 typedef __gnu_debug::_Safe_sequence<vector> _Safe_base;
00051
00052 typedef typename _Base::const_iterator _Base_const_iterator;
00053 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00054
00055 public:
00056 typedef typename _Base::reference reference;
00057 typedef typename _Base::const_reference const_reference;
00058
00059 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector>
00060 iterator;
00061 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
00062 const_iterator;
00063
00064 typedef typename _Base::size_type size_type;
00065 typedef typename _Base::difference_type difference_type;
00066
00067 typedef _Tp value_type;
00068 typedef _Allocator allocator_type;
00069 typedef typename _Base::pointer pointer;
00070 typedef typename _Base::const_pointer const_pointer;
00071 typedef std::reverse_iterator<iterator> reverse_iterator;
00072 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00073
00074
00075 explicit vector(const _Allocator& __a = _Allocator())
00076 : _Base(__a), _M_guaranteed_capacity(0) { }
00077
00078 explicit vector(size_type __n, const _Tp& __value = _Tp(),
00079 const _Allocator& __a = _Allocator())
00080 : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
00081
00082 template<class _InputIterator>
00083 vector(_InputIterator __first, _InputIterator __last,
00084 const _Allocator& __a = _Allocator())
00085 : _Base(__gnu_debug::__check_valid_range(__first, __last),
00086 __last, __a),
00087 _M_guaranteed_capacity(0)
00088 { _M_update_guaranteed_capacity(); }
00089
00090 vector(const vector& __x)
00091 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
00092
00093
00094 vector(const _Base& __x)
00095 : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
00096
00097 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00098 vector(vector&& __x)
00099 : _Base(std::forward<vector>(__x)), _Safe_base(),
00100 _M_guaranteed_capacity(this->size())
00101 {
00102 this->_M_swap(__x);
00103 __x._M_guaranteed_capacity = 0;
00104 }
00105
00106 vector(initializer_list<value_type> __l,
00107 const allocator_type& __a = allocator_type())
00108 : _Base(__l, __a), _Safe_base(),
00109 _M_guaranteed_capacity(__l.size()) { }
00110 #endif
00111
00112 ~vector() { }
00113
00114 vector&
00115 operator=(const vector& __x)
00116 {
00117 static_cast<_Base&>(*this) = __x;
00118 this->_M_invalidate_all();
00119 _M_update_guaranteed_capacity();
00120 return *this;
00121 }
00122
00123 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00124 vector&
00125 operator=(vector&& __x)
00126 {
00127
00128
00129 clear();
00130 swap(__x);
00131 return *this;
00132 }
00133
00134 vector&
00135 operator=(initializer_list<value_type> __l)
00136 {
00137 static_cast<_Base&>(*this) = __l;
00138 this->_M_invalidate_all();
00139 _M_update_guaranteed_capacity();
00140 return *this;
00141 }
00142 #endif
00143
00144 template<typename _InputIterator>
00145 void
00146 assign(_InputIterator __first, _InputIterator __last)
00147 {
00148 __glibcxx_check_valid_range(__first, __last);
00149 _Base::assign(__first, __last);
00150 this->_M_invalidate_all();
00151 _M_update_guaranteed_capacity();
00152 }
00153
00154 void
00155 assign(size_type __n, const _Tp& __u)
00156 {
00157 _Base::assign(__n, __u);
00158 this->_M_invalidate_all();
00159 _M_update_guaranteed_capacity();
00160 }
00161
00162 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00163 void
00164 assign(initializer_list<value_type> __l)
00165 {
00166 _Base::assign(__l);
00167 this->_M_invalidate_all();
00168 _M_update_guaranteed_capacity();
00169 }
00170 #endif
00171
00172 using _Base::get_allocator;
00173
00174
00175 iterator
00176 begin()
00177 { return iterator(_Base::begin(), this); }
00178
00179 const_iterator
00180 begin() const
00181 { return const_iterator(_Base::begin(), this); }
00182
00183 iterator
00184 end()
00185 { return iterator(_Base::end(), this); }
00186
00187 const_iterator
00188 end() const
00189 { return const_iterator(_Base::end(), this); }
00190
00191 reverse_iterator
00192 rbegin()
00193 { return reverse_iterator(end()); }
00194
00195 const_reverse_iterator
00196 rbegin() const
00197 { return const_reverse_iterator(end()); }
00198
00199 reverse_iterator
00200 rend()
00201 { return reverse_iterator(begin()); }
00202
00203 const_reverse_iterator
00204 rend() const
00205 { return const_reverse_iterator(begin()); }
00206
00207 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00208 const_iterator
00209 cbegin() const
00210 { return const_iterator(_Base::begin(), this); }
00211
00212 const_iterator
00213 cend() const
00214 { return const_iterator(_Base::end(), this); }
00215
00216 const_reverse_iterator
00217 crbegin() const
00218 { return const_reverse_iterator(end()); }
00219
00220 const_reverse_iterator
00221 crend() const
00222 { return const_reverse_iterator(begin()); }
00223 #endif
00224
00225
00226 using _Base::size;
00227 using _Base::max_size;
00228
00229 void
00230 resize(size_type __sz, _Tp __c = _Tp())
00231 {
00232 bool __realloc = _M_requires_reallocation(__sz);
00233 if (__sz < this->size())
00234 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
00235 _Base::resize(__sz, __c);
00236 if (__realloc)
00237 this->_M_invalidate_all();
00238 }
00239
00240 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00241 using _Base::shrink_to_fit;
00242 #endif
00243
00244 size_type
00245 capacity() const
00246 {
00247 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00248 return _M_guaranteed_capacity;
00249 #else
00250 return _Base::capacity();
00251 #endif
00252 }
00253
00254 using _Base::empty;
00255
00256 void
00257 reserve(size_type __n)
00258 {
00259 bool __realloc = _M_requires_reallocation(__n);
00260 _Base::reserve(__n);
00261 if (__n > _M_guaranteed_capacity)
00262 _M_guaranteed_capacity = __n;
00263 if (__realloc)
00264 this->_M_invalidate_all();
00265 }
00266
00267
00268 reference
00269 operator[](size_type __n)
00270 {
00271 __glibcxx_check_subscript(__n);
00272 return _M_base()[__n];
00273 }
00274
00275 const_reference
00276 operator[](size_type __n) const
00277 {
00278 __glibcxx_check_subscript(__n);
00279 return _M_base()[__n];
00280 }
00281
00282 using _Base::at;
00283
00284 reference
00285 front()
00286 {
00287 __glibcxx_check_nonempty();
00288 return _Base::front();
00289 }
00290
00291 const_reference
00292 front() const
00293 {
00294 __glibcxx_check_nonempty();
00295 return _Base::front();
00296 }
00297
00298 reference
00299 back()
00300 {
00301 __glibcxx_check_nonempty();
00302 return _Base::back();
00303 }
00304
00305 const_reference
00306 back() const
00307 {
00308 __glibcxx_check_nonempty();
00309 return _Base::back();
00310 }
00311
00312
00313
00314 using _Base::data;
00315
00316
00317 void
00318 push_back(const _Tp& __x)
00319 {
00320 bool __realloc = _M_requires_reallocation(this->size() + 1);
00321 _Base::push_back(__x);
00322 if (__realloc)
00323 this->_M_invalidate_all();
00324 _M_update_guaranteed_capacity();
00325 }
00326
00327 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00328 template<typename _Up = _Tp>
00329 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00330 void>::__type
00331 push_back(_Tp&& __x)
00332 { emplace_back(std::move(__x)); }
00333
00334 template<typename... _Args>
00335 void
00336 emplace_back(_Args&&... __args)
00337 {
00338 bool __realloc = _M_requires_reallocation(this->size() + 1);
00339 _Base::emplace_back(std::forward<_Args>(__args)...);
00340 if (__realloc)
00341 this->_M_invalidate_all();
00342 _M_update_guaranteed_capacity();
00343 }
00344 #endif
00345
00346 void
00347 pop_back()
00348 {
00349 __glibcxx_check_nonempty();
00350 iterator __victim = end() - 1;
00351 __victim._M_invalidate();
00352 _Base::pop_back();
00353 }
00354
00355 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00356 template<typename... _Args>
00357 iterator
00358 emplace(iterator __position, _Args&&... __args)
00359 {
00360 __glibcxx_check_insert(__position);
00361 bool __realloc = _M_requires_reallocation(this->size() + 1);
00362 difference_type __offset = __position - begin();
00363 typename _Base::iterator __res = _Base::emplace(__position.base(),
00364 std::forward<_Args>(__args)...);
00365 if (__realloc)
00366 this->_M_invalidate_all();
00367 else
00368 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00369 _M_update_guaranteed_capacity();
00370 return iterator(__res, this);
00371 }
00372 #endif
00373
00374 iterator
00375 insert(iterator __position, const _Tp& __x)
00376 {
00377 __glibcxx_check_insert(__position);
00378 bool __realloc = _M_requires_reallocation(this->size() + 1);
00379 difference_type __offset = __position - begin();
00380 typename _Base::iterator __res = _Base::insert(__position.base(),__x);
00381 if (__realloc)
00382 this->_M_invalidate_all();
00383 else
00384 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00385 _M_update_guaranteed_capacity();
00386 return iterator(__res, this);
00387 }
00388
00389 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00390 template<typename _Up = _Tp>
00391 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00392 iterator>::__type
00393 insert(iterator __position, _Tp&& __x)
00394 { return emplace(__position, std::move(__x)); }
00395
00396 void
00397 insert(iterator __position, initializer_list<value_type> __l)
00398 { this->insert(__position, __l.begin(), __l.end()); }
00399 #endif
00400
00401 void
00402 insert(iterator __position, size_type __n, const _Tp& __x)
00403 {
00404 __glibcxx_check_insert(__position);
00405 bool __realloc = _M_requires_reallocation(this->size() + __n);
00406 difference_type __offset = __position - begin();
00407 _Base::insert(__position.base(), __n, __x);
00408 if (__realloc)
00409 this->_M_invalidate_all();
00410 else
00411 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00412 _M_update_guaranteed_capacity();
00413 }
00414
00415 template<class _InputIterator>
00416 void
00417 insert(iterator __position,
00418 _InputIterator __first, _InputIterator __last)
00419 {
00420 __glibcxx_check_insert_range(__position, __first, __last);
00421
00422
00423
00424
00425 typename _Base::iterator __old_begin = _M_base().begin();
00426 difference_type __offset = __position - begin();
00427 _Base::insert(__position.base(), __first, __last);
00428
00429 if (_M_base().begin() != __old_begin)
00430 this->_M_invalidate_all();
00431 else
00432 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00433 _M_update_guaranteed_capacity();
00434 }
00435
00436 iterator
00437 erase(iterator __position)
00438 {
00439 __glibcxx_check_erase(__position);
00440 difference_type __offset = __position - begin();
00441 typename _Base::iterator __res = _Base::erase(__position.base());
00442 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00443 return iterator(__res, this);
00444 }
00445
00446 iterator
00447 erase(iterator __first, iterator __last)
00448 {
00449
00450
00451 __glibcxx_check_erase_range(__first, __last);
00452
00453 difference_type __offset = __first - begin();
00454 typename _Base::iterator __res = _Base::erase(__first.base(),
00455 __last.base());
00456 this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
00457 return iterator(__res, this);
00458 }
00459
00460 void
00461 swap(vector& __x)
00462 {
00463 _Base::swap(__x);
00464 this->_M_swap(__x);
00465 std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
00466 }
00467
00468 void
00469 clear()
00470 {
00471 _Base::clear();
00472 this->_M_invalidate_all();
00473 _M_guaranteed_capacity = 0;
00474 }
00475
00476 _Base&
00477 _M_base() { return *this; }
00478
00479 const _Base&
00480 _M_base() const { return *this; }
00481
00482 private:
00483 size_type _M_guaranteed_capacity;
00484
00485 bool
00486 _M_requires_reallocation(size_type __elements)
00487 { return __elements > this->capacity(); }
00488
00489 void
00490 _M_update_guaranteed_capacity()
00491 {
00492 if (this->size() > _M_guaranteed_capacity)
00493 _M_guaranteed_capacity = this->size();
00494 }
00495 };
00496
00497 template<typename _Tp, typename _Alloc>
00498 inline bool
00499 operator==(const vector<_Tp, _Alloc>& __lhs,
00500 const vector<_Tp, _Alloc>& __rhs)
00501 { return __lhs._M_base() == __rhs._M_base(); }
00502
00503 template<typename _Tp, typename _Alloc>
00504 inline bool
00505 operator!=(const vector<_Tp, _Alloc>& __lhs,
00506 const vector<_Tp, _Alloc>& __rhs)
00507 { return __lhs._M_base() != __rhs._M_base(); }
00508
00509 template<typename _Tp, typename _Alloc>
00510 inline bool
00511 operator<(const vector<_Tp, _Alloc>& __lhs,
00512 const vector<_Tp, _Alloc>& __rhs)
00513 { return __lhs._M_base() < __rhs._M_base(); }
00514
00515 template<typename _Tp, typename _Alloc>
00516 inline bool
00517 operator<=(const vector<_Tp, _Alloc>& __lhs,
00518 const vector<_Tp, _Alloc>& __rhs)
00519 { return __lhs._M_base() <= __rhs._M_base(); }
00520
00521 template<typename _Tp, typename _Alloc>
00522 inline bool
00523 operator>=(const vector<_Tp, _Alloc>& __lhs,
00524 const vector<_Tp, _Alloc>& __rhs)
00525 { return __lhs._M_base() >= __rhs._M_base(); }
00526
00527 template<typename _Tp, typename _Alloc>
00528 inline bool
00529 operator>(const vector<_Tp, _Alloc>& __lhs,
00530 const vector<_Tp, _Alloc>& __rhs)
00531 { return __lhs._M_base() > __rhs._M_base(); }
00532
00533 template<typename _Tp, typename _Alloc>
00534 inline void
00535 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00536 { __lhs.swap(__rhs); }
00537
00538 }
00539 }
00540
00541 #endif