deque 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. // Debugging deque implementation -*- C++ -*-
  2. // Copyright (C) 2003-2015 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/deque
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_DEQUE
  24. #define _GLIBCXX_DEBUG_DEQUE 1
  25. #include <deque>
  26. #include <debug/safe_sequence.h>
  27. #include <debug/safe_container.h>
  28. #include <debug/safe_iterator.h>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. namespace __debug
  32. {
  33. /// Class std::deque with safety/checking/debug instrumentation.
  34. template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
  35. class deque
  36. : public __gnu_debug::_Safe_container<
  37. deque<_Tp, _Allocator>, _Allocator,
  38. __gnu_debug::_Safe_sequence>,
  39. public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
  40. {
  41. typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
  42. typedef __gnu_debug::_Safe_container<
  43. deque, _Allocator, __gnu_debug::_Safe_sequence> _Safe;
  44. typedef typename _Base::const_iterator _Base_const_iterator;
  45. typedef typename _Base::iterator _Base_iterator;
  46. typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
  47. public:
  48. typedef typename _Base::reference reference;
  49. typedef typename _Base::const_reference const_reference;
  50. typedef __gnu_debug::_Safe_iterator<_Base_iterator, deque>
  51. iterator;
  52. typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque>
  53. const_iterator;
  54. typedef typename _Base::size_type size_type;
  55. typedef typename _Base::difference_type difference_type;
  56. typedef _Tp value_type;
  57. typedef _Allocator allocator_type;
  58. typedef typename _Base::pointer pointer;
  59. typedef typename _Base::const_pointer const_pointer;
  60. typedef std::reverse_iterator<iterator> reverse_iterator;
  61. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  62. // 23.2.1.1 construct/copy/destroy:
  63. #if __cplusplus < 201103L
  64. deque()
  65. : _Base() { }
  66. deque(const deque& __x)
  67. : _Base(__x) { }
  68. ~deque() { }
  69. #else
  70. deque() = default;
  71. deque(const deque&) = default;
  72. deque(deque&&) = default;
  73. deque(const deque& __d, const _Allocator& __a)
  74. : _Base(__d, __a) { }
  75. deque(deque&& __d, const _Allocator& __a)
  76. : _Safe(std::move(__d)), _Base(std::move(__d), __a) { }
  77. deque(initializer_list<value_type> __l,
  78. const allocator_type& __a = allocator_type())
  79. : _Base(__l, __a) { }
  80. ~deque() = default;
  81. #endif
  82. explicit
  83. deque(const _Allocator& __a)
  84. : _Base(__a) { }
  85. #if __cplusplus >= 201103L
  86. explicit
  87. deque(size_type __n, const _Allocator& __a = _Allocator())
  88. : _Base(__n, __a) { }
  89. deque(size_type __n, const _Tp& __value,
  90. const _Allocator& __a = _Allocator())
  91. : _Base(__n, __value, __a) { }
  92. #else
  93. explicit
  94. deque(size_type __n, const _Tp& __value = _Tp(),
  95. const _Allocator& __a = _Allocator())
  96. : _Base(__n, __value, __a) { }
  97. #endif
  98. #if __cplusplus >= 201103L
  99. template<class _InputIterator,
  100. typename = std::_RequireInputIter<_InputIterator>>
  101. #else
  102. template<class _InputIterator>
  103. #endif
  104. deque(_InputIterator __first, _InputIterator __last,
  105. const _Allocator& __a = _Allocator())
  106. : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
  107. __last)),
  108. __gnu_debug::__base(__last), __a)
  109. { }
  110. deque(const _Base& __x)
  111. : _Base(__x) { }
  112. #if __cplusplus < 201103L
  113. deque&
  114. operator=(const deque& __x)
  115. {
  116. this->_M_safe() = __x;
  117. _M_base() = __x;
  118. return *this;
  119. }
  120. #else
  121. deque&
  122. operator=(const deque&) = default;
  123. deque&
  124. operator=(deque&&) = default;
  125. deque&
  126. operator=(initializer_list<value_type> __l)
  127. {
  128. _M_base() = __l;
  129. this->_M_invalidate_all();
  130. return *this;
  131. }
  132. #endif
  133. #if __cplusplus >= 201103L
  134. template<class _InputIterator,
  135. typename = std::_RequireInputIter<_InputIterator>>
  136. #else
  137. template<class _InputIterator>
  138. #endif
  139. void
  140. assign(_InputIterator __first, _InputIterator __last)
  141. {
  142. __glibcxx_check_valid_range(__first, __last);
  143. _Base::assign(__gnu_debug::__base(__first),
  144. __gnu_debug::__base(__last));
  145. this->_M_invalidate_all();
  146. }
  147. void
  148. assign(size_type __n, const _Tp& __t)
  149. {
  150. _Base::assign(__n, __t);
  151. this->_M_invalidate_all();
  152. }
  153. #if __cplusplus >= 201103L
  154. void
  155. assign(initializer_list<value_type> __l)
  156. {
  157. _Base::assign(__l);
  158. this->_M_invalidate_all();
  159. }
  160. #endif
  161. using _Base::get_allocator;
  162. // iterators:
  163. iterator
  164. begin() _GLIBCXX_NOEXCEPT
  165. { return iterator(_Base::begin(), this); }
  166. const_iterator
  167. begin() const _GLIBCXX_NOEXCEPT
  168. { return const_iterator(_Base::begin(), this); }
  169. iterator
  170. end() _GLIBCXX_NOEXCEPT
  171. { return iterator(_Base::end(), this); }
  172. const_iterator
  173. end() const _GLIBCXX_NOEXCEPT
  174. { return const_iterator(_Base::end(), this); }
  175. reverse_iterator
  176. rbegin() _GLIBCXX_NOEXCEPT
  177. { return reverse_iterator(end()); }
  178. const_reverse_iterator
  179. rbegin() const _GLIBCXX_NOEXCEPT
  180. { return const_reverse_iterator(end()); }
  181. reverse_iterator
  182. rend() _GLIBCXX_NOEXCEPT
  183. { return reverse_iterator(begin()); }
  184. const_reverse_iterator
  185. rend() const _GLIBCXX_NOEXCEPT
  186. { return const_reverse_iterator(begin()); }
  187. #if __cplusplus >= 201103L
  188. const_iterator
  189. cbegin() const noexcept
  190. { return const_iterator(_Base::begin(), this); }
  191. const_iterator
  192. cend() const noexcept
  193. { return const_iterator(_Base::end(), this); }
  194. const_reverse_iterator
  195. crbegin() const noexcept
  196. { return const_reverse_iterator(end()); }
  197. const_reverse_iterator
  198. crend() const noexcept
  199. { return const_reverse_iterator(begin()); }
  200. #endif
  201. private:
  202. void
  203. _M_invalidate_after_nth(difference_type __n)
  204. {
  205. typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
  206. this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
  207. }
  208. public:
  209. // 23.2.1.2 capacity:
  210. using _Base::size;
  211. using _Base::max_size;
  212. #if __cplusplus >= 201103L
  213. void
  214. resize(size_type __sz)
  215. {
  216. bool __invalidate_all = __sz > this->size();
  217. if (__sz < this->size())
  218. this->_M_invalidate_after_nth(__sz);
  219. _Base::resize(__sz);
  220. if (__invalidate_all)
  221. this->_M_invalidate_all();
  222. }
  223. void
  224. resize(size_type __sz, const _Tp& __c)
  225. {
  226. bool __invalidate_all = __sz > this->size();
  227. if (__sz < this->size())
  228. this->_M_invalidate_after_nth(__sz);
  229. _Base::resize(__sz, __c);
  230. if (__invalidate_all)
  231. this->_M_invalidate_all();
  232. }
  233. #else
  234. void
  235. resize(size_type __sz, _Tp __c = _Tp())
  236. {
  237. bool __invalidate_all = __sz > this->size();
  238. if (__sz < this->size())
  239. this->_M_invalidate_after_nth(__sz);
  240. _Base::resize(__sz, __c);
  241. if (__invalidate_all)
  242. this->_M_invalidate_all();
  243. }
  244. #endif
  245. #if __cplusplus >= 201103L
  246. void
  247. shrink_to_fit() noexcept
  248. {
  249. if (_Base::_M_shrink_to_fit())
  250. this->_M_invalidate_all();
  251. }
  252. #endif
  253. using _Base::empty;
  254. // element access:
  255. reference
  256. operator[](size_type __n) _GLIBCXX_NOEXCEPT
  257. {
  258. __glibcxx_check_subscript(__n);
  259. return _M_base()[__n];
  260. }
  261. const_reference
  262. operator[](size_type __n) const _GLIBCXX_NOEXCEPT
  263. {
  264. __glibcxx_check_subscript(__n);
  265. return _M_base()[__n];
  266. }
  267. using _Base::at;
  268. reference
  269. front() _GLIBCXX_NOEXCEPT
  270. {
  271. __glibcxx_check_nonempty();
  272. return _Base::front();
  273. }
  274. const_reference
  275. front() const _GLIBCXX_NOEXCEPT
  276. {
  277. __glibcxx_check_nonempty();
  278. return _Base::front();
  279. }
  280. reference
  281. back() _GLIBCXX_NOEXCEPT
  282. {
  283. __glibcxx_check_nonempty();
  284. return _Base::back();
  285. }
  286. const_reference
  287. back() const _GLIBCXX_NOEXCEPT
  288. {
  289. __glibcxx_check_nonempty();
  290. return _Base::back();
  291. }
  292. // 23.2.1.3 modifiers:
  293. void
  294. push_front(const _Tp& __x)
  295. {
  296. _Base::push_front(__x);
  297. this->_M_invalidate_all();
  298. }
  299. void
  300. push_back(const _Tp& __x)
  301. {
  302. _Base::push_back(__x);
  303. this->_M_invalidate_all();
  304. }
  305. #if __cplusplus >= 201103L
  306. void
  307. push_front(_Tp&& __x)
  308. { emplace_front(std::move(__x)); }
  309. void
  310. push_back(_Tp&& __x)
  311. { emplace_back(std::move(__x)); }
  312. template<typename... _Args>
  313. void
  314. emplace_front(_Args&&... __args)
  315. {
  316. _Base::emplace_front(std::forward<_Args>(__args)...);
  317. this->_M_invalidate_all();
  318. }
  319. template<typename... _Args>
  320. void
  321. emplace_back(_Args&&... __args)
  322. {
  323. _Base::emplace_back(std::forward<_Args>(__args)...);
  324. this->_M_invalidate_all();
  325. }
  326. template<typename... _Args>
  327. iterator
  328. emplace(const_iterator __position, _Args&&... __args)
  329. {
  330. __glibcxx_check_insert(__position);
  331. _Base_iterator __res = _Base::emplace(__position.base(),
  332. std::forward<_Args>(__args)...);
  333. this->_M_invalidate_all();
  334. return iterator(__res, this);
  335. }
  336. #endif
  337. iterator
  338. #if __cplusplus >= 201103L
  339. insert(const_iterator __position, const _Tp& __x)
  340. #else
  341. insert(iterator __position, const _Tp& __x)
  342. #endif
  343. {
  344. __glibcxx_check_insert(__position);
  345. _Base_iterator __res = _Base::insert(__position.base(), __x);
  346. this->_M_invalidate_all();
  347. return iterator(__res, this);
  348. }
  349. #if __cplusplus >= 201103L
  350. iterator
  351. insert(const_iterator __position, _Tp&& __x)
  352. { return emplace(__position, std::move(__x)); }
  353. iterator
  354. insert(const_iterator __position, initializer_list<value_type> __l)
  355. {
  356. __glibcxx_check_insert(__position);
  357. _Base_iterator __res = _Base::insert(__position.base(), __l);
  358. this->_M_invalidate_all();
  359. return iterator(__res, this);
  360. }
  361. #endif
  362. #if __cplusplus >= 201103L
  363. iterator
  364. insert(const_iterator __position, size_type __n, const _Tp& __x)
  365. {
  366. __glibcxx_check_insert(__position);
  367. _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
  368. this->_M_invalidate_all();
  369. return iterator(__res, this);
  370. }
  371. #else
  372. void
  373. insert(iterator __position, size_type __n, const _Tp& __x)
  374. {
  375. __glibcxx_check_insert(__position);
  376. _Base::insert(__position.base(), __n, __x);
  377. this->_M_invalidate_all();
  378. }
  379. #endif
  380. #if __cplusplus >= 201103L
  381. template<class _InputIterator,
  382. typename = std::_RequireInputIter<_InputIterator>>
  383. iterator
  384. insert(const_iterator __position,
  385. _InputIterator __first, _InputIterator __last)
  386. {
  387. __glibcxx_check_insert_range(__position, __first, __last);
  388. _Base_iterator __res = _Base::insert(__position.base(),
  389. __gnu_debug::__base(__first),
  390. __gnu_debug::__base(__last));
  391. this->_M_invalidate_all();
  392. return iterator(__res, this);
  393. }
  394. #else
  395. template<class _InputIterator>
  396. void
  397. insert(iterator __position,
  398. _InputIterator __first, _InputIterator __last)
  399. {
  400. __glibcxx_check_insert_range(__position, __first, __last);
  401. _Base::insert(__position.base(), __gnu_debug::__base(__first),
  402. __gnu_debug::__base(__last));
  403. this->_M_invalidate_all();
  404. }
  405. #endif
  406. void
  407. pop_front() _GLIBCXX_NOEXCEPT
  408. {
  409. __glibcxx_check_nonempty();
  410. this->_M_invalidate_if(_Equal(_Base::begin()));
  411. _Base::pop_front();
  412. }
  413. void
  414. pop_back() _GLIBCXX_NOEXCEPT
  415. {
  416. __glibcxx_check_nonempty();
  417. this->_M_invalidate_if(_Equal(--_Base::end()));
  418. _Base::pop_back();
  419. }
  420. iterator
  421. #if __cplusplus >= 201103L
  422. erase(const_iterator __position)
  423. #else
  424. erase(iterator __position)
  425. #endif
  426. {
  427. __glibcxx_check_erase(__position);
  428. #if __cplusplus >= 201103L
  429. _Base_const_iterator __victim = __position.base();
  430. #else
  431. _Base_iterator __victim = __position.base();
  432. #endif
  433. if (__victim == _Base::begin() || __victim == _Base::end() - 1)
  434. {
  435. this->_M_invalidate_if(_Equal(__victim));
  436. return iterator(_Base::erase(__victim), this);
  437. }
  438. else
  439. {
  440. _Base_iterator __res = _Base::erase(__victim);
  441. this->_M_invalidate_all();
  442. return iterator(__res, this);
  443. }
  444. }
  445. iterator
  446. #if __cplusplus >= 201103L
  447. erase(const_iterator __first, const_iterator __last)
  448. #else
  449. erase(iterator __first, iterator __last)
  450. #endif
  451. {
  452. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  453. // 151. can't currently clear() empty container
  454. __glibcxx_check_erase_range(__first, __last);
  455. if (__first.base() == __last.base())
  456. #if __cplusplus >= 201103L
  457. return iterator(__first.base()._M_const_cast(), this);
  458. #else
  459. return __first;
  460. #endif
  461. else if (__first.base() == _Base::begin()
  462. || __last.base() == _Base::end())
  463. {
  464. this->_M_detach_singular();
  465. for (_Base_const_iterator __position = __first.base();
  466. __position != __last.base(); ++__position)
  467. {
  468. this->_M_invalidate_if(_Equal(__position));
  469. }
  470. __try
  471. {
  472. return iterator(_Base::erase(__first.base(), __last.base()),
  473. this);
  474. }
  475. __catch(...)
  476. {
  477. this->_M_revalidate_singular();
  478. __throw_exception_again;
  479. }
  480. }
  481. else
  482. {
  483. _Base_iterator __res = _Base::erase(__first.base(),
  484. __last.base());
  485. this->_M_invalidate_all();
  486. return iterator(__res, this);
  487. }
  488. }
  489. void
  490. swap(deque& __x)
  491. #if __cplusplus >= 201103L
  492. noexcept( noexcept(declval<_Base>().swap(__x)) )
  493. #endif
  494. {
  495. _Safe::_M_swap(__x);
  496. _Base::swap(__x);
  497. }
  498. void
  499. clear() _GLIBCXX_NOEXCEPT
  500. {
  501. _Base::clear();
  502. this->_M_invalidate_all();
  503. }
  504. _Base&
  505. _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  506. const _Base&
  507. _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  508. };
  509. template<typename _Tp, typename _Alloc>
  510. inline bool
  511. operator==(const deque<_Tp, _Alloc>& __lhs,
  512. const deque<_Tp, _Alloc>& __rhs)
  513. { return __lhs._M_base() == __rhs._M_base(); }
  514. template<typename _Tp, typename _Alloc>
  515. inline bool
  516. operator!=(const deque<_Tp, _Alloc>& __lhs,
  517. const deque<_Tp, _Alloc>& __rhs)
  518. { return __lhs._M_base() != __rhs._M_base(); }
  519. template<typename _Tp, typename _Alloc>
  520. inline bool
  521. operator<(const deque<_Tp, _Alloc>& __lhs,
  522. const deque<_Tp, _Alloc>& __rhs)
  523. { return __lhs._M_base() < __rhs._M_base(); }
  524. template<typename _Tp, typename _Alloc>
  525. inline bool
  526. operator<=(const deque<_Tp, _Alloc>& __lhs,
  527. const deque<_Tp, _Alloc>& __rhs)
  528. { return __lhs._M_base() <= __rhs._M_base(); }
  529. template<typename _Tp, typename _Alloc>
  530. inline bool
  531. operator>=(const deque<_Tp, _Alloc>& __lhs,
  532. const deque<_Tp, _Alloc>& __rhs)
  533. { return __lhs._M_base() >= __rhs._M_base(); }
  534. template<typename _Tp, typename _Alloc>
  535. inline bool
  536. operator>(const deque<_Tp, _Alloc>& __lhs,
  537. const deque<_Tp, _Alloc>& __rhs)
  538. { return __lhs._M_base() > __rhs._M_base(); }
  539. template<typename _Tp, typename _Alloc>
  540. inline void
  541. swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
  542. { __lhs.swap(__rhs); }
  543. } // namespace __debug
  544. } // namespace std
  545. #endif