]>
Commit | Line | Data |
---|---|---|
1 | // Debugging vector implementation -*- C++ -*- | |
2 | ||
3 | // Copyright (C) 2003-2014 Free Software Foundation, Inc. | |
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 | |
8 | // Free Software Foundation; either version 3, or (at your option) | |
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 | ||
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/>. | |
24 | ||
25 | /** @file debug/vector | |
26 | * This file is a GNU debug extension to the Standard C++ Library. | |
27 | */ | |
28 | ||
29 | #ifndef _GLIBCXX_DEBUG_VECTOR | |
30 | #define _GLIBCXX_DEBUG_VECTOR 1 | |
31 | ||
32 | #include <vector> | |
33 | #include <utility> | |
34 | #include <debug/safe_sequence.h> | |
35 | #include <debug/safe_iterator.h> | |
36 | ||
37 | namespace std _GLIBCXX_VISIBILITY(default) | |
38 | { | |
39 | namespace __debug | |
40 | { | |
41 | /// Class std::vector with safety/checking/debug instrumentation. | |
42 | template<typename _Tp, | |
43 | typename _Allocator = std::allocator<_Tp> > | |
44 | class vector | |
45 | : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, | |
46 | public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > | |
47 | { | |
48 | typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; | |
49 | ||
50 | typedef typename _Base::iterator _Base_iterator; | |
51 | typedef typename _Base::const_iterator _Base_const_iterator; | |
52 | typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; | |
53 | ||
54 | #if __cplusplus >= 201103L | |
55 | typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits; | |
56 | #endif | |
57 | ||
58 | public: | |
59 | typedef typename _Base::reference reference; | |
60 | typedef typename _Base::const_reference const_reference; | |
61 | ||
62 | typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector> | |
63 | iterator; | |
64 | typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector> | |
65 | const_iterator; | |
66 | ||
67 | typedef typename _Base::size_type size_type; | |
68 | typedef typename _Base::difference_type difference_type; | |
69 | ||
70 | typedef _Tp value_type; | |
71 | typedef _Allocator allocator_type; | |
72 | typedef typename _Base::pointer pointer; | |
73 | typedef typename _Base::const_pointer const_pointer; | |
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: | |
78 | explicit | |
79 | vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT | |
80 | : _Base(__a), _M_guaranteed_capacity(0) { } | |
81 | ||
82 | #if __cplusplus >= 201103L | |
83 | explicit | |
84 | vector(size_type __n, const _Allocator& __a = _Allocator()) | |
85 | : _Base(__n, __a), _M_guaranteed_capacity(__n) { } | |
86 | ||
87 | vector(size_type __n, const _Tp& __value, | |
88 | const _Allocator& __a = _Allocator()) | |
89 | : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } | |
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 | |
96 | ||
97 | #if __cplusplus >= 201103L | |
98 | template<class _InputIterator, | |
99 | typename = std::_RequireInputIter<_InputIterator>> | |
100 | #else | |
101 | template<class _InputIterator> | |
102 | #endif | |
103 | vector(_InputIterator __first, _InputIterator __last, | |
104 | const _Allocator& __a = _Allocator()) | |
105 | : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, | |
106 | __last)), | |
107 | __gnu_debug::__base(__last), __a), | |
108 | _M_guaranteed_capacity(0) | |
109 | { _M_update_guaranteed_capacity(); } | |
110 | ||
111 | vector(const vector& __x) | |
112 | : _Base(__x), _M_guaranteed_capacity(__x.size()) { } | |
113 | ||
114 | /// Construction from a release-mode vector | |
115 | vector(const _Base& __x) | |
116 | : _Base(__x), _M_guaranteed_capacity(__x.size()) { } | |
117 | ||
118 | #if __cplusplus >= 201103L | |
119 | vector(vector&& __x) noexcept | |
120 | : _Base(std::move(__x)), | |
121 | _M_guaranteed_capacity(this->size()) | |
122 | { | |
123 | this->_M_swap(__x); | |
124 | __x._M_guaranteed_capacity = 0; | |
125 | } | |
126 | ||
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 | ||
138 | vector(initializer_list<value_type> __l, | |
139 | const allocator_type& __a = allocator_type()) | |
140 | : _Base(__l, __a), | |
141 | _M_guaranteed_capacity(__l.size()) { } | |
142 | #endif | |
143 | ||
144 | ~vector() _GLIBCXX_NOEXCEPT { } | |
145 | ||
146 | vector& | |
147 | operator=(const vector& __x) | |
148 | { | |
149 | static_cast<_Base&>(*this) = __x; | |
150 | this->_M_invalidate_all(); | |
151 | _M_update_guaranteed_capacity(); | |
152 | return *this; | |
153 | } | |
154 | ||
155 | #if __cplusplus >= 201103L | |
156 | vector& | |
157 | operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) | |
158 | { | |
159 | __glibcxx_check_self_move_assign(__x); | |
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; | |
165 | return *this; | |
166 | } | |
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 | } | |
176 | #endif | |
177 | ||
178 | #if __cplusplus >= 201103L | |
179 | template<typename _InputIterator, | |
180 | typename = std::_RequireInputIter<_InputIterator>> | |
181 | #else | |
182 | template<typename _InputIterator> | |
183 | #endif | |
184 | void | |
185 | assign(_InputIterator __first, _InputIterator __last) | |
186 | { | |
187 | __glibcxx_check_valid_range(__first, __last); | |
188 | _Base::assign(__gnu_debug::__base(__first), | |
189 | __gnu_debug::__base(__last)); | |
190 | this->_M_invalidate_all(); | |
191 | _M_update_guaranteed_capacity(); | |
192 | } | |
193 | ||
194 | void | |
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 | ||
202 | #if __cplusplus >= 201103L | |
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 | ||
212 | using _Base::get_allocator; | |
213 | ||
214 | // iterators: | |
215 | iterator | |
216 | begin() _GLIBCXX_NOEXCEPT | |
217 | { return iterator(_Base::begin(), this); } | |
218 | ||
219 | const_iterator | |
220 | begin() const _GLIBCXX_NOEXCEPT | |
221 | { return const_iterator(_Base::begin(), this); } | |
222 | ||
223 | iterator | |
224 | end() _GLIBCXX_NOEXCEPT | |
225 | { return iterator(_Base::end(), this); } | |
226 | ||
227 | const_iterator | |
228 | end() const _GLIBCXX_NOEXCEPT | |
229 | { return const_iterator(_Base::end(), this); } | |
230 | ||
231 | reverse_iterator | |
232 | rbegin() _GLIBCXX_NOEXCEPT | |
233 | { return reverse_iterator(end()); } | |
234 | ||
235 | const_reverse_iterator | |
236 | rbegin() const _GLIBCXX_NOEXCEPT | |
237 | { return const_reverse_iterator(end()); } | |
238 | ||
239 | reverse_iterator | |
240 | rend() _GLIBCXX_NOEXCEPT | |
241 | { return reverse_iterator(begin()); } | |
242 | ||
243 | const_reverse_iterator | |
244 | rend() const _GLIBCXX_NOEXCEPT | |
245 | { return const_reverse_iterator(begin()); } | |
246 | ||
247 | #if __cplusplus >= 201103L | |
248 | const_iterator | |
249 | cbegin() const noexcept | |
250 | { return const_iterator(_Base::begin(), this); } | |
251 | ||
252 | const_iterator | |
253 | cend() const noexcept | |
254 | { return const_iterator(_Base::end(), this); } | |
255 | ||
256 | const_reverse_iterator | |
257 | crbegin() const noexcept | |
258 | { return const_reverse_iterator(end()); } | |
259 | ||
260 | const_reverse_iterator | |
261 | crend() const noexcept | |
262 | { return const_reverse_iterator(begin()); } | |
263 | #endif | |
264 | ||
265 | // 23.2.4.2 capacity: | |
266 | using _Base::size; | |
267 | using _Base::max_size; | |
268 | ||
269 | #if __cplusplus >= 201103L | |
270 | void | |
271 | resize(size_type __sz) | |
272 | { | |
273 | bool __realloc = _M_requires_reallocation(__sz); | |
274 | if (__sz < this->size()) | |
275 | this->_M_invalidate_after_nth(__sz); | |
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()) | |
287 | this->_M_invalidate_after_nth(__sz); | |
288 | _Base::resize(__sz, __c); | |
289 | if (__realloc) | |
290 | this->_M_invalidate_all(); | |
291 | _M_update_guaranteed_capacity(); | |
292 | } | |
293 | #else | |
294 | void | |
295 | resize(size_type __sz, _Tp __c = _Tp()) | |
296 | { | |
297 | bool __realloc = _M_requires_reallocation(__sz); | |
298 | if (__sz < this->size()) | |
299 | this->_M_invalidate_after_nth(__sz); | |
300 | _Base::resize(__sz, __c); | |
301 | if (__realloc) | |
302 | this->_M_invalidate_all(); | |
303 | _M_update_guaranteed_capacity(); | |
304 | } | |
305 | #endif | |
306 | ||
307 | #if __cplusplus >= 201103L | |
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 | } | |
317 | #endif | |
318 | ||
319 | size_type | |
320 | capacity() const _GLIBCXX_NOEXCEPT | |
321 | { | |
322 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
323 | return _M_guaranteed_capacity; | |
324 | #else | |
325 | return _Base::capacity(); | |
326 | #endif | |
327 | } | |
328 | ||
329 | using _Base::empty; | |
330 | ||
331 | void | |
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: | |
343 | reference | |
344 | operator[](size_type __n) _GLIBCXX_NOEXCEPT | |
345 | { | |
346 | __glibcxx_check_subscript(__n); | |
347 | return _M_base()[__n]; | |
348 | } | |
349 | ||
350 | const_reference | |
351 | operator[](size_type __n) const _GLIBCXX_NOEXCEPT | |
352 | { | |
353 | __glibcxx_check_subscript(__n); | |
354 | return _M_base()[__n]; | |
355 | } | |
356 | ||
357 | using _Base::at; | |
358 | ||
359 | reference | |
360 | front() _GLIBCXX_NOEXCEPT | |
361 | { | |
362 | __glibcxx_check_nonempty(); | |
363 | return _Base::front(); | |
364 | } | |
365 | ||
366 | const_reference | |
367 | front() const _GLIBCXX_NOEXCEPT | |
368 | { | |
369 | __glibcxx_check_nonempty(); | |
370 | return _Base::front(); | |
371 | } | |
372 | ||
373 | reference | |
374 | back() _GLIBCXX_NOEXCEPT | |
375 | { | |
376 | __glibcxx_check_nonempty(); | |
377 | return _Base::back(); | |
378 | } | |
379 | ||
380 | const_reference | |
381 | back() const _GLIBCXX_NOEXCEPT | |
382 | { | |
383 | __glibcxx_check_nonempty(); | |
384 | return _Base::back(); | |
385 | } | |
386 | ||
387 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
388 | // DR 464. Suggestion for new member functions in standard containers. | |
389 | using _Base::data; | |
390 | ||
391 | // 23.2.4.3 modifiers: | |
392 | void | |
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 | } | |
401 | ||
402 | #if __cplusplus >= 201103L | |
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)); } | |
408 | ||
409 | template<typename... _Args> | |
410 | void | |
411 | emplace_back(_Args&&... __args) | |
412 | { | |
413 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
414 | _Base::emplace_back(std::forward<_Args>(__args)...); | |
415 | if (__realloc) | |
416 | this->_M_invalidate_all(); | |
417 | _M_update_guaranteed_capacity(); | |
418 | } | |
419 | #endif | |
420 | ||
421 | void | |
422 | pop_back() _GLIBCXX_NOEXCEPT | |
423 | { | |
424 | __glibcxx_check_nonempty(); | |
425 | this->_M_invalidate_if(_Equal(--_Base::end())); | |
426 | _Base::pop_back(); | |
427 | } | |
428 | ||
429 | #if __cplusplus >= 201103L | |
430 | template<typename... _Args> | |
431 | iterator | |
432 | emplace(const_iterator __position, _Args&&... __args) | |
433 | { | |
434 | __glibcxx_check_insert(__position); | |
435 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
436 | difference_type __offset = __position.base() - _Base::begin(); | |
437 | _Base_iterator __res = _Base::emplace(__position.base(), | |
438 | std::forward<_Args>(__args)...); | |
439 | if (__realloc) | |
440 | this->_M_invalidate_all(); | |
441 | else | |
442 | this->_M_invalidate_after_nth(__offset); | |
443 | _M_update_guaranteed_capacity(); | |
444 | return iterator(__res, this); | |
445 | } | |
446 | #endif | |
447 | ||
448 | iterator | |
449 | #if __cplusplus >= 201103L | |
450 | insert(const_iterator __position, const _Tp& __x) | |
451 | #else | |
452 | insert(iterator __position, const _Tp& __x) | |
453 | #endif | |
454 | { | |
455 | __glibcxx_check_insert(__position); | |
456 | bool __realloc = _M_requires_reallocation(this->size() + 1); | |
457 | difference_type __offset = __position.base() - _Base::begin(); | |
458 | _Base_iterator __res = _Base::insert(__position.base(), __x); | |
459 | if (__realloc) | |
460 | this->_M_invalidate_all(); | |
461 | else | |
462 | this->_M_invalidate_after_nth(__offset); | |
463 | _M_update_guaranteed_capacity(); | |
464 | return iterator(__res, this); | |
465 | } | |
466 | ||
467 | #if __cplusplus >= 201103L | |
468 | template<typename _Up = _Tp> | |
469 | typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, | |
470 | iterator>::__type | |
471 | insert(const_iterator __position, _Tp&& __x) | |
472 | { return emplace(__position, std::move(__x)); } | |
473 | ||
474 | iterator | |
475 | insert(const_iterator __position, initializer_list<value_type> __l) | |
476 | { return this->insert(__position, __l.begin(), __l.end()); } | |
477 | #endif | |
478 | ||
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 | |
495 | void | |
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); | |
500 | difference_type __offset = __position.base() - _Base::begin(); | |
501 | _Base::insert(__position.base(), __n, __x); | |
502 | if (__realloc) | |
503 | this->_M_invalidate_all(); | |
504 | else | |
505 | this->_M_invalidate_after_nth(__offset); | |
506 | _M_update_guaranteed_capacity(); | |
507 | } | |
508 | #endif | |
509 | ||
510 | #if __cplusplus >= 201103L | |
511 | template<class _InputIterator, | |
512 | typename = std::_RequireInputIter<_InputIterator>> | |
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 | } | |
535 | #else | |
536 | template<class _InputIterator> | |
537 | void | |
538 | insert(iterator __position, | |
539 | _InputIterator __first, _InputIterator __last) | |
540 | { | |
541 | __glibcxx_check_insert_range(__position, __first, __last); | |
542 | ||
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. */ | |
546 | _Base_iterator __old_begin = _M_base().begin(); | |
547 | difference_type __offset = __position.base() - _Base::begin(); | |
548 | _Base::insert(__position.base(), __gnu_debug::__base(__first), | |
549 | __gnu_debug::__base(__last)); | |
550 | ||
551 | if (_M_base().begin() != __old_begin) | |
552 | this->_M_invalidate_all(); | |
553 | else | |
554 | this->_M_invalidate_after_nth(__offset); | |
555 | _M_update_guaranteed_capacity(); | |
556 | } | |
557 | #endif | |
558 | ||
559 | iterator | |
560 | #if __cplusplus >= 201103L | |
561 | erase(const_iterator __position) | |
562 | #else | |
563 | erase(iterator __position) | |
564 | #endif | |
565 | { | |
566 | __glibcxx_check_erase(__position); | |
567 | difference_type __offset = __position.base() - _Base::begin(); | |
568 | _Base_iterator __res = _Base::erase(__position.base()); | |
569 | this->_M_invalidate_after_nth(__offset); | |
570 | return iterator(__res, this); | |
571 | } | |
572 | ||
573 | iterator | |
574 | #if __cplusplus >= 201103L | |
575 | erase(const_iterator __first, const_iterator __last) | |
576 | #else | |
577 | erase(iterator __first, iterator __last) | |
578 | #endif | |
579 | { | |
580 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
581 | // 151. can't currently clear() empty container | |
582 | __glibcxx_check_erase_range(__first, __last); | |
583 | ||
584 | if (__first.base() != __last.base()) | |
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 | |
593 | #if __cplusplus >= 201103L | |
594 | return iterator(__first.base()._M_const_cast(), this); | |
595 | #else | |
596 | return __first; | |
597 | #endif | |
598 | } | |
599 | ||
600 | void | |
601 | swap(vector& __x) | |
602 | #if __cplusplus >= 201103L | |
603 | noexcept(_Alloc_traits::_S_nothrow_swap()) | |
604 | #endif | |
605 | { | |
606 | #if __cplusplus >= 201103L | |
607 | if (!_Alloc_traits::_S_propagate_on_swap()) | |
608 | __glibcxx_check_equal_allocs(__x); | |
609 | #endif | |
610 | _Base::swap(__x); | |
611 | this->_M_swap(__x); | |
612 | std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); | |
613 | } | |
614 | ||
615 | void | |
616 | clear() _GLIBCXX_NOEXCEPT | |
617 | { | |
618 | _Base::clear(); | |
619 | this->_M_invalidate_all(); | |
620 | _M_guaranteed_capacity = 0; | |
621 | } | |
622 | ||
623 | _Base& | |
624 | _M_base() _GLIBCXX_NOEXCEPT { return *this; } | |
625 | ||
626 | const _Base& | |
627 | _M_base() const _GLIBCXX_NOEXCEPT { return *this; } | |
628 | ||
629 | private: | |
630 | size_type _M_guaranteed_capacity; | |
631 | ||
632 | bool | |
633 | _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT | |
634 | { return __elements > this->capacity(); } | |
635 | ||
636 | void | |
637 | _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT | |
638 | { | |
639 | if (this->size() > _M_guaranteed_capacity) | |
640 | _M_guaranteed_capacity = this->size(); | |
641 | } | |
642 | ||
643 | void | |
644 | _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT | |
645 | { | |
646 | typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; | |
647 | this->_M_invalidate_if(_After_nth(__n, _Base::begin())); | |
648 | } | |
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 | |
659 | operator!=(const vector<_Tp, _Alloc>& __lhs, | |
660 | const vector<_Tp, _Alloc>& __rhs) | |
661 | { return __lhs._M_base() != __rhs._M_base(); } | |
662 | ||
663 | template<typename _Tp, typename _Alloc> | |
664 | inline bool | |
665 | operator<(const vector<_Tp, _Alloc>& __lhs, | |
666 | const vector<_Tp, _Alloc>& __rhs) | |
667 | { return __lhs._M_base() < __rhs._M_base(); } | |
668 | ||
669 | template<typename _Tp, typename _Alloc> | |
670 | inline bool | |
671 | operator<=(const vector<_Tp, _Alloc>& __lhs, | |
672 | const vector<_Tp, _Alloc>& __rhs) | |
673 | { return __lhs._M_base() <= __rhs._M_base(); } | |
674 | ||
675 | template<typename _Tp, typename _Alloc> | |
676 | inline bool | |
677 | operator>=(const vector<_Tp, _Alloc>& __lhs, | |
678 | const vector<_Tp, _Alloc>& __rhs) | |
679 | { return __lhs._M_base() >= __rhs._M_base(); } | |
680 | ||
681 | template<typename _Tp, typename _Alloc> | |
682 | inline bool | |
683 | operator>(const vector<_Tp, _Alloc>& __lhs, | |
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); } | |
691 | ||
692 | } // namespace __debug | |
693 | ||
694 | #if __cplusplus >= 201103L | |
695 | // DR 1182. | |
696 | /// std::hash specialization for vector<bool>. | |
697 | template<typename _Alloc> | |
698 | struct hash<__debug::vector<bool, _Alloc>> | |
699 | : public __hash_base<size_t, __debug::vector<bool, _Alloc>> | |
700 | { | |
701 | size_t | |
702 | operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept | |
703 | { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>() | |
704 | (__b._M_base()); } | |
705 | }; | |
706 | #endif | |
707 | ||
708 | } // namespace std | |
709 | ||
710 | #endif |