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