]>
Commit | Line | Data |
---|---|---|
285b36d6 BK |
1 | // Debugging vector implementation -*- C++ -*- |
2 | ||
405feeb8 | 3 | // Copyright (C) 2003-2013 Free Software Foundation, Inc. |
285b36d6 BK |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
285b36d6 BK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
285b36d6 | 24 | |
78a53887 BK |
25 | /** @file debug/vector |
26 | * This file is a GNU debug extension to the Standard C++ Library. | |
27 | */ | |
28 | ||
285b36d6 BK |
29 | #ifndef _GLIBCXX_DEBUG_VECTOR |
30 | #define _GLIBCXX_DEBUG_VECTOR 1 | |
31 | ||
32 | #include <vector> | |
d2763ab5 | 33 | #include <utility> |
285b36d6 BK |
34 | #include <debug/safe_sequence.h> |
35 | #include <debug/safe_iterator.h> | |
36 | ||
12ffa228 | 37 | namespace std _GLIBCXX_VISIBILITY(default) |
3cbc7af0 | 38 | { |
45f388bb | 39 | namespace __debug |
285b36d6 | 40 | { |
1ceb9e06 | 41 | /// Class std::vector with safety/checking/debug instrumentation. |
526da49c | 42 | template<typename _Tp, |
285b36d6 BK |
43 | typename _Allocator = std::allocator<_Tp> > |
44 | class vector | |
12ffa228 | 45 | : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, |
285b36d6 BK |
46 | public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > |
47 | { | |
12ffa228 | 48 | typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; |
285b36d6 | 49 | |
afe96d41 | 50 | typedef typename _Base::iterator _Base_iterator; |
285b36d6 | 51 | typedef typename _Base::const_iterator _Base_const_iterator; |
afe96d41 | 52 | typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; |
285b36d6 | 53 | |
734f5023 | 54 | #if __cplusplus >= 201103L |
42500675 JW |
55 | typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; |
56 | #endif | |
57 | ||
285b36d6 BK |
58 | public: |
59 | typedef typename _Base::reference reference; | |
60 | typedef typename _Base::const_reference const_reference; | |
61 | ||
afe96d41 | 62 | typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector> |
285b36d6 | 63 | iterator; |
afe96d41 | 64 | typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector> |
285b36d6 BK |
65 | const_iterator; |
66 | ||
67 | typedef typename _Base::size_type size_type; | |
68 | typedef typename _Base::difference_type difference_type; | |
69 | ||
526da49c BI |
70 | typedef _Tp value_type; |
71 | typedef _Allocator allocator_type; | |
09952acc PC |
72 | typedef typename _Base::pointer pointer; |
73 | typedef typename _Base::const_pointer const_pointer; | |
285b36d6 BK |
74 | typedef std::reverse_iterator<iterator> reverse_iterator; |
75 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
76 | ||
77 | // 23.2.4.1 construct/copy/destroy: | |
dc2cf706 | 78 | explicit |
757b1644 | 79 | vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT |
285b36d6 BK |
80 | : _Base(__a), _M_guaranteed_capacity(0) { } |
81 | ||
734f5023 | 82 | #if __cplusplus >= 201103L |
dc2cf706 | 83 | explicit |
d720a22b JW |
84 | vector(size_type __n, const _Allocator& __a = _Allocator()) |
85 | : _Base(__n, __a), _M_guaranteed_capacity(__n) { } | |
dc2cf706 PC |
86 | |
87 | vector(size_type __n, const _Tp& __value, | |
88 | const _Allocator& __a = _Allocator()) | |
285b36d6 | 89 | : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } |
dc2cf706 PC |
90 | #else |
91 | explicit | |
92 | vector(size_type __n, const _Tp& __value = _Tp(), | |
93 | const _Allocator& __a = _Allocator()) | |
94 | : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } | |
95 | #endif | |
285b36d6 | 96 | |
734f5023 | 97 | #if __cplusplus >= 201103L |
2203cb90 PC |
98 | template<class _InputIterator, |
99 | typename = std::_RequireInputIter<_InputIterator>> | |
100 | #else | |
285b36d6 | 101 | template<class _InputIterator> |
2203cb90 | 102 | #endif |
285b36d6 BK |
103 | vector(_InputIterator __first, _InputIterator __last, |
104 | const _Allocator& __a = _Allocator()) | |
1f5ca1a1 PC |
105 | : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, |
106 | __last)), | |
107 | __gnu_debug::__base(__last), __a), | |
285b36d6 BK |
108 | _M_guaranteed_capacity(0) |
109 | { _M_update_guaranteed_capacity(); } | |
110 | ||
ed540c0a | 111 | vector(const vector& __x) |
4c2d93db | 112 | : _Base(__x), _M_guaranteed_capacity(__x.size()) { } |
285b36d6 BK |
113 | |
114 | /// Construction from a release-mode vector | |
526da49c | 115 | vector(const _Base& __x) |
4c2d93db | 116 | : _Base(__x), _M_guaranteed_capacity(__x.size()) { } |
285b36d6 | 117 | |
734f5023 | 118 | #if __cplusplus >= 201103L |
6f59ea25 | 119 | vector(vector&& __x) noexcept |
4c2d93db | 120 | : _Base(std::move(__x)), |
cc8c030d PC |
121 | _M_guaranteed_capacity(this->size()) |
122 | { | |
ed540c0a CJ |
123 | this->_M_swap(__x); |
124 | __x._M_guaranteed_capacity = 0; | |
125 | } | |
988499f4 | 126 | |
42500675 JW |
127 | vector(const vector& __x, const allocator_type& __a) |
128 | : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { } | |
129 | ||
130 | vector(vector&& __x, const allocator_type& __a) | |
131 | : _Base(std::move(__x), __a), | |
132 | _M_guaranteed_capacity(this->size()) | |
133 | { | |
134 | __x._M_invalidate_all(); | |
135 | __x._M_guaranteed_capacity = 0; | |
136 | } | |
137 | ||
988499f4 JM |
138 | vector(initializer_list<value_type> __l, |
139 | const allocator_type& __a = allocator_type()) | |
4c2d93db | 140 | : _Base(__l, __a), |
b798df05 | 141 | _M_guaranteed_capacity(__l.size()) { } |
ed540c0a CJ |
142 | #endif |
143 | ||
6f59ea25 | 144 | ~vector() _GLIBCXX_NOEXCEPT { } |
285b36d6 | 145 | |
ed540c0a CJ |
146 | vector& |
147 | operator=(const vector& __x) | |
285b36d6 BK |
148 | { |
149 | static_cast<_Base&>(*this) = __x; | |
150 | this->_M_invalidate_all(); | |
151 | _M_update_guaranteed_capacity(); | |
152 | return *this; | |
153 | } | |
154 | ||
734f5023 | 155 | #if __cplusplus >= 201103L |
ed540c0a | 156 | vector& |
42500675 | 157 | operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) |
ed540c0a | 158 | { |
739fd6a6 | 159 | __glibcxx_check_self_move_assign(__x); |
42500675 JW |
160 | _Base::operator=(std::move(__x)); |
161 | this->_M_invalidate_all(); | |
162 | _M_update_guaranteed_capacity(); | |
163 | __x._M_invalidate_all(); | |
164 | __x._M_guaranteed_capacity = 0; | |
ed540c0a CJ |
165 | return *this; |
166 | } | |
988499f4 JM |
167 | |
168 | vector& | |
169 | operator=(initializer_list<value_type> __l) | |
170 | { | |
171 | static_cast<_Base&>(*this) = __l; | |
172 | this->_M_invalidate_all(); | |
173 | _M_update_guaranteed_capacity(); | |
174 | return *this; | |
175 | } | |
ed540c0a CJ |
176 | #endif |
177 | ||
734f5023 | 178 | #if __cplusplus >= 201103L |
2203cb90 PC |
179 | template<typename _InputIterator, |
180 | typename = std::_RequireInputIter<_InputIterator>> | |
181 | #else | |
285b36d6 | 182 | template<typename _InputIterator> |
2203cb90 | 183 | #endif |
526da49c | 184 | void |
285b36d6 BK |
185 | assign(_InputIterator __first, _InputIterator __last) |
186 | { | |
187 | __glibcxx_check_valid_range(__first, __last); | |
1f5ca1a1 PC |
188 | _Base::assign(__gnu_debug::__base(__first), |
189 | __gnu_debug::__base(__last)); | |
285b36d6 BK |
190 | this->_M_invalidate_all(); |
191 | _M_update_guaranteed_capacity(); | |
192 | } | |
193 | ||
526da49c | 194 | void |
285b36d6 BK |
195 | assign(size_type __n, const _Tp& __u) |
196 | { | |
197 | _Base::assign(__n, __u); | |
198 | this->_M_invalidate_all(); | |
199 | _M_update_guaranteed_capacity(); | |
200 | } | |
201 | ||
734f5023 | 202 | #if __cplusplus >= 201103L |
988499f4 JM |
203 | void |
204 | assign(initializer_list<value_type> __l) | |
205 | { | |
206 | _Base::assign(__l); | |
207 | this->_M_invalidate_all(); | |
208 | _M_update_guaranteed_capacity(); | |
209 | } | |
210 | #endif | |
211 | ||
285b36d6 BK |
212 | using _Base::get_allocator; |
213 | ||
214 | // iterators: | |
526da49c | 215 | iterator |
d3677132 | 216 | begin() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
217 | { return iterator(_Base::begin(), this); } |
218 | ||
526da49c | 219 | const_iterator |
d3677132 | 220 | begin() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
221 | { return const_iterator(_Base::begin(), this); } |
222 | ||
526da49c | 223 | iterator |
d3677132 | 224 | end() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
225 | { return iterator(_Base::end(), this); } |
226 | ||
526da49c | 227 | const_iterator |
d3677132 | 228 | end() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
229 | { return const_iterator(_Base::end(), this); } |
230 | ||
526da49c | 231 | reverse_iterator |
d3677132 | 232 | rbegin() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
233 | { return reverse_iterator(end()); } |
234 | ||
526da49c | 235 | const_reverse_iterator |
d3677132 | 236 | rbegin() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
237 | { return const_reverse_iterator(end()); } |
238 | ||
526da49c | 239 | reverse_iterator |
d3677132 | 240 | rend() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
241 | { return reverse_iterator(begin()); } |
242 | ||
526da49c | 243 | const_reverse_iterator |
d3677132 | 244 | rend() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
245 | { return const_reverse_iterator(begin()); } |
246 | ||
734f5023 | 247 | #if __cplusplus >= 201103L |
0cd50f89 | 248 | const_iterator |
d3677132 | 249 | cbegin() const noexcept |
0cd50f89 PC |
250 | { return const_iterator(_Base::begin(), this); } |
251 | ||
252 | const_iterator | |
d3677132 | 253 | cend() const noexcept |
0cd50f89 PC |
254 | { return const_iterator(_Base::end(), this); } |
255 | ||
256 | const_reverse_iterator | |
d3677132 | 257 | crbegin() const noexcept |
0cd50f89 PC |
258 | { return const_reverse_iterator(end()); } |
259 | ||
260 | const_reverse_iterator | |
d3677132 | 261 | crend() const noexcept |
0cd50f89 PC |
262 | { return const_reverse_iterator(begin()); } |
263 | #endif | |
264 | ||
285b36d6 BK |
265 | // 23.2.4.2 capacity: |
266 | using _Base::size; | |
267 | using _Base::max_size; | |
268 | ||
734f5023 | 269 | #if __cplusplus >= 201103L |
dc2cf706 PC |
270 | void |
271 | resize(size_type __sz) | |
272 | { | |
273 | bool __realloc = _M_requires_reallocation(__sz); | |
274 | if (__sz < this->size()) | |
afe96d41 | 275 | this->_M_invalidate_after_nth(__sz); |
dc2cf706 PC |
276 | _Base::resize(__sz); |
277 | if (__realloc) | |
278 | this->_M_invalidate_all(); | |
279 | _M_update_guaranteed_capacity(); | |
280 | } | |
281 | ||
282 | void | |
283 | resize(size_type __sz, const _Tp& __c) | |
284 | { | |
285 | bool __realloc = _M_requires_reallocation(__sz); | |
286 | if (__sz < this->size()) | |
afe96d41 | 287 | this->_M_invalidate_after_nth(__sz); |
dc2cf706 PC |
288 | _Base::resize(__sz, __c); |
289 | if (__realloc) | |
290 | this->_M_invalidate_all(); | |
291 | _M_update_guaranteed_capacity(); | |
292 | } | |
293 | #else | |
526da49c | 294 | void |
285b36d6 BK |
295 | resize(size_type __sz, _Tp __c = _Tp()) |
296 | { | |
297 | bool __realloc = _M_requires_reallocation(__sz); | |
298 | if (__sz < this->size()) | |
afe96d41 | 299 | this->_M_invalidate_after_nth(__sz); |
285b36d6 BK |
300 | _Base::resize(__sz, __c); |
301 | if (__realloc) | |
302 | this->_M_invalidate_all(); | |
ddc962a4 | 303 | _M_update_guaranteed_capacity(); |
285b36d6 | 304 | } |
dc2cf706 | 305 | #endif |
285b36d6 | 306 | |
734f5023 | 307 | #if __cplusplus >= 201103L |
8a752dfe FD |
308 | void |
309 | shrink_to_fit() | |
310 | { | |
311 | if (_Base::_M_shrink_to_fit()) | |
312 | { | |
313 | _M_guaranteed_capacity = _Base::capacity(); | |
314 | this->_M_invalidate_all(); | |
315 | } | |
316 | } | |
79667f82 PC |
317 | #endif |
318 | ||
2028b66d | 319 | size_type |
d3677132 | 320 | capacity() const _GLIBCXX_NOEXCEPT |
2028b66d SS |
321 | { |
322 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
323 | return _M_guaranteed_capacity; | |
324 | #else | |
325 | return _Base::capacity(); | |
326 | #endif | |
327 | } | |
328 | ||
285b36d6 BK |
329 | using _Base::empty; |
330 | ||
526da49c | 331 | void |
285b36d6 BK |
332 | reserve(size_type __n) |
333 | { | |
334 | bool __realloc = _M_requires_reallocation(__n); | |
335 | _Base::reserve(__n); | |
336 | if (__n > _M_guaranteed_capacity) | |
337 | _M_guaranteed_capacity = __n; | |
338 | if (__realloc) | |
339 | this->_M_invalidate_all(); | |
340 | } | |
341 | ||
342 | // element access: | |
526da49c | 343 | reference |
757b1644 | 344 | operator[](size_type __n) _GLIBCXX_NOEXCEPT |
285b36d6 BK |
345 | { |
346 | __glibcxx_check_subscript(__n); | |
347 | return _M_base()[__n]; | |
348 | } | |
349 | ||
526da49c | 350 | const_reference |
757b1644 | 351 | operator[](size_type __n) const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
352 | { |
353 | __glibcxx_check_subscript(__n); | |
354 | return _M_base()[__n]; | |
355 | } | |
356 | ||
357 | using _Base::at; | |
358 | ||
526da49c | 359 | reference |
757b1644 | 360 | front() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
361 | { |
362 | __glibcxx_check_nonempty(); | |
363 | return _Base::front(); | |
364 | } | |
365 | ||
526da49c | 366 | const_reference |
757b1644 | 367 | front() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
368 | { |
369 | __glibcxx_check_nonempty(); | |
370 | return _Base::front(); | |
371 | } | |
372 | ||
526da49c | 373 | reference |
757b1644 | 374 | back() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
375 | { |
376 | __glibcxx_check_nonempty(); | |
377 | return _Base::back(); | |
378 | } | |
379 | ||
526da49c | 380 | const_reference |
757b1644 | 381 | back() const _GLIBCXX_NOEXCEPT |
285b36d6 BK |
382 | { |
383 | __glibcxx_check_nonempty(); | |
384 | return _Base::back(); | |
385 | } | |
386 | ||
8b5f07a2 PC |
387 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
388 | // DR 464. Suggestion for new member functions in standard containers. | |
389 | using _Base::data; | |
390 | ||
285b36d6 | 391 | // 23.2.4.3 modifiers: |
526da49c | 392 | void |
285b36d6 BK |
393 | push_back(const _Tp& __x) |
394 | { | |
395 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
396 | _Base::push_back(__x); | |
397 | if (__realloc) | |
398 | this->_M_invalidate_all(); | |
399 | _M_update_guaranteed_capacity(); | |
400 | } | |
4dc3e453 | 401 | |
734f5023 | 402 | #if __cplusplus >= 201103L |
77f376d9 PC |
403 | template<typename _Up = _Tp> |
404 | typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, | |
405 | void>::__type | |
406 | push_back(_Tp&& __x) | |
407 | { emplace_back(std::move(__x)); } | |
4dc3e453 | 408 | |
6eef7402 CJ |
409 | template<typename... _Args> |
410 | void | |
4dc3e453 | 411 | emplace_back(_Args&&... __args) |
6eef7402 CJ |
412 | { |
413 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
4dc3e453 | 414 | _Base::emplace_back(std::forward<_Args>(__args)...); |
6eef7402 CJ |
415 | if (__realloc) |
416 | this->_M_invalidate_all(); | |
417 | _M_update_guaranteed_capacity(); | |
418 | } | |
419 | #endif | |
285b36d6 | 420 | |
526da49c | 421 | void |
757b1644 | 422 | pop_back() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
423 | { |
424 | __glibcxx_check_nonempty(); | |
afe96d41 | 425 | this->_M_invalidate_if(_Equal(--_Base::end())); |
285b36d6 BK |
426 | _Base::pop_back(); |
427 | } | |
428 | ||
734f5023 | 429 | #if __cplusplus >= 201103L |
6eef7402 CJ |
430 | template<typename... _Args> |
431 | iterator | |
7b61c5a9 | 432 | emplace(const_iterator __position, _Args&&... __args) |
6eef7402 CJ |
433 | { |
434 | __glibcxx_check_insert(__position); | |
435 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
afe96d41 FD |
436 | difference_type __offset = __position.base() - _Base::begin(); |
437 | _Base_iterator __res = _Base::emplace(__position.base(), | |
438 | std::forward<_Args>(__args)...); | |
6eef7402 CJ |
439 | if (__realloc) |
440 | this->_M_invalidate_all(); | |
441 | else | |
afe96d41 | 442 | this->_M_invalidate_after_nth(__offset); |
6eef7402 CJ |
443 | _M_update_guaranteed_capacity(); |
444 | return iterator(__res, this); | |
445 | } | |
446 | #endif | |
447 | ||
526da49c | 448 | iterator |
7b61c5a9 PC |
449 | #if __cplusplus >= 201103L |
450 | insert(const_iterator __position, const _Tp& __x) | |
451 | #else | |
285b36d6 | 452 | insert(iterator __position, const _Tp& __x) |
7b61c5a9 | 453 | #endif |
285b36d6 BK |
454 | { |
455 | __glibcxx_check_insert(__position); | |
456 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
afe96d41 FD |
457 | difference_type __offset = __position.base() - _Base::begin(); |
458 | _Base_iterator __res = _Base::insert(__position.base(), __x); | |
285b36d6 BK |
459 | if (__realloc) |
460 | this->_M_invalidate_all(); | |
461 | else | |
afe96d41 | 462 | this->_M_invalidate_after_nth(__offset); |
285b36d6 BK |
463 | _M_update_guaranteed_capacity(); |
464 | return iterator(__res, this); | |
465 | } | |
466 | ||
734f5023 | 467 | #if __cplusplus >= 201103L |
77f376d9 PC |
468 | template<typename _Up = _Tp> |
469 | typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, | |
470 | iterator>::__type | |
7b61c5a9 | 471 | insert(const_iterator __position, _Tp&& __x) |
77f376d9 | 472 | { return emplace(__position, std::move(__x)); } |
988499f4 | 473 | |
06eed9f5 PC |
474 | iterator |
475 | insert(const_iterator __position, initializer_list<value_type> __l) | |
476 | { return this->insert(__position, __l.begin(), __l.end()); } | |
6eef7402 CJ |
477 | #endif |
478 | ||
06eed9f5 PC |
479 | #if __cplusplus >= 201103L |
480 | iterator | |
481 | insert(const_iterator __position, size_type __n, const _Tp& __x) | |
482 | { | |
483 | __glibcxx_check_insert(__position); | |
484 | bool __realloc = _M_requires_reallocation(this->size() + __n); | |
485 | difference_type __offset = __position.base() - _Base::cbegin(); | |
486 | _Base_iterator __res = _Base::insert(__position.base(), __n, __x); | |
487 | if (__realloc) | |
488 | this->_M_invalidate_all(); | |
489 | else | |
490 | this->_M_invalidate_after_nth(__offset); | |
491 | _M_update_guaranteed_capacity(); | |
492 | return iterator(__res, this); | |
493 | } | |
494 | #else | |
526da49c | 495 | void |
285b36d6 BK |
496 | insert(iterator __position, size_type __n, const _Tp& __x) |
497 | { | |
498 | __glibcxx_check_insert(__position); | |
499 | bool __realloc = _M_requires_reallocation(this->size() + __n); | |
afe96d41 | 500 | difference_type __offset = __position.base() - _Base::begin(); |
285b36d6 BK |
501 | _Base::insert(__position.base(), __n, __x); |
502 | if (__realloc) | |
503 | this->_M_invalidate_all(); | |
504 | else | |
afe96d41 | 505 | this->_M_invalidate_after_nth(__offset); |
285b36d6 BK |
506 | _M_update_guaranteed_capacity(); |
507 | } | |
06eed9f5 | 508 | #endif |
285b36d6 | 509 | |
734f5023 | 510 | #if __cplusplus >= 201103L |
2203cb90 PC |
511 | template<class _InputIterator, |
512 | typename = std::_RequireInputIter<_InputIterator>> | |
06eed9f5 PC |
513 | iterator |
514 | insert(const_iterator __position, | |
515 | _InputIterator __first, _InputIterator __last) | |
516 | { | |
517 | __glibcxx_check_insert_range(__position, __first, __last); | |
518 | ||
519 | /* Hard to guess if invalidation will occur, because __last | |
520 | - __first can't be calculated in all cases, so we just | |
521 | punt here by checking if it did occur. */ | |
522 | _Base_iterator __old_begin = _M_base().begin(); | |
523 | difference_type __offset = __position.base() - _Base::cbegin(); | |
524 | _Base_iterator __res = _Base::insert(__position.base(), | |
525 | __gnu_debug::__base(__first), | |
526 | __gnu_debug::__base(__last)); | |
527 | ||
528 | if (_M_base().begin() != __old_begin) | |
529 | this->_M_invalidate_all(); | |
530 | else | |
531 | this->_M_invalidate_after_nth(__offset); | |
532 | _M_update_guaranteed_capacity(); | |
533 | return iterator(__res, this); | |
534 | } | |
2203cb90 | 535 | #else |
285b36d6 | 536 | template<class _InputIterator> |
526da49c BI |
537 | void |
538 | insert(iterator __position, | |
285b36d6 BK |
539 | _InputIterator __first, _InputIterator __last) |
540 | { | |
541 | __glibcxx_check_insert_range(__position, __first, __last); | |
526da49c | 542 | |
285b36d6 BK |
543 | /* Hard to guess if invalidation will occur, because __last |
544 | - __first can't be calculated in all cases, so we just | |
545 | punt here by checking if it did occur. */ | |
afe96d41 FD |
546 | _Base_iterator __old_begin = _M_base().begin(); |
547 | difference_type __offset = __position.base() - _Base::begin(); | |
1f5ca1a1 PC |
548 | _Base::insert(__position.base(), __gnu_debug::__base(__first), |
549 | __gnu_debug::__base(__last)); | |
526da49c | 550 | |
285b36d6 BK |
551 | if (_M_base().begin() != __old_begin) |
552 | this->_M_invalidate_all(); | |
553 | else | |
afe96d41 | 554 | this->_M_invalidate_after_nth(__offset); |
285b36d6 BK |
555 | _M_update_guaranteed_capacity(); |
556 | } | |
06eed9f5 | 557 | #endif |
526da49c BI |
558 | |
559 | iterator | |
94938aec PC |
560 | #if __cplusplus >= 201103L |
561 | erase(const_iterator __position) | |
562 | #else | |
285b36d6 | 563 | erase(iterator __position) |
94938aec | 564 | #endif |
285b36d6 BK |
565 | { |
566 | __glibcxx_check_erase(__position); | |
afe96d41 FD |
567 | difference_type __offset = __position.base() - _Base::begin(); |
568 | _Base_iterator __res = _Base::erase(__position.base()); | |
569 | this->_M_invalidate_after_nth(__offset); | |
285b36d6 BK |
570 | return iterator(__res, this); |
571 | } | |
572 | ||
526da49c | 573 | iterator |
94938aec PC |
574 | #if __cplusplus >= 201103L |
575 | erase(const_iterator __first, const_iterator __last) | |
576 | #else | |
285b36d6 | 577 | erase(iterator __first, iterator __last) |
94938aec | 578 | #endif |
285b36d6 BK |
579 | { |
580 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
581 | // 151. can't currently clear() empty container | |
582 | __glibcxx_check_erase_range(__first, __last); | |
526da49c | 583 | |
cdfa3dbb | 584 | if (__first.base() != __last.base()) |
a7cee01d PC |
585 | { |
586 | difference_type __offset = __first.base() - _Base::begin(); | |
587 | _Base_iterator __res = _Base::erase(__first.base(), | |
588 | __last.base()); | |
589 | this->_M_invalidate_after_nth(__offset); | |
590 | return iterator(__res, this); | |
591 | } | |
592 | else | |
94938aec PC |
593 | #if __cplusplus >= 201103L |
594 | return iterator(__first.base()._M_const_cast(), this); | |
595 | #else | |
a7cee01d | 596 | return __first; |
94938aec | 597 | #endif |
285b36d6 BK |
598 | } |
599 | ||
526da49c | 600 | void |
ed540c0a | 601 | swap(vector& __x) |
734f5023 | 602 | #if __cplusplus >= 201103L |
42500675 JW |
603 | noexcept(_Alloc_traits::_S_nothrow_swap()) |
604 | #endif | |
285b36d6 | 605 | { |
734f5023 | 606 | #if __cplusplus >= 201103L |
e77c9aed JW |
607 | if (!_Alloc_traits::_S_propagate_on_swap()) |
608 | __glibcxx_check_equal_allocs(__x); | |
609 | #endif | |
285b36d6 BK |
610 | _Base::swap(__x); |
611 | this->_M_swap(__x); | |
1b80d64a | 612 | std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); |
285b36d6 BK |
613 | } |
614 | ||
526da49c | 615 | void |
d3677132 | 616 | clear() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
617 | { |
618 | _Base::clear(); | |
619 | this->_M_invalidate_all(); | |
1b80d64a | 620 | _M_guaranteed_capacity = 0; |
285b36d6 BK |
621 | } |
622 | ||
526da49c | 623 | _Base& |
d3677132 | 624 | _M_base() _GLIBCXX_NOEXCEPT { return *this; } |
285b36d6 | 625 | |
526da49c | 626 | const _Base& |
d3677132 | 627 | _M_base() const _GLIBCXX_NOEXCEPT { return *this; } |
285b36d6 BK |
628 | |
629 | private: | |
630 | size_type _M_guaranteed_capacity; | |
631 | ||
526da49c | 632 | bool |
757b1644 | 633 | _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT |
2028b66d | 634 | { return __elements > this->capacity(); } |
526da49c BI |
635 | |
636 | void | |
757b1644 | 637 | _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT |
285b36d6 BK |
638 | { |
639 | if (this->size() > _M_guaranteed_capacity) | |
640 | _M_guaranteed_capacity = this->size(); | |
641 | } | |
afe96d41 FD |
642 | |
643 | void | |
757b1644 | 644 | _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT |
afe96d41 FD |
645 | { |
646 | typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; | |
647 | this->_M_invalidate_if(_After_nth(__n, _Base::begin())); | |
648 | } | |
285b36d6 BK |
649 | }; |
650 | ||
651 | template<typename _Tp, typename _Alloc> | |
652 | inline bool | |
653 | operator==(const vector<_Tp, _Alloc>& __lhs, | |
654 | const vector<_Tp, _Alloc>& __rhs) | |
655 | { return __lhs._M_base() == __rhs._M_base(); } | |
656 | ||
657 | template<typename _Tp, typename _Alloc> | |
658 | inline bool | |
526da49c | 659 | operator!=(const vector<_Tp, _Alloc>& __lhs, |
285b36d6 BK |
660 | const vector<_Tp, _Alloc>& __rhs) |
661 | { return __lhs._M_base() != __rhs._M_base(); } | |
662 | ||
663 | template<typename _Tp, typename _Alloc> | |
664 | inline bool | |
526da49c | 665 | operator<(const vector<_Tp, _Alloc>& __lhs, |
285b36d6 BK |
666 | const vector<_Tp, _Alloc>& __rhs) |
667 | { return __lhs._M_base() < __rhs._M_base(); } | |
668 | ||
669 | template<typename _Tp, typename _Alloc> | |
670 | inline bool | |
526da49c | 671 | operator<=(const vector<_Tp, _Alloc>& __lhs, |
285b36d6 BK |
672 | const vector<_Tp, _Alloc>& __rhs) |
673 | { return __lhs._M_base() <= __rhs._M_base(); } | |
674 | ||
675 | template<typename _Tp, typename _Alloc> | |
676 | inline bool | |
526da49c | 677 | operator>=(const vector<_Tp, _Alloc>& __lhs, |
285b36d6 BK |
678 | const vector<_Tp, _Alloc>& __rhs) |
679 | { return __lhs._M_base() >= __rhs._M_base(); } | |
680 | ||
681 | template<typename _Tp, typename _Alloc> | |
682 | inline bool | |
526da49c | 683 | operator>(const vector<_Tp, _Alloc>& __lhs, |
285b36d6 BK |
684 | const vector<_Tp, _Alloc>& __rhs) |
685 | { return __lhs._M_base() > __rhs._M_base(); } | |
686 | ||
687 | template<typename _Tp, typename _Alloc> | |
688 | inline void | |
689 | swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) | |
690 | { __lhs.swap(__rhs); } | |
ed540c0a | 691 | |
45f388bb | 692 | } // namespace __debug |
4cd533a7 | 693 | |
734f5023 | 694 | #if __cplusplus >= 201103L |
4cd533a7 PC |
695 | // DR 1182. |
696 | /// std::hash specialization for vector<bool>. | |
697 | template<typename _Alloc> | |
698 | struct hash<__debug::vector<bool, _Alloc>> | |
5d64ee19 | 699 | : public __hash_base<size_t, __debug::vector<bool, _Alloc>> |
4cd533a7 PC |
700 | { |
701 | size_t | |
72f1c34b | 702 | operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept |
12ffa228 | 703 | { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() |
4cd533a7 PC |
704 | (__b._M_base()); } |
705 | }; | |
706 | #endif | |
707 | ||
3cbc7af0 | 708 | } // namespace std |
285b36d6 | 709 | |
526da49c | 710 | #endif |