deque.tcc 34 KB

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