deque.tcc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. // Deque implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  3. // Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library. This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Under Section 7 of GPL version 3, you are granted additional
  15. // permissions described in the GCC Runtime Library Exception, version
  16. // 3.1, as published by the Free Software Foundation.
  17. // You should have received a copy of the GNU General Public License and
  18. // a copy of the GCC Runtime Library Exception along with this program;
  19. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  20. // <http://www.gnu.org/licenses/>.
  21. /*
  22. *
  23. * Copyright (c) 1994
  24. * Hewlett-Packard Company
  25. *
  26. * Permission to use, copy, modify, distribute and sell this software
  27. * and its documentation for any purpose is hereby granted without fee,
  28. * provided that the above copyright notice appear in all copies and
  29. * that both that copyright notice and this permission notice appear
  30. * in supporting documentation. Hewlett-Packard Company makes no
  31. * representations about the suitability of this software for any
  32. * purpose. It is provided "as is" without express or implied warranty.
  33. *
  34. *
  35. * Copyright (c) 1997
  36. * Silicon Graphics Computer Systems, Inc.
  37. *
  38. * Permission to use, copy, modify, distribute and sell this software
  39. * and its documentation for any purpose is hereby granted without fee,
  40. * provided that the above copyright notice appear in all copies and
  41. * that both that copyright notice and this permission notice appear
  42. * in supporting documentation. Silicon Graphics makes no
  43. * representations about the suitability of this software for any
  44. * purpose. It is provided "as is" without express or implied warranty.
  45. */
  46. /** @file deque.tcc
  47. * This is an internal header file, included by other library headers.
  48. * You should not attempt to use it directly.
  49. */
  50. #ifndef _DEQUE_TCC
  51. #define _DEQUE_TCC 1
  52. _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
  53. template <typename _Tp, typename _Alloc>
  54. deque<_Tp, _Alloc>&
  55. deque<_Tp, _Alloc>::
  56. operator=(const deque& __x)
  57. {
  58. const size_type __len = size();
  59. if (&__x != this)
  60. {
  61. if (__len >= __x.size())
  62. _M_erase_at_end(std::copy(__x.begin(), __x.end(),
  63. this->_M_impl._M_start));
  64. else
  65. {
  66. const_iterator __mid = __x.begin() + difference_type(__len);
  67. std::copy(__x.begin(), __mid, this->_M_impl._M_start);
  68. insert(this->_M_impl._M_finish, __mid, __x.end());
  69. }
  70. }
  71. return *this;
  72. }
  73. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  74. template<typename _Tp, typename _Alloc>
  75. template<typename... _Args>
  76. void
  77. deque<_Tp, _Alloc>::
  78. emplace_front(_Args&&... __args)
  79. {
  80. if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
  81. {
  82. this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1,
  83. std::forward<_Args>(__args)...);
  84. --this->_M_impl._M_start._M_cur;
  85. }
  86. else
  87. _M_push_front_aux(std::forward<_Args>(__args)...);
  88. }
  89. template<typename _Tp, typename _Alloc>
  90. template<typename... _Args>
  91. void
  92. deque<_Tp, _Alloc>::
  93. emplace_back(_Args&&... __args)
  94. {
  95. if (this->_M_impl._M_finish._M_cur
  96. != this->_M_impl._M_finish._M_last - 1)
  97. {
  98. this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
  99. std::forward<_Args>(__args)...);
  100. ++this->_M_impl._M_finish._M_cur;
  101. }
  102. else
  103. _M_push_back_aux(std::forward<_Args>(__args)...);
  104. }
  105. #endif
  106. template <typename _Tp, typename _Alloc>
  107. typename deque<_Tp, _Alloc>::iterator
  108. deque<_Tp, _Alloc>::
  109. insert(iterator __position, const value_type& __x)
  110. {
  111. if (__position._M_cur == this->_M_impl._M_start._M_cur)
  112. {
  113. push_front(__x);
  114. return this->_M_impl._M_start;
  115. }
  116. else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
  117. {
  118. push_back(__x);
  119. iterator __tmp = this->_M_impl._M_finish;
  120. --__tmp;
  121. return __tmp;
  122. }
  123. else
  124. return _M_insert_aux(__position, __x);
  125. }
  126. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  127. template<typename _Tp, typename _Alloc>
  128. template<typename... _Args>
  129. typename deque<_Tp, _Alloc>::iterator
  130. deque<_Tp, _Alloc>::
  131. emplace(iterator __position, _Args&&... __args)
  132. {
  133. if (__position._M_cur == this->_M_impl._M_start._M_cur)
  134. {
  135. push_front(std::forward<_Args>(__args)...);
  136. return this->_M_impl._M_start;
  137. }
  138. else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
  139. {
  140. push_back(std::forward<_Args>(__args)...);
  141. iterator __tmp = this->_M_impl._M_finish;
  142. --__tmp;
  143. return __tmp;
  144. }
  145. else
  146. return _M_insert_aux(__position, std::forward<_Args>(__args)...);
  147. }
  148. #endif
  149. template <typename _Tp, typename _Alloc>
  150. typename deque<_Tp, _Alloc>::iterator
  151. deque<_Tp, _Alloc>::
  152. erase(iterator __position)
  153. {
  154. iterator __next = __position;
  155. ++__next;
  156. const difference_type __index = __position - begin();
  157. if (static_cast<size_type>(__index) < (size() >> 1))
  158. {
  159. if (__position != begin())
  160. _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
  161. pop_front();
  162. }
  163. else
  164. {
  165. if (__next != end())
  166. _GLIBCXX_MOVE3(__next, end(), __position);
  167. pop_back();
  168. }
  169. return begin() + __index;
  170. }
  171. template <typename _Tp, typename _Alloc>
  172. typename deque<_Tp, _Alloc>::iterator
  173. deque<_Tp, _Alloc>::
  174. erase(iterator __first, iterator __last)
  175. {
  176. if (__first == begin() && __last == end())
  177. {
  178. clear();
  179. return end();
  180. }
  181. else
  182. {
  183. const difference_type __n = __last - __first;
  184. const difference_type __elems_before = __first - begin();
  185. if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
  186. {
  187. if (__first != begin())
  188. _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
  189. _M_erase_at_begin(begin() + __n);
  190. }
  191. else
  192. {
  193. if (__last != end())
  194. _GLIBCXX_MOVE3(__last, end(), __first);
  195. _M_erase_at_end(end() - __n);
  196. }
  197. return begin() + __elems_before;
  198. }
  199. }
  200. template <typename _Tp, class _Alloc>
  201. template <typename _InputIterator>
  202. void
  203. deque<_Tp, _Alloc>::
  204. _M_assign_aux(_InputIterator __first, _InputIterator __last,
  205. std::input_iterator_tag)
  206. {
  207. iterator __cur = begin();
  208. for (; __first != __last && __cur != end(); ++__cur, ++__first)
  209. *__cur = *__first;
  210. if (__first == __last)
  211. _M_erase_at_end(__cur);
  212. else
  213. insert(end(), __first, __last);
  214. }
  215. template <typename _Tp, typename _Alloc>
  216. void
  217. deque<_Tp, _Alloc>::
  218. _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
  219. {
  220. if (__pos._M_cur == this->_M_impl._M_start._M_cur)
  221. {
  222. iterator __new_start = _M_reserve_elements_at_front(__n);
  223. __try
  224. {
  225. std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
  226. __x, _M_get_Tp_allocator());
  227. this->_M_impl._M_start = __new_start;
  228. }
  229. __catch(...)
  230. {
  231. _M_destroy_nodes(__new_start._M_node,
  232. this->_M_impl._M_start._M_node);
  233. __throw_exception_again;
  234. }
  235. }
  236. else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
  237. {
  238. iterator __new_finish = _M_reserve_elements_at_back(__n);
  239. __try
  240. {
  241. std::__uninitialized_fill_a(this->_M_impl._M_finish,
  242. __new_finish, __x,
  243. _M_get_Tp_allocator());
  244. this->_M_impl._M_finish = __new_finish;
  245. }
  246. __catch(...)
  247. {
  248. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  249. __new_finish._M_node + 1);
  250. __throw_exception_again;
  251. }
  252. }
  253. else
  254. _M_insert_aux(__pos, __n, __x);
  255. }
  256. template <typename _Tp, typename _Alloc>
  257. void
  258. deque<_Tp, _Alloc>::
  259. _M_fill_initialize(const value_type& __value)
  260. {
  261. _Map_pointer __cur;
  262. __try
  263. {
  264. for (__cur = this->_M_impl._M_start._M_node;
  265. __cur < this->_M_impl._M_finish._M_node;
  266. ++__cur)
  267. std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
  268. __value, _M_get_Tp_allocator());
  269. std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
  270. this->_M_impl._M_finish._M_cur,
  271. __value, _M_get_Tp_allocator());
  272. }
  273. __catch(...)
  274. {
  275. std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
  276. _M_get_Tp_allocator());
  277. __throw_exception_again;
  278. }
  279. }
  280. template <typename _Tp, typename _Alloc>
  281. template <typename _InputIterator>
  282. void
  283. deque<_Tp, _Alloc>::
  284. _M_range_initialize(_InputIterator __first, _InputIterator __last,
  285. std::input_iterator_tag)
  286. {
  287. this->_M_initialize_map(0);
  288. __try
  289. {
  290. for (; __first != __last; ++__first)
  291. push_back(*__first);
  292. }
  293. __catch(...)
  294. {
  295. clear();
  296. __throw_exception_again;
  297. }
  298. }
  299. template <typename _Tp, typename _Alloc>
  300. template <typename _ForwardIterator>
  301. void
  302. deque<_Tp, _Alloc>::
  303. _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
  304. std::forward_iterator_tag)
  305. {
  306. const size_type __n = std::distance(__first, __last);
  307. this->_M_initialize_map(__n);
  308. _Map_pointer __cur_node;
  309. __try
  310. {
  311. for (__cur_node = this->_M_impl._M_start._M_node;
  312. __cur_node < this->_M_impl._M_finish._M_node;
  313. ++__cur_node)
  314. {
  315. _ForwardIterator __mid = __first;
  316. std::advance(__mid, _S_buffer_size());
  317. std::__uninitialized_copy_a(__first, __mid, *__cur_node,
  318. _M_get_Tp_allocator());
  319. __first = __mid;
  320. }
  321. std::__uninitialized_copy_a(__first, __last,
  322. this->_M_impl._M_finish._M_first,
  323. _M_get_Tp_allocator());
  324. }
  325. __catch(...)
  326. {
  327. std::_Destroy(this->_M_impl._M_start,
  328. iterator(*__cur_node, __cur_node),
  329. _M_get_Tp_allocator());
  330. __throw_exception_again;
  331. }
  332. }
  333. // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
  334. template<typename _Tp, typename _Alloc>
  335. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  336. template<typename... _Args>
  337. void
  338. deque<_Tp, _Alloc>::
  339. _M_push_back_aux(_Args&&... __args)
  340. #else
  341. void
  342. deque<_Tp, _Alloc>::
  343. _M_push_back_aux(const value_type& __t)
  344. #endif
  345. {
  346. _M_reserve_map_at_back();
  347. *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
  348. __try
  349. {
  350. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  351. this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
  352. std::forward<_Args>(__args)...);
  353. #else
  354. this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
  355. #endif
  356. this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
  357. + 1);
  358. this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
  359. }
  360. __catch(...)
  361. {
  362. _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
  363. __throw_exception_again;
  364. }
  365. }
  366. // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
  367. template<typename _Tp, typename _Alloc>
  368. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  369. template<typename... _Args>
  370. void
  371. deque<_Tp, _Alloc>::
  372. _M_push_front_aux(_Args&&... __args)
  373. #else
  374. void
  375. deque<_Tp, _Alloc>::
  376. _M_push_front_aux(const value_type& __t)
  377. #endif
  378. {
  379. _M_reserve_map_at_front();
  380. *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
  381. __try
  382. {
  383. this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
  384. - 1);
  385. this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
  386. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  387. this->_M_impl.construct(this->_M_impl._M_start._M_cur,
  388. std::forward<_Args>(__args)...);
  389. #else
  390. this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
  391. #endif
  392. }
  393. __catch(...)
  394. {
  395. ++this->_M_impl._M_start;
  396. _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
  397. __throw_exception_again;
  398. }
  399. }
  400. // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
  401. template <typename _Tp, typename _Alloc>
  402. void deque<_Tp, _Alloc>::
  403. _M_pop_back_aux()
  404. {
  405. _M_deallocate_node(this->_M_impl._M_finish._M_first);
  406. this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
  407. this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
  408. this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
  409. }
  410. // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
  411. // Note that if the deque has at least one element (a precondition for this
  412. // member function), and if
  413. // _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
  414. // then the deque must have at least two nodes.
  415. template <typename _Tp, typename _Alloc>
  416. void deque<_Tp, _Alloc>::
  417. _M_pop_front_aux()
  418. {
  419. this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
  420. _M_deallocate_node(this->_M_impl._M_start._M_first);
  421. this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
  422. this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
  423. }
  424. template <typename _Tp, typename _Alloc>
  425. template <typename _InputIterator>
  426. void
  427. deque<_Tp, _Alloc>::
  428. _M_range_insert_aux(iterator __pos,
  429. _InputIterator __first, _InputIterator __last,
  430. std::input_iterator_tag)
  431. { std::copy(__first, __last, std::inserter(*this, __pos)); }
  432. template <typename _Tp, typename _Alloc>
  433. template <typename _ForwardIterator>
  434. void
  435. deque<_Tp, _Alloc>::
  436. _M_range_insert_aux(iterator __pos,
  437. _ForwardIterator __first, _ForwardIterator __last,
  438. std::forward_iterator_tag)
  439. {
  440. const size_type __n = std::distance(__first, __last);
  441. if (__pos._M_cur == this->_M_impl._M_start._M_cur)
  442. {
  443. iterator __new_start = _M_reserve_elements_at_front(__n);
  444. __try
  445. {
  446. std::__uninitialized_copy_a(__first, __last, __new_start,
  447. _M_get_Tp_allocator());
  448. this->_M_impl._M_start = __new_start;
  449. }
  450. __catch(...)
  451. {
  452. _M_destroy_nodes(__new_start._M_node,
  453. this->_M_impl._M_start._M_node);
  454. __throw_exception_again;
  455. }
  456. }
  457. else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
  458. {
  459. iterator __new_finish = _M_reserve_elements_at_back(__n);
  460. __try
  461. {
  462. std::__uninitialized_copy_a(__first, __last,
  463. this->_M_impl._M_finish,
  464. _M_get_Tp_allocator());
  465. this->_M_impl._M_finish = __new_finish;
  466. }
  467. __catch(...)
  468. {
  469. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  470. __new_finish._M_node + 1);
  471. __throw_exception_again;
  472. }
  473. }
  474. else
  475. _M_insert_aux(__pos, __first, __last, __n);
  476. }
  477. template<typename _Tp, typename _Alloc>
  478. #ifdef __GXX_EXPERIMENTAL_CXX0X__
  479. template<typename... _Args>
  480. typename deque<_Tp, _Alloc>::iterator
  481. deque<_Tp, _Alloc>::
  482. _M_insert_aux(iterator __pos, _Args&&... __args)
  483. {
  484. value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
  485. #else
  486. typename deque<_Tp, _Alloc>::iterator
  487. deque<_Tp, _Alloc>::
  488. _M_insert_aux(iterator __pos, const value_type& __x)
  489. {
  490. value_type __x_copy = __x; // XXX copy
  491. #endif
  492. difference_type __index = __pos - this->_M_impl._M_start;
  493. if (static_cast<size_type>(__index) < size() / 2)
  494. {
  495. push_front(_GLIBCXX_MOVE(front()));
  496. iterator __front1 = this->_M_impl._M_start;
  497. ++__front1;
  498. iterator __front2 = __front1;
  499. ++__front2;
  500. __pos = this->_M_impl._M_start + __index;
  501. iterator __pos1 = __pos;
  502. ++__pos1;
  503. _GLIBCXX_MOVE3(__front2, __pos1, __front1);
  504. }
  505. else
  506. {
  507. push_back(_GLIBCXX_MOVE(back()));
  508. iterator __back1 = this->_M_impl._M_finish;
  509. --__back1;
  510. iterator __back2 = __back1;
  511. --__back2;
  512. __pos = this->_M_impl._M_start + __index;
  513. _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
  514. }
  515. *__pos = _GLIBCXX_MOVE(__x_copy);
  516. return __pos;
  517. }
  518. template <typename _Tp, typename _Alloc>
  519. void
  520. deque<_Tp, _Alloc>::
  521. _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
  522. {
  523. const difference_type __elems_before = __pos - this->_M_impl._M_start;
  524. const size_type __length = this->size();
  525. value_type __x_copy = __x;
  526. if (__elems_before < difference_type(__length / 2))
  527. {
  528. iterator __new_start = _M_reserve_elements_at_front(__n);
  529. iterator __old_start = this->_M_impl._M_start;
  530. __pos = this->_M_impl._M_start + __elems_before;
  531. __try
  532. {
  533. if (__elems_before >= difference_type(__n))
  534. {
  535. iterator __start_n = (this->_M_impl._M_start
  536. + difference_type(__n));
  537. std::__uninitialized_move_a(this->_M_impl._M_start,
  538. __start_n, __new_start,
  539. _M_get_Tp_allocator());
  540. this->_M_impl._M_start = __new_start;
  541. _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
  542. std::fill(__pos - difference_type(__n), __pos, __x_copy);
  543. }
  544. else
  545. {
  546. std::__uninitialized_move_fill(this->_M_impl._M_start,
  547. __pos, __new_start,
  548. this->_M_impl._M_start,
  549. __x_copy,
  550. _M_get_Tp_allocator());
  551. this->_M_impl._M_start = __new_start;
  552. std::fill(__old_start, __pos, __x_copy);
  553. }
  554. }
  555. __catch(...)
  556. {
  557. _M_destroy_nodes(__new_start._M_node,
  558. this->_M_impl._M_start._M_node);
  559. __throw_exception_again;
  560. }
  561. }
  562. else
  563. {
  564. iterator __new_finish = _M_reserve_elements_at_back(__n);
  565. iterator __old_finish = this->_M_impl._M_finish;
  566. const difference_type __elems_after =
  567. difference_type(__length) - __elems_before;
  568. __pos = this->_M_impl._M_finish - __elems_after;
  569. __try
  570. {
  571. if (__elems_after > difference_type(__n))
  572. {
  573. iterator __finish_n = (this->_M_impl._M_finish
  574. - difference_type(__n));
  575. std::__uninitialized_move_a(__finish_n,
  576. this->_M_impl._M_finish,
  577. this->_M_impl._M_finish,
  578. _M_get_Tp_allocator());
  579. this->_M_impl._M_finish = __new_finish;
  580. _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
  581. std::fill(__pos, __pos + difference_type(__n), __x_copy);
  582. }
  583. else
  584. {
  585. std::__uninitialized_fill_move(this->_M_impl._M_finish,
  586. __pos + difference_type(__n),
  587. __x_copy, __pos,
  588. this->_M_impl._M_finish,
  589. _M_get_Tp_allocator());
  590. this->_M_impl._M_finish = __new_finish;
  591. std::fill(__pos, __old_finish, __x_copy);
  592. }
  593. }
  594. __catch(...)
  595. {
  596. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  597. __new_finish._M_node + 1);
  598. __throw_exception_again;
  599. }
  600. }
  601. }
  602. template <typename _Tp, typename _Alloc>
  603. template <typename _ForwardIterator>
  604. void
  605. deque<_Tp, _Alloc>::
  606. _M_insert_aux(iterator __pos,
  607. _ForwardIterator __first, _ForwardIterator __last,
  608. size_type __n)
  609. {
  610. const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
  611. const size_type __length = size();
  612. if (static_cast<size_type>(__elemsbefore) < __length / 2)
  613. {
  614. iterator __new_start = _M_reserve_elements_at_front(__n);
  615. iterator __old_start = this->_M_impl._M_start;
  616. __pos = this->_M_impl._M_start + __elemsbefore;
  617. __try
  618. {
  619. if (__elemsbefore >= difference_type(__n))
  620. {
  621. iterator __start_n = (this->_M_impl._M_start
  622. + difference_type(__n));
  623. std::__uninitialized_move_a(this->_M_impl._M_start,
  624. __start_n, __new_start,
  625. _M_get_Tp_allocator());
  626. this->_M_impl._M_start = __new_start;
  627. _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
  628. std::copy(__first, __last, __pos - difference_type(__n));
  629. }
  630. else
  631. {
  632. _ForwardIterator __mid = __first;
  633. std::advance(__mid, difference_type(__n) - __elemsbefore);
  634. std::__uninitialized_move_copy(this->_M_impl._M_start,
  635. __pos, __first, __mid,
  636. __new_start,
  637. _M_get_Tp_allocator());
  638. this->_M_impl._M_start = __new_start;
  639. std::copy(__mid, __last, __old_start);
  640. }
  641. }
  642. __catch(...)
  643. {
  644. _M_destroy_nodes(__new_start._M_node,
  645. this->_M_impl._M_start._M_node);
  646. __throw_exception_again;
  647. }
  648. }
  649. else
  650. {
  651. iterator __new_finish = _M_reserve_elements_at_back(__n);
  652. iterator __old_finish = this->_M_impl._M_finish;
  653. const difference_type __elemsafter =
  654. difference_type(__length) - __elemsbefore;
  655. __pos = this->_M_impl._M_finish - __elemsafter;
  656. __try
  657. {
  658. if (__elemsafter > difference_type(__n))
  659. {
  660. iterator __finish_n = (this->_M_impl._M_finish
  661. - difference_type(__n));
  662. std::__uninitialized_move_a(__finish_n,
  663. this->_M_impl._M_finish,
  664. this->_M_impl._M_finish,
  665. _M_get_Tp_allocator());
  666. this->_M_impl._M_finish = __new_finish;
  667. _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
  668. std::copy(__first, __last, __pos);
  669. }
  670. else
  671. {
  672. _ForwardIterator __mid = __first;
  673. std::advance(__mid, __elemsafter);
  674. std::__uninitialized_copy_move(__mid, __last, __pos,
  675. this->_M_impl._M_finish,
  676. this->_M_impl._M_finish,
  677. _M_get_Tp_allocator());
  678. this->_M_impl._M_finish = __new_finish;
  679. std::copy(__first, __mid, __pos);
  680. }
  681. }
  682. __catch(...)
  683. {
  684. _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
  685. __new_finish._M_node + 1);
  686. __throw_exception_again;
  687. }
  688. }
  689. }
  690. template<typename _Tp, typename _Alloc>
  691. void
  692. deque<_Tp, _Alloc>::
  693. _M_destroy_data_aux(iterator __first, iterator __last)
  694. {
  695. for (_Map_pointer __node = __first._M_node + 1;
  696. __node < __last._M_node; ++__node)
  697. std::_Destroy(*__node, *__node + _S_buffer_size(),
  698. _M_get_Tp_allocator());
  699. if (__first._M_node != __last._M_node)
  700. {
  701. std::_Destroy(__first._M_cur, __first._M_last,
  702. _M_get_Tp_allocator());
  703. std::_Destroy(__last._M_first, __last._M_cur,
  704. _M_get_Tp_allocator());
  705. }
  706. else
  707. std::_Destroy(__first._M_cur, __last._M_cur,
  708. _M_get_Tp_allocator());
  709. }
  710. template <typename _Tp, typename _Alloc>
  711. void
  712. deque<_Tp, _Alloc>::
  713. _M_new_elements_at_front(size_type __new_elems)
  714. {
  715. if (this->max_size() - this->size() < __new_elems)
  716. __throw_length_error(__N("deque::_M_new_elements_at_front"));
  717. const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
  718. / _S_buffer_size());
  719. _M_reserve_map_at_front(__new_nodes);
  720. size_type __i;
  721. __try
  722. {
  723. for (__i = 1; __i <= __new_nodes; ++__i)
  724. *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
  725. }
  726. __catch(...)
  727. {
  728. for (size_type __j = 1; __j < __i; ++__j)
  729. _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
  730. __throw_exception_again;
  731. }
  732. }
  733. template <typename _Tp, typename _Alloc>
  734. void
  735. deque<_Tp, _Alloc>::
  736. _M_new_elements_at_back(size_type __new_elems)
  737. {
  738. if (this->max_size() - this->size() < __new_elems)
  739. __throw_length_error(__N("deque::_M_new_elements_at_back"));
  740. const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
  741. / _S_buffer_size());
  742. _M_reserve_map_at_back(__new_nodes);
  743. size_type __i;
  744. __try
  745. {
  746. for (__i = 1; __i <= __new_nodes; ++__i)
  747. *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
  748. }
  749. __catch(...)
  750. {
  751. for (size_type __j = 1; __j < __i; ++__j)
  752. _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
  753. __throw_exception_again;
  754. }
  755. }
  756. template <typename _Tp, typename _Alloc>
  757. void
  758. deque<_Tp, _Alloc>::
  759. _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
  760. {
  761. const size_type __old_num_nodes
  762. = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
  763. const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
  764. _Map_pointer __new_nstart;
  765. if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
  766. {
  767. __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
  768. - __new_num_nodes) / 2
  769. + (__add_at_front ? __nodes_to_add : 0);
  770. if (__new_nstart < this->_M_impl._M_start._M_node)
  771. std::copy(this->_M_impl._M_start._M_node,
  772. this->_M_impl._M_finish._M_node + 1,
  773. __new_nstart);
  774. else
  775. std::copy_backward(this->_M_impl._M_start._M_node,
  776. this->_M_impl._M_finish._M_node + 1,
  777. __new_nstart + __old_num_nodes);
  778. }
  779. else
  780. {
  781. size_type __new_map_size = this->_M_impl._M_map_size
  782. + std::max(this->_M_impl._M_map_size,
  783. __nodes_to_add) + 2;
  784. _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
  785. __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
  786. + (__add_at_front ? __nodes_to_add : 0);
  787. std::copy(this->_M_impl._M_start._M_node,
  788. this->_M_impl._M_finish._M_node + 1,
  789. __new_nstart);
  790. _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
  791. this->_M_impl._M_map = __new_map;
  792. this->_M_impl._M_map_size = __new_map_size;
  793. }
  794. this->_M_impl._M_start._M_set_node(__new_nstart);
  795. this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
  796. }
  797. // Overload for deque::iterators, exploiting the "segmented-iterator
  798. // optimization". NB: leave const_iterators alone!
  799. template<typename _Tp>
  800. void
  801. fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
  802. const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
  803. {
  804. typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
  805. for (typename _Self::_Map_pointer __node = __first._M_node + 1;
  806. __node < __last._M_node; ++__node)
  807. std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
  808. if (__first._M_node != __last._M_node)
  809. {
  810. std::fill(__first._M_cur, __first._M_last, __value);
  811. std::fill(__last._M_first, __last._M_cur, __value);
  812. }
  813. else
  814. std::fill(__first._M_cur, __last._M_cur, __value);
  815. }
  816. _GLIBCXX_END_NESTED_NAMESPACE
  817. #endif