You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

835 lines
23KB

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