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.

1217 lines
36KB

  1. // Deque implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2001-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. /*
  21. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 1997
  35. * Silicon Graphics Computer Systems, Inc.
  36. *
  37. * Permission to use, copy, modify, distribute and sell this software
  38. * and its documentation for any purpose is hereby granted without fee,
  39. * provided that the above copyright notice appear in all copies and
  40. * that both that copyright notice and this permission notice appear
  41. * in supporting documentation. Silicon Graphics makes no
  42. * representations about the suitability of this software for any
  43. * purpose. It is provided "as is" without express or implied warranty.
  44. */
  45. /** @file bits/deque.tcc
  46. * This is an internal header file, included by other library headers.
  47. * Do not attempt to use it directly. @headername{deque}
  48. */
  49. #ifndef _DEQUE_TCC
  50. #define _DEQUE_TCC 1
  51. #include <bits/stl_algobase.h>
  52. namespace std _GLIBCXX_VISIBILITY(default)
  53. {
  54. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  55. _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  56. #if __cplusplus >= 201103L
  57. template <typename _Tp, typename _Alloc>
  58. void
  59. deque<_Tp, _Alloc>::
  60. _M_default_initialize()
  61. {
  62. _Map_pointer __cur;
  63. __try
  64. {
  65. for (__cur = this->_M_impl._M_start._M_node;
  66. __cur < this->_M_impl._M_finish._M_node;
  67. ++__cur)
  68. std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
  69. _M_get_Tp_allocator());
  70. std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
  71. this->_M_impl._M_finish._M_cur,
  72. _M_get_Tp_allocator());
  73. }
  74. __catch(...)
  75. {
  76. std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
  77. _M_get_Tp_allocator());
  78. __throw_exception_again;
  79. }
  80. }
  81. #endif
  82. template <typename _Tp, typename _Alloc>
  83. deque<_Tp, _Alloc>&
  84. deque<_Tp, _Alloc>::
  85. operator=(const deque& __x)
  86. {
  87. if (&__x != this)
  88. {
  89. #if __cplusplus >= 201103L
  90. if (_Alloc_traits::_S_propagate_on_copy_assign())
  91. {
  92. if (!_Alloc_traits::_S_always_equal()
  93. && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
  94. {
  95. // Replacement allocator cannot free existing storage,
  96. // so deallocate everything and take copy of __x's data.
  97. _M_replace_map(__x, __x.get_allocator());
  98. std::__alloc_on_copy(_M_get_Tp_allocator(),
  99. __x._M_get_Tp_allocator());
  100. return *this;
  101. }
  102. std::__alloc_on_copy(_M_get_Tp_allocator(),
  103. __x._M_get_Tp_allocator());
  104. }
  105. #endif
  106. const size_type __len = size();
  107. if (__len >= __x.size())
  108. _M_erase_at_end(std::copy(__x.begin(), __x.end(),
  109. this->_M_impl._M_start));
  110. else
  111. {
  112. const_iterator __mid = __x.begin() + difference_type(__len);
  113. std::copy(__x.begin(), __mid, this->_M_impl._M_start);
  114. _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(),
  115. std::random_access_iterator_tag());
  116. }
  117. }
  118. return *this;
  119. }
  120. #if __cplusplus >= 201103L
  121. template<typename _Tp, typename _Alloc>
  122. template<typename... _Args>
  123. #if __cplusplus > 201402L
  124. typename deque<_Tp, _Alloc>::reference
  125. #else
  126. void
  127. #endif
  128. deque<_Tp, _Alloc>::
  129. emplace_front(_Args&&... __args)
  130. {
  131. if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
  132. {
  133. _Alloc_traits::construct(this->_M_impl,
  134. this->_M_impl._M_start._M_cur - 1,
  135. std::forward<_Args>(__args)...);
  136. --this->_M_impl._M_start._M_cur;
  137. }
  138. else
  139. _M_push_front_aux(std::forward<_Args>(__args)...);
  140. #if __cplusplus > 201402L
  141. return front();
  142. #endif
  143. }
  144. template<typename _Tp, typename _Alloc>
  145. template<typename... _Args>
  146. #if __cplusplus > 201402L
  147. typename deque<_Tp, _Alloc>::reference
  148. #else
  149. void
  150. #endif
  151. deque<_Tp, _Alloc>::
  152. emplace_back(_Args&&... __args)
  153. {
  154. if (this->_M_impl._M_finish._M_cur
  155. != this->_M_impl._M_finish._M_last - 1)
  156. {
  157. _Alloc_traits::construct(this->_M_impl,
  158. this->_M_impl._M_finish._M_cur,
  159. std::forward<_Args>(__args)...);
  160. ++this->_M_impl._M_finish._M_cur;
  161. }
  162. else
  163. _M_push_back_aux(std::forward<_Args>(__args)...);
  164. #if __cplusplus > 201402L
  165. return back();
  166. #endif
  167. }
  168. #endif
  169. #if __cplusplus >= 201103L
  170. template<typename _Tp, typename _Alloc>
  171. template<typename... _Args>
  172. typename deque<_Tp, _Alloc>::iterator
  173. deque<_Tp, _Alloc>::
  174. emplace(const_iterator __position, _Args&&... __args)
  175. {
  176. if (__position._M_cur == this->_M_impl._M_start._M_cur)
  177. {
  178. emplace_front(std::forward<_Args>(__args)...);
  179. return this->_M_impl._M_start;
  180. }
  181. else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
  182. {
  183. emplace_back(std::forward<_Args>(__args)...);
  184. iterator __tmp = this->_M_impl._M_finish;
  185. --__tmp;
  186. return __tmp;
  187. }
  188. else
  189. return _M_insert_aux(__position._M_const_cast(),
  190. std::forward<_Args>(__args)...);
  191. }
  192. #endif
  193. template <typename _Tp, typename _Alloc>
  194. typename deque<_Tp, _Alloc>::iterator
  195. deque<_Tp, _Alloc>::
  196. #if __cplusplus >= 201103L
  197. insert(const_iterator __position, const value_type& __x)
  198. #else
  199. insert(iterator __position, const value_type& __x)
  200. #endif
  201. {
  202. if (__position._M_cur == this->_M_impl._M_start._M_cur)
  203. {
  204. push_front(__x);
  205. return this->_M_impl._M_start;
  206. }
  207. else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
  208. {
  209. push_back(__x);
  210. iterator __tmp = this->_M_impl._M_finish;
  211. --__tmp;
  212. return __tmp;
  213. }
  214. else
  215. return _M_insert_aux(__position._M_const_cast(), __x);
  216. }
  217. template <typename _Tp, typename _Alloc>
  218. typename deque<_Tp, _Alloc>::iterator
  219. deque<_Tp, _Alloc>::
  220. _M_erase(iterator __position)
  221. {
  222. iterator __next = __position;
  223. ++__next;
  224. const difference_type __index = __position - begin();
  225. if (static_cast<size_type>(__index) < (size() >> 1))
  226. {
  227. if (__position != begin())
  228. _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
  229. pop_front();
  230. }
  231. else
  232. {
  233. if (__next != end())
  234. _GLIBCXX_MOVE3(__next, end(), __position);
  235. pop_back();
  236. }
  237. return begin() + __index;
  238. }
  239. template <typename _Tp, typename _Alloc>
  240. typename deque<_Tp, _Alloc>::iterator
  241. deque<_Tp, _Alloc>::
  242. _M_erase(iterator __first, iterator __last)
  243. {
  244. if (__first == __last)
  245. return __first;
  246. else if (__first == begin() && __last == end())
  247. {
  248. clear();
  249. return end();
  250. }
  251. else
  252. {
  253. const difference_type __n = __last - __first;
  254. const difference_type __elems_before = __first - begin();
  255. if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
  256. {
  257. if (__first != begin())
  258. _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
  259. _M_erase_at_begin(begin() + __n);
  260. }
  261. else
  262. {
  263. if (__last != end())
  264. _GLIBCXX_MOVE3(__last, end(), __first);
  265. _M_erase_at_end(end() - __n);
  266. }
  267. return begin() + __elems_before;
  268. }
  269. }
  270. template <typename _Tp, class _Alloc>
  271. template <typename _InputIterator>
  272. void
  273. deque<_Tp, _Alloc>::
  274. _M_assign_aux(_InputIterator __first, _InputIterator __last,
  275. std::input_iterator_tag)
  276. {
  277. iterator __cur = begin();
  278. for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
  279. *__cur = *__first;
  280. if (__first == __last)
  281. _M_erase_at_end(__cur);
  282. else
  283. _M_range_insert_aux(end(), __first, __last,
  284. std::__iterator_category(__first));
  285. }
  286. template <typename _Tp, typename _Alloc>
  287. void
  288. deque<_Tp, _Alloc>::
  289. _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
  290. {
  291. if (__pos._M_cur == this->_M_impl._M_start._M_cur)
  292. {
  293. iterator __new_start = _M_reserve_elements_at_front(__n);
  294. __try
  295. {
  296. std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
  297. __x, _M_get_Tp_allocator());
  298. this->_M_impl._M_start = __new_start;
  299. }
  300. __catch(...)
  301. {
  302. _M_destroy_nodes(__new_start._M_node,
  303. this->_M_impl._M_start._M_node);
  304. __throw_exception_again;
  305. }
  306. }
  307. else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
  308. {
  309. iterator __new_finish = _M_reserve_elements_at_back(__n);
  310. __try
  311. {
  312. std::__uninitialized_fill_a(this->_M_impl._M_finish,
  313. __new_finish, __x,
  314. _M_get_Tp_allocator());
  315. this->_M_impl._M_finish = __new_finish;
  316. }
  317. __catch(...)
  318. {
  319. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  320. __new_finish._M_node + 1);
  321. __throw_exception_again;
  322. }
  323. }
  324. else
  325. _M_insert_aux(__pos, __n, __x);
  326. }
  327. #if __cplusplus >= 201103L
  328. template <typename _Tp, typename _Alloc>
  329. void
  330. deque<_Tp, _Alloc>::
  331. _M_default_append(size_type __n)
  332. {
  333. if (__n)
  334. {
  335. iterator __new_finish = _M_reserve_elements_at_back(__n);
  336. __try
  337. {
  338. std::__uninitialized_default_a(this->_M_impl._M_finish,
  339. __new_finish,
  340. _M_get_Tp_allocator());
  341. this->_M_impl._M_finish = __new_finish;
  342. }
  343. __catch(...)
  344. {
  345. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  346. __new_finish._M_node + 1);
  347. __throw_exception_again;
  348. }
  349. }
  350. }
  351. template <typename _Tp, typename _Alloc>
  352. bool
  353. deque<_Tp, _Alloc>::
  354. _M_shrink_to_fit()
  355. {
  356. const difference_type __front_capacity
  357. = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
  358. if (__front_capacity == 0)
  359. return false;
  360. const difference_type __back_capacity
  361. = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
  362. if (__front_capacity + __back_capacity < _S_buffer_size())
  363. return false;
  364. return std::__shrink_to_fit_aux<deque>::_S_do_it(*this);
  365. }
  366. #endif
  367. template <typename _Tp, typename _Alloc>
  368. void
  369. deque<_Tp, _Alloc>::
  370. _M_fill_initialize(const value_type& __value)
  371. {
  372. _Map_pointer __cur;
  373. __try
  374. {
  375. for (__cur = this->_M_impl._M_start._M_node;
  376. __cur < this->_M_impl._M_finish._M_node;
  377. ++__cur)
  378. std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
  379. __value, _M_get_Tp_allocator());
  380. std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
  381. this->_M_impl._M_finish._M_cur,
  382. __value, _M_get_Tp_allocator());
  383. }
  384. __catch(...)
  385. {
  386. std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
  387. _M_get_Tp_allocator());
  388. __throw_exception_again;
  389. }
  390. }
  391. template <typename _Tp, typename _Alloc>
  392. template <typename _InputIterator>
  393. void
  394. deque<_Tp, _Alloc>::
  395. _M_range_initialize(_InputIterator __first, _InputIterator __last,
  396. std::input_iterator_tag)
  397. {
  398. this->_M_initialize_map(0);
  399. __try
  400. {
  401. for (; __first != __last; ++__first)
  402. #if __cplusplus >= 201103L
  403. emplace_back(*__first);
  404. #else
  405. push_back(*__first);
  406. #endif
  407. }
  408. __catch(...)
  409. {
  410. clear();
  411. __throw_exception_again;
  412. }
  413. }
  414. template <typename _Tp, typename _Alloc>
  415. template <typename _ForwardIterator>
  416. void
  417. deque<_Tp, _Alloc>::
  418. _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
  419. std::forward_iterator_tag)
  420. {
  421. const size_type __n = std::distance(__first, __last);
  422. this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
  423. _Map_pointer __cur_node;
  424. __try
  425. {
  426. for (__cur_node = this->_M_impl._M_start._M_node;
  427. __cur_node < this->_M_impl._M_finish._M_node;
  428. ++__cur_node)
  429. {
  430. _ForwardIterator __mid = __first;
  431. std::advance(__mid, _S_buffer_size());
  432. std::__uninitialized_copy_a(__first, __mid, *__cur_node,
  433. _M_get_Tp_allocator());
  434. __first = __mid;
  435. }
  436. std::__uninitialized_copy_a(__first, __last,
  437. this->_M_impl._M_finish._M_first,
  438. _M_get_Tp_allocator());
  439. }
  440. __catch(...)
  441. {
  442. std::_Destroy(this->_M_impl._M_start,
  443. iterator(*__cur_node, __cur_node),
  444. _M_get_Tp_allocator());
  445. __throw_exception_again;
  446. }
  447. }
  448. // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
  449. template<typename _Tp, typename _Alloc>
  450. #if __cplusplus >= 201103L
  451. template<typename... _Args>
  452. void
  453. deque<_Tp, _Alloc>::
  454. _M_push_back_aux(_Args&&... __args)
  455. #else
  456. void
  457. deque<_Tp, _Alloc>::
  458. _M_push_back_aux(const value_type& __t)
  459. #endif
  460. {
  461. if (size() == max_size())
  462. __throw_length_error(
  463. __N("cannot create std::deque larger than max_size()"));
  464. _M_reserve_map_at_back();
  465. *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
  466. __try
  467. {
  468. #if __cplusplus >= 201103L
  469. _Alloc_traits::construct(this->_M_impl,
  470. this->_M_impl._M_finish._M_cur,
  471. std::forward<_Args>(__args)...);
  472. #else
  473. this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
  474. #endif
  475. this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
  476. + 1);
  477. this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
  478. }
  479. __catch(...)
  480. {
  481. _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
  482. __throw_exception_again;
  483. }
  484. }
  485. // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
  486. template<typename _Tp, typename _Alloc>
  487. #if __cplusplus >= 201103L
  488. template<typename... _Args>
  489. void
  490. deque<_Tp, _Alloc>::
  491. _M_push_front_aux(_Args&&... __args)
  492. #else
  493. void
  494. deque<_Tp, _Alloc>::
  495. _M_push_front_aux(const value_type& __t)
  496. #endif
  497. {
  498. if (size() == max_size())
  499. __throw_length_error(
  500. __N("cannot create std::deque larger than max_size()"));
  501. _M_reserve_map_at_front();
  502. *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
  503. __try
  504. {
  505. this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
  506. - 1);
  507. this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
  508. #if __cplusplus >= 201103L
  509. _Alloc_traits::construct(this->_M_impl,
  510. this->_M_impl._M_start._M_cur,
  511. std::forward<_Args>(__args)...);
  512. #else
  513. this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
  514. #endif
  515. }
  516. __catch(...)
  517. {
  518. ++this->_M_impl._M_start;
  519. _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
  520. __throw_exception_again;
  521. }
  522. }
  523. // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
  524. template <typename _Tp, typename _Alloc>
  525. void deque<_Tp, _Alloc>::
  526. _M_pop_back_aux()
  527. {
  528. _M_deallocate_node(this->_M_impl._M_finish._M_first);
  529. this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
  530. this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
  531. _Alloc_traits::destroy(_M_get_Tp_allocator(),
  532. this->_M_impl._M_finish._M_cur);
  533. }
  534. // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
  535. // Note that if the deque has at least one element (a precondition for this
  536. // member function), and if
  537. // _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
  538. // then the deque must have at least two nodes.
  539. template <typename _Tp, typename _Alloc>
  540. void deque<_Tp, _Alloc>::
  541. _M_pop_front_aux()
  542. {
  543. _Alloc_traits::destroy(_M_get_Tp_allocator(),
  544. this->_M_impl._M_start._M_cur);
  545. _M_deallocate_node(this->_M_impl._M_start._M_first);
  546. this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
  547. this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
  548. }
  549. template <typename _Tp, typename _Alloc>
  550. template <typename _InputIterator>
  551. void
  552. deque<_Tp, _Alloc>::
  553. _M_range_insert_aux(iterator __pos,
  554. _InputIterator __first, _InputIterator __last,
  555. std::input_iterator_tag)
  556. { std::copy(__first, __last, std::inserter(*this, __pos)); }
  557. template <typename _Tp, typename _Alloc>
  558. template <typename _ForwardIterator>
  559. void
  560. deque<_Tp, _Alloc>::
  561. _M_range_insert_aux(iterator __pos,
  562. _ForwardIterator __first, _ForwardIterator __last,
  563. std::forward_iterator_tag)
  564. {
  565. const size_type __n = std::distance(__first, __last);
  566. if (__pos._M_cur == this->_M_impl._M_start._M_cur)
  567. {
  568. iterator __new_start = _M_reserve_elements_at_front(__n);
  569. __try
  570. {
  571. std::__uninitialized_copy_a(__first, __last, __new_start,
  572. _M_get_Tp_allocator());
  573. this->_M_impl._M_start = __new_start;
  574. }
  575. __catch(...)
  576. {
  577. _M_destroy_nodes(__new_start._M_node,
  578. this->_M_impl._M_start._M_node);
  579. __throw_exception_again;
  580. }
  581. }
  582. else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
  583. {
  584. iterator __new_finish = _M_reserve_elements_at_back(__n);
  585. __try
  586. {
  587. std::__uninitialized_copy_a(__first, __last,
  588. this->_M_impl._M_finish,
  589. _M_get_Tp_allocator());
  590. this->_M_impl._M_finish = __new_finish;
  591. }
  592. __catch(...)
  593. {
  594. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  595. __new_finish._M_node + 1);
  596. __throw_exception_again;
  597. }
  598. }
  599. else
  600. _M_insert_aux(__pos, __first, __last, __n);
  601. }
  602. template<typename _Tp, typename _Alloc>
  603. #if __cplusplus >= 201103L
  604. template<typename... _Args>
  605. typename deque<_Tp, _Alloc>::iterator
  606. deque<_Tp, _Alloc>::
  607. _M_insert_aux(iterator __pos, _Args&&... __args)
  608. {
  609. value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
  610. #else
  611. typename deque<_Tp, _Alloc>::iterator
  612. deque<_Tp, _Alloc>::
  613. _M_insert_aux(iterator __pos, const value_type& __x)
  614. {
  615. value_type __x_copy = __x; // XXX copy
  616. #endif
  617. difference_type __index = __pos - this->_M_impl._M_start;
  618. if (static_cast<size_type>(__index) < size() / 2)
  619. {
  620. push_front(_GLIBCXX_MOVE(front()));
  621. iterator __front1 = this->_M_impl._M_start;
  622. ++__front1;
  623. iterator __front2 = __front1;
  624. ++__front2;
  625. __pos = this->_M_impl._M_start + __index;
  626. iterator __pos1 = __pos;
  627. ++__pos1;
  628. _GLIBCXX_MOVE3(__front2, __pos1, __front1);
  629. }
  630. else
  631. {
  632. push_back(_GLIBCXX_MOVE(back()));
  633. iterator __back1 = this->_M_impl._M_finish;
  634. --__back1;
  635. iterator __back2 = __back1;
  636. --__back2;
  637. __pos = this->_M_impl._M_start + __index;
  638. _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
  639. }
  640. *__pos = _GLIBCXX_MOVE(__x_copy);
  641. return __pos;
  642. }
  643. template <typename _Tp, typename _Alloc>
  644. void
  645. deque<_Tp, _Alloc>::
  646. _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
  647. {
  648. const difference_type __elems_before = __pos - this->_M_impl._M_start;
  649. const size_type __length = this->size();
  650. value_type __x_copy = __x;
  651. if (__elems_before < difference_type(__length / 2))
  652. {
  653. iterator __new_start = _M_reserve_elements_at_front(__n);
  654. iterator __old_start = this->_M_impl._M_start;
  655. __pos = this->_M_impl._M_start + __elems_before;
  656. __try
  657. {
  658. if (__elems_before >= difference_type(__n))
  659. {
  660. iterator __start_n = (this->_M_impl._M_start
  661. + difference_type(__n));
  662. std::__uninitialized_move_a(this->_M_impl._M_start,
  663. __start_n, __new_start,
  664. _M_get_Tp_allocator());
  665. this->_M_impl._M_start = __new_start;
  666. _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
  667. std::fill(__pos - difference_type(__n), __pos, __x_copy);
  668. }
  669. else
  670. {
  671. std::__uninitialized_move_fill(this->_M_impl._M_start,
  672. __pos, __new_start,
  673. this->_M_impl._M_start,
  674. __x_copy,
  675. _M_get_Tp_allocator());
  676. this->_M_impl._M_start = __new_start;
  677. std::fill(__old_start, __pos, __x_copy);
  678. }
  679. }
  680. __catch(...)
  681. {
  682. _M_destroy_nodes(__new_start._M_node,
  683. this->_M_impl._M_start._M_node);
  684. __throw_exception_again;
  685. }
  686. }
  687. else
  688. {
  689. iterator __new_finish = _M_reserve_elements_at_back(__n);
  690. iterator __old_finish = this->_M_impl._M_finish;
  691. const difference_type __elems_after =
  692. difference_type(__length) - __elems_before;
  693. __pos = this->_M_impl._M_finish - __elems_after;
  694. __try
  695. {
  696. if (__elems_after > difference_type(__n))
  697. {
  698. iterator __finish_n = (this->_M_impl._M_finish
  699. - difference_type(__n));
  700. std::__uninitialized_move_a(__finish_n,
  701. this->_M_impl._M_finish,
  702. this->_M_impl._M_finish,
  703. _M_get_Tp_allocator());
  704. this->_M_impl._M_finish = __new_finish;
  705. _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
  706. std::fill(__pos, __pos + difference_type(__n), __x_copy);
  707. }
  708. else
  709. {
  710. std::__uninitialized_fill_move(this->_M_impl._M_finish,
  711. __pos + difference_type(__n),
  712. __x_copy, __pos,
  713. this->_M_impl._M_finish,
  714. _M_get_Tp_allocator());
  715. this->_M_impl._M_finish = __new_finish;
  716. std::fill(__pos, __old_finish, __x_copy);
  717. }
  718. }
  719. __catch(...)
  720. {
  721. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  722. __new_finish._M_node + 1);
  723. __throw_exception_again;
  724. }
  725. }
  726. }
  727. template <typename _Tp, typename _Alloc>
  728. template <typename _ForwardIterator>
  729. void
  730. deque<_Tp, _Alloc>::
  731. _M_insert_aux(iterator __pos,
  732. _ForwardIterator __first, _ForwardIterator __last,
  733. size_type __n)
  734. {
  735. const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
  736. const size_type __length = size();
  737. if (static_cast<size_type>(__elemsbefore) < __length / 2)
  738. {
  739. iterator __new_start = _M_reserve_elements_at_front(__n);
  740. iterator __old_start = this->_M_impl._M_start;
  741. __pos = this->_M_impl._M_start + __elemsbefore;
  742. __try
  743. {
  744. if (__elemsbefore >= difference_type(__n))
  745. {
  746. iterator __start_n = (this->_M_impl._M_start
  747. + difference_type(__n));
  748. std::__uninitialized_move_a(this->_M_impl._M_start,
  749. __start_n, __new_start,
  750. _M_get_Tp_allocator());
  751. this->_M_impl._M_start = __new_start;
  752. _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
  753. std::copy(__first, __last, __pos - difference_type(__n));
  754. }
  755. else
  756. {
  757. _ForwardIterator __mid = __first;
  758. std::advance(__mid, difference_type(__n) - __elemsbefore);
  759. std::__uninitialized_move_copy(this->_M_impl._M_start,
  760. __pos, __first, __mid,
  761. __new_start,
  762. _M_get_Tp_allocator());
  763. this->_M_impl._M_start = __new_start;
  764. std::copy(__mid, __last, __old_start);
  765. }
  766. }
  767. __catch(...)
  768. {
  769. _M_destroy_nodes(__new_start._M_node,
  770. this->_M_impl._M_start._M_node);
  771. __throw_exception_again;
  772. }
  773. }
  774. else
  775. {
  776. iterator __new_finish = _M_reserve_elements_at_back(__n);
  777. iterator __old_finish = this->_M_impl._M_finish;
  778. const difference_type __elemsafter =
  779. difference_type(__length) - __elemsbefore;
  780. __pos = this->_M_impl._M_finish - __elemsafter;
  781. __try
  782. {
  783. if (__elemsafter > difference_type(__n))
  784. {
  785. iterator __finish_n = (this->_M_impl._M_finish
  786. - difference_type(__n));
  787. std::__uninitialized_move_a(__finish_n,
  788. this->_M_impl._M_finish,
  789. this->_M_impl._M_finish,
  790. _M_get_Tp_allocator());
  791. this->_M_impl._M_finish = __new_finish;
  792. _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
  793. std::copy(__first, __last, __pos);
  794. }
  795. else
  796. {
  797. _ForwardIterator __mid = __first;
  798. std::advance(__mid, __elemsafter);
  799. std::__uninitialized_copy_move(__mid, __last, __pos,
  800. this->_M_impl._M_finish,
  801. this->_M_impl._M_finish,
  802. _M_get_Tp_allocator());
  803. this->_M_impl._M_finish = __new_finish;
  804. std::copy(__first, __mid, __pos);
  805. }
  806. }
  807. __catch(...)
  808. {
  809. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  810. __new_finish._M_node + 1);
  811. __throw_exception_again;
  812. }
  813. }
  814. }
  815. template<typename _Tp, typename _Alloc>
  816. void
  817. deque<_Tp, _Alloc>::
  818. _M_destroy_data_aux(iterator __first, iterator __last)
  819. {
  820. for (_Map_pointer __node = __first._M_node + 1;
  821. __node < __last._M_node; ++__node)
  822. std::_Destroy(*__node, *__node + _S_buffer_size(),
  823. _M_get_Tp_allocator());
  824. if (__first._M_node != __last._M_node)
  825. {
  826. std::_Destroy(__first._M_cur, __first._M_last,
  827. _M_get_Tp_allocator());
  828. std::_Destroy(__last._M_first, __last._M_cur,
  829. _M_get_Tp_allocator());
  830. }
  831. else
  832. std::_Destroy(__first._M_cur, __last._M_cur,
  833. _M_get_Tp_allocator());
  834. }
  835. template <typename _Tp, typename _Alloc>
  836. void
  837. deque<_Tp, _Alloc>::
  838. _M_new_elements_at_front(size_type __new_elems)
  839. {
  840. if (this->max_size() - this->size() < __new_elems)
  841. __throw_length_error(__N("deque::_M_new_elements_at_front"));
  842. const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
  843. / _S_buffer_size());
  844. _M_reserve_map_at_front(__new_nodes);
  845. size_type __i;
  846. __try
  847. {
  848. for (__i = 1; __i <= __new_nodes; ++__i)
  849. *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
  850. }
  851. __catch(...)
  852. {
  853. for (size_type __j = 1; __j < __i; ++__j)
  854. _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
  855. __throw_exception_again;
  856. }
  857. }
  858. template <typename _Tp, typename _Alloc>
  859. void
  860. deque<_Tp, _Alloc>::
  861. _M_new_elements_at_back(size_type __new_elems)
  862. {
  863. if (this->max_size() - this->size() < __new_elems)
  864. __throw_length_error(__N("deque::_M_new_elements_at_back"));
  865. const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
  866. / _S_buffer_size());
  867. _M_reserve_map_at_back(__new_nodes);
  868. size_type __i;
  869. __try
  870. {
  871. for (__i = 1; __i <= __new_nodes; ++__i)
  872. *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
  873. }
  874. __catch(...)
  875. {
  876. for (size_type __j = 1; __j < __i; ++__j)
  877. _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
  878. __throw_exception_again;
  879. }
  880. }
  881. template <typename _Tp, typename _Alloc>
  882. void
  883. deque<_Tp, _Alloc>::
  884. _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
  885. {
  886. const size_type __old_num_nodes
  887. = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
  888. const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
  889. _Map_pointer __new_nstart;
  890. if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
  891. {
  892. __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
  893. - __new_num_nodes) / 2
  894. + (__add_at_front ? __nodes_to_add : 0);
  895. if (__new_nstart < this->_M_impl._M_start._M_node)
  896. std::copy(this->_M_impl._M_start._M_node,
  897. this->_M_impl._M_finish._M_node + 1,
  898. __new_nstart);
  899. else
  900. std::copy_backward(this->_M_impl._M_start._M_node,
  901. this->_M_impl._M_finish._M_node + 1,
  902. __new_nstart + __old_num_nodes);
  903. }
  904. else
  905. {
  906. size_type __new_map_size = this->_M_impl._M_map_size
  907. + std::max(this->_M_impl._M_map_size,
  908. __nodes_to_add) + 2;
  909. _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
  910. __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
  911. + (__add_at_front ? __nodes_to_add : 0);
  912. std::copy(this->_M_impl._M_start._M_node,
  913. this->_M_impl._M_finish._M_node + 1,
  914. __new_nstart);
  915. _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
  916. this->_M_impl._M_map = __new_map;
  917. this->_M_impl._M_map_size = __new_map_size;
  918. }
  919. this->_M_impl._M_start._M_set_node(__new_nstart);
  920. this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
  921. }
  922. _GLIBCXX_END_NAMESPACE_CONTAINER
  923. // Overload for deque::iterators, exploiting the "segmented-iterator
  924. // optimization".
  925. template<typename _Tp, typename _VTp>
  926. void
  927. __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
  928. const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __last,
  929. const _VTp& __value)
  930. {
  931. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
  932. if (__first._M_node != __last._M_node)
  933. {
  934. std::__fill_a1(__first._M_cur, __first._M_last, __value);
  935. for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
  936. __node < __last._M_node; ++__node)
  937. std::__fill_a1(*__node, *__node + _Iter::_S_buffer_size(), __value);
  938. std::__fill_a1(__last._M_first, __last._M_cur, __value);
  939. }
  940. else
  941. std::__fill_a1(__first._M_cur, __last._M_cur, __value);
  942. }
  943. template<bool _IsMove,
  944. typename _Tp, typename _Ref, typename _Ptr, typename _OI>
  945. _OI
  946. __copy_move_dit(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
  947. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
  948. _OI __result)
  949. {
  950. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
  951. if (__first._M_node != __last._M_node)
  952. {
  953. __result
  954. = std::__copy_move_a1<_IsMove>(__first._M_cur, __first._M_last,
  955. __result);
  956. for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
  957. __node != __last._M_node; ++__node)
  958. __result
  959. = std::__copy_move_a1<_IsMove>(*__node,
  960. *__node + _Iter::_S_buffer_size(),
  961. __result);
  962. return std::__copy_move_a1<_IsMove>(__last._M_first, __last._M_cur,
  963. __result);
  964. }
  965. return std::__copy_move_a1<_IsMove>(__first._M_cur, __last._M_cur,
  966. __result);
  967. }
  968. template<bool _IsMove,
  969. typename _Tp, typename _Ref, typename _Ptr, typename _OI>
  970. _OI
  971. __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
  972. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
  973. _OI __result)
  974. { return __copy_move_dit<_IsMove>(__first, __last, __result); }
  975. template<bool _IsMove,
  976. typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
  977. _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
  978. __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
  979. _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
  980. _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
  981. { return __copy_move_dit<_IsMove>(__first, __last, __result); }
  982. template<bool _IsMove, typename _II, typename _Tp>
  983. typename __gnu_cxx::__enable_if<
  984. __is_random_access_iter<_II>::__value,
  985. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
  986. __copy_move_a1(_II __first, _II __last,
  987. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
  988. {
  989. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
  990. typedef typename _Iter::difference_type difference_type;
  991. difference_type __len = __last - __first;
  992. while (__len > 0)
  993. {
  994. const difference_type __clen
  995. = std::min(__len, __result._M_last - __result._M_cur);
  996. std::__copy_move_a1<_IsMove>(__first, __first + __clen,
  997. __result._M_cur);
  998. __first += __clen;
  999. __result += __clen;
  1000. __len -= __clen;
  1001. }
  1002. return __result;
  1003. }
  1004. template<bool _IsMove,
  1005. typename _Tp, typename _Ref, typename _Ptr, typename _OI>
  1006. _OI
  1007. __copy_move_backward_dit(
  1008. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
  1009. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
  1010. _OI __result)
  1011. {
  1012. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
  1013. if (__first._M_node != __last._M_node)
  1014. {
  1015. __result = std::__copy_move_backward_a1<_IsMove>(
  1016. __last._M_first, __last._M_cur, __result);
  1017. for (typename _Iter::_Map_pointer __node = __last._M_node - 1;
  1018. __node != __first._M_node; --__node)
  1019. __result = std::__copy_move_backward_a1<_IsMove>(
  1020. *__node, *__node + _Iter::_S_buffer_size(), __result);
  1021. return std::__copy_move_backward_a1<_IsMove>(
  1022. __first._M_cur, __first._M_last, __result);
  1023. }
  1024. return std::__copy_move_backward_a1<_IsMove>(
  1025. __first._M_cur, __last._M_cur, __result);
  1026. }
  1027. template<bool _IsMove,
  1028. typename _Tp, typename _Ref, typename _Ptr, typename _OI>
  1029. _OI
  1030. __copy_move_backward_a1(
  1031. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
  1032. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
  1033. _OI __result)
  1034. { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
  1035. template<bool _IsMove,
  1036. typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
  1037. _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
  1038. __copy_move_backward_a1(
  1039. _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
  1040. _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
  1041. _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
  1042. { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
  1043. template<bool _IsMove, typename _II, typename _Tp>
  1044. typename __gnu_cxx::__enable_if<
  1045. __is_random_access_iter<_II>::__value,
  1046. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
  1047. __copy_move_backward_a1(_II __first, _II __last,
  1048. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
  1049. {
  1050. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
  1051. typedef typename _Iter::difference_type difference_type;
  1052. difference_type __len = __last - __first;
  1053. while (__len > 0)
  1054. {
  1055. difference_type __rlen = __result._M_cur - __result._M_first;
  1056. _Tp* __rend = __result._M_cur;
  1057. if (!__rlen)
  1058. {
  1059. __rlen = _Iter::_S_buffer_size();
  1060. __rend = *(__result._M_node - 1) + __rlen;
  1061. }
  1062. const difference_type __clen = std::min(__len, __rlen);
  1063. std::__copy_move_backward_a1<_IsMove>(__last - __clen, __last, __rend);
  1064. __last -= __clen;
  1065. __result -= __clen;
  1066. __len -= __clen;
  1067. }
  1068. return __result;
  1069. }
  1070. template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
  1071. bool
  1072. __equal_dit(
  1073. const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __first1,
  1074. const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __last1,
  1075. _II __first2)
  1076. {
  1077. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
  1078. if (__first1._M_node != __last1._M_node)
  1079. {
  1080. if (!std::__equal_aux1(__first1._M_cur, __first1._M_last, __first2))
  1081. return false;
  1082. __first2 += __first1._M_last - __first1._M_cur;
  1083. for (typename _Iter::_Map_pointer __node = __first1._M_node + 1;
  1084. __node != __last1._M_node;
  1085. __first2 += _Iter::_S_buffer_size(), ++__node)
  1086. if (!std::__equal_aux1(*__node, *__node + _Iter::_S_buffer_size(),
  1087. __first2))
  1088. return false;
  1089. return std::__equal_aux1(__last1._M_first, __last1._M_cur, __first2);
  1090. }
  1091. return std::__equal_aux1(__first1._M_cur, __last1._M_cur, __first2);
  1092. }
  1093. template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
  1094. typename __gnu_cxx::__enable_if<
  1095. __is_random_access_iter<_II>::__value, bool>::__type
  1096. __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first1,
  1097. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last1,
  1098. _II __first2)
  1099. { return std::__equal_dit(__first1, __last1, __first2); }
  1100. template<typename _Tp1, typename _Ref1, typename _Ptr1,
  1101. typename _Tp2, typename _Ref2, typename _Ptr2>
  1102. bool
  1103. __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
  1104. _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
  1105. _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2)
  1106. { return std::__equal_dit(__first1, __last1, __first2); }
  1107. template<typename _II, typename _Tp, typename _Ref, typename _Ptr>
  1108. typename __gnu_cxx::__enable_if<
  1109. __is_random_access_iter<_II>::__value, bool>::__type
  1110. __equal_aux1(_II __first1, _II __last1,
  1111. _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first2)
  1112. {
  1113. typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
  1114. typedef typename _Iter::difference_type difference_type;
  1115. difference_type __len = __last1 - __first1;
  1116. while (__len > 0)
  1117. {
  1118. const difference_type __clen
  1119. = std::min(__len, __first2._M_last - __first2._M_cur);
  1120. if (!std::__equal_aux1(__first1, __first1 + __clen, __first2._M_cur))
  1121. return false;
  1122. __first1 += __clen;
  1123. __len -= __clen;
  1124. __first2 += __clen;
  1125. }
  1126. return true;
  1127. }
  1128. _GLIBCXX_END_NAMESPACE_VERSION
  1129. } // namespace std
  1130. #endif