list.tcc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // List implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2001-2018 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) 1996,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/list.tcc
  46. * This is an internal header file, included by other library headers.
  47. * Do not attempt to use it directly. @headername{list}
  48. */
  49. #ifndef _LIST_TCC
  50. #define _LIST_TCC 1
  51. namespace std _GLIBCXX_VISIBILITY(default)
  52. {
  53. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  54. _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  55. template<typename _Tp, typename _Alloc>
  56. void
  57. _List_base<_Tp, _Alloc>::
  58. _M_clear() _GLIBCXX_NOEXCEPT
  59. {
  60. typedef _List_node<_Tp> _Node;
  61. __detail::_List_node_base* __cur = _M_impl._M_node._M_next;
  62. while (__cur != &_M_impl._M_node)
  63. {
  64. _Node* __tmp = static_cast<_Node*>(__cur);
  65. __cur = __tmp->_M_next;
  66. _Tp* __val = __tmp->_M_valptr();
  67. #if __cplusplus >= 201103L
  68. _Node_alloc_traits::destroy(_M_get_Node_allocator(), __val);
  69. #else
  70. _Tp_alloc_type(_M_get_Node_allocator()).destroy(__val);
  71. #endif
  72. _M_put_node(__tmp);
  73. }
  74. }
  75. #if __cplusplus >= 201103L
  76. template<typename _Tp, typename _Alloc>
  77. template<typename... _Args>
  78. typename list<_Tp, _Alloc>::iterator
  79. list<_Tp, _Alloc>::
  80. emplace(const_iterator __position, _Args&&... __args)
  81. {
  82. _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
  83. __tmp->_M_hook(__position._M_const_cast()._M_node);
  84. this->_M_inc_size(1);
  85. return iterator(__tmp);
  86. }
  87. #endif
  88. template<typename _Tp, typename _Alloc>
  89. typename list<_Tp, _Alloc>::iterator
  90. list<_Tp, _Alloc>::
  91. #if __cplusplus >= 201103L
  92. insert(const_iterator __position, const value_type& __x)
  93. #else
  94. insert(iterator __position, const value_type& __x)
  95. #endif
  96. {
  97. _Node* __tmp = _M_create_node(__x);
  98. __tmp->_M_hook(__position._M_const_cast()._M_node);
  99. this->_M_inc_size(1);
  100. return iterator(__tmp);
  101. }
  102. #if __cplusplus >= 201103L
  103. template<typename _Tp, typename _Alloc>
  104. typename list<_Tp, _Alloc>::iterator
  105. list<_Tp, _Alloc>::
  106. insert(const_iterator __position, size_type __n, const value_type& __x)
  107. {
  108. if (__n)
  109. {
  110. list __tmp(__n, __x, get_allocator());
  111. iterator __it = __tmp.begin();
  112. splice(__position, __tmp);
  113. return __it;
  114. }
  115. return __position._M_const_cast();
  116. }
  117. template<typename _Tp, typename _Alloc>
  118. template<typename _InputIterator, typename>
  119. typename list<_Tp, _Alloc>::iterator
  120. list<_Tp, _Alloc>::
  121. insert(const_iterator __position, _InputIterator __first,
  122. _InputIterator __last)
  123. {
  124. list __tmp(__first, __last, get_allocator());
  125. if (!__tmp.empty())
  126. {
  127. iterator __it = __tmp.begin();
  128. splice(__position, __tmp);
  129. return __it;
  130. }
  131. return __position._M_const_cast();
  132. }
  133. #endif
  134. template<typename _Tp, typename _Alloc>
  135. typename list<_Tp, _Alloc>::iterator
  136. list<_Tp, _Alloc>::
  137. #if __cplusplus >= 201103L
  138. erase(const_iterator __position) noexcept
  139. #else
  140. erase(iterator __position)
  141. #endif
  142. {
  143. iterator __ret = iterator(__position._M_node->_M_next);
  144. _M_erase(__position._M_const_cast());
  145. return __ret;
  146. }
  147. // Return a const_iterator indicating the position to start inserting or
  148. // erasing elements (depending whether the list is growing or shrinking),
  149. // and set __new_size to the number of new elements that must be appended.
  150. // Equivalent to the following, but performed optimally:
  151. // if (__new_size < size()) {
  152. // __new_size = 0;
  153. // return std::next(begin(), __new_size);
  154. // } else {
  155. // __newsize -= size();
  156. // return end();
  157. // }
  158. template<typename _Tp, typename _Alloc>
  159. typename list<_Tp, _Alloc>::const_iterator
  160. list<_Tp, _Alloc>::
  161. _M_resize_pos(size_type& __new_size) const
  162. {
  163. const_iterator __i;
  164. #if _GLIBCXX_USE_CXX11_ABI
  165. const size_type __len = size();
  166. if (__new_size < __len)
  167. {
  168. if (__new_size <= __len / 2)
  169. {
  170. __i = begin();
  171. std::advance(__i, __new_size);
  172. }
  173. else
  174. {
  175. __i = end();
  176. ptrdiff_t __num_erase = __len - __new_size;
  177. std::advance(__i, -__num_erase);
  178. }
  179. __new_size = 0;
  180. return __i;
  181. }
  182. else
  183. __i = end();
  184. #else
  185. size_type __len = 0;
  186. for (__i = begin(); __i != end() && __len < __new_size; ++__i, ++__len)
  187. ;
  188. #endif
  189. __new_size -= __len;
  190. return __i;
  191. }
  192. #if __cplusplus >= 201103L
  193. template<typename _Tp, typename _Alloc>
  194. void
  195. list<_Tp, _Alloc>::
  196. _M_default_append(size_type __n)
  197. {
  198. size_type __i = 0;
  199. __try
  200. {
  201. for (; __i < __n; ++__i)
  202. emplace_back();
  203. }
  204. __catch(...)
  205. {
  206. for (; __i; --__i)
  207. pop_back();
  208. __throw_exception_again;
  209. }
  210. }
  211. template<typename _Tp, typename _Alloc>
  212. void
  213. list<_Tp, _Alloc>::
  214. resize(size_type __new_size)
  215. {
  216. const_iterator __i = _M_resize_pos(__new_size);
  217. if (__new_size)
  218. _M_default_append(__new_size);
  219. else
  220. erase(__i, end());
  221. }
  222. template<typename _Tp, typename _Alloc>
  223. void
  224. list<_Tp, _Alloc>::
  225. resize(size_type __new_size, const value_type& __x)
  226. {
  227. const_iterator __i = _M_resize_pos(__new_size);
  228. if (__new_size)
  229. insert(end(), __new_size, __x);
  230. else
  231. erase(__i, end());
  232. }
  233. #else
  234. template<typename _Tp, typename _Alloc>
  235. void
  236. list<_Tp, _Alloc>::
  237. resize(size_type __new_size, value_type __x)
  238. {
  239. const_iterator __i = _M_resize_pos(__new_size);
  240. if (__new_size)
  241. insert(end(), __new_size, __x);
  242. else
  243. erase(__i._M_const_cast(), end());
  244. }
  245. #endif
  246. template<typename _Tp, typename _Alloc>
  247. list<_Tp, _Alloc>&
  248. list<_Tp, _Alloc>::
  249. operator=(const list& __x)
  250. {
  251. if (this != std::__addressof(__x))
  252. {
  253. #if __cplusplus >= 201103L
  254. if (_Node_alloc_traits::_S_propagate_on_copy_assign())
  255. {
  256. auto& __this_alloc = this->_M_get_Node_allocator();
  257. auto& __that_alloc = __x._M_get_Node_allocator();
  258. if (!_Node_alloc_traits::_S_always_equal()
  259. && __this_alloc != __that_alloc)
  260. {
  261. // replacement allocator cannot free existing storage
  262. clear();
  263. }
  264. std::__alloc_on_copy(__this_alloc, __that_alloc);
  265. }
  266. #endif
  267. _M_assign_dispatch(__x.begin(), __x.end(), __false_type());
  268. }
  269. return *this;
  270. }
  271. template<typename _Tp, typename _Alloc>
  272. void
  273. list<_Tp, _Alloc>::
  274. _M_fill_assign(size_type __n, const value_type& __val)
  275. {
  276. iterator __i = begin();
  277. for (; __i != end() && __n > 0; ++__i, --__n)
  278. *__i = __val;
  279. if (__n > 0)
  280. insert(end(), __n, __val);
  281. else
  282. erase(__i, end());
  283. }
  284. template<typename _Tp, typename _Alloc>
  285. template <typename _InputIterator>
  286. void
  287. list<_Tp, _Alloc>::
  288. _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
  289. __false_type)
  290. {
  291. iterator __first1 = begin();
  292. iterator __last1 = end();
  293. for (; __first1 != __last1 && __first2 != __last2;
  294. ++__first1, ++__first2)
  295. *__first1 = *__first2;
  296. if (__first2 == __last2)
  297. erase(__first1, __last1);
  298. else
  299. insert(__last1, __first2, __last2);
  300. }
  301. template<typename _Tp, typename _Alloc>
  302. void
  303. list<_Tp, _Alloc>::
  304. remove(const value_type& __value)
  305. {
  306. iterator __first = begin();
  307. iterator __last = end();
  308. iterator __extra = __last;
  309. while (__first != __last)
  310. {
  311. iterator __next = __first;
  312. ++__next;
  313. if (*__first == __value)
  314. {
  315. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  316. // 526. Is it undefined if a function in the standard changes
  317. // in parameters?
  318. if (std::__addressof(*__first) != std::__addressof(__value))
  319. _M_erase(__first);
  320. else
  321. __extra = __first;
  322. }
  323. __first = __next;
  324. }
  325. if (__extra != __last)
  326. _M_erase(__extra);
  327. }
  328. template<typename _Tp, typename _Alloc>
  329. void
  330. list<_Tp, _Alloc>::
  331. unique()
  332. {
  333. iterator __first = begin();
  334. iterator __last = end();
  335. if (__first == __last)
  336. return;
  337. iterator __next = __first;
  338. while (++__next != __last)
  339. {
  340. if (*__first == *__next)
  341. _M_erase(__next);
  342. else
  343. __first = __next;
  344. __next = __first;
  345. }
  346. }
  347. template<typename _Tp, typename _Alloc>
  348. void
  349. list<_Tp, _Alloc>::
  350. #if __cplusplus >= 201103L
  351. merge(list&& __x)
  352. #else
  353. merge(list& __x)
  354. #endif
  355. {
  356. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  357. // 300. list::merge() specification incomplete
  358. if (this != std::__addressof(__x))
  359. {
  360. _M_check_equal_allocators(__x);
  361. iterator __first1 = begin();
  362. iterator __last1 = end();
  363. iterator __first2 = __x.begin();
  364. iterator __last2 = __x.end();
  365. const size_t __orig_size = __x.size();
  366. __try {
  367. while (__first1 != __last1 && __first2 != __last2)
  368. if (*__first2 < *__first1)
  369. {
  370. iterator __next = __first2;
  371. _M_transfer(__first1, __first2, ++__next);
  372. __first2 = __next;
  373. }
  374. else
  375. ++__first1;
  376. if (__first2 != __last2)
  377. _M_transfer(__last1, __first2, __last2);
  378. this->_M_inc_size(__x._M_get_size());
  379. __x._M_set_size(0);
  380. }
  381. __catch(...)
  382. {
  383. const size_t __dist = std::distance(__first2, __last2);
  384. this->_M_inc_size(__orig_size - __dist);
  385. __x._M_set_size(__dist);
  386. __throw_exception_again;
  387. }
  388. }
  389. }
  390. template<typename _Tp, typename _Alloc>
  391. template <typename _StrictWeakOrdering>
  392. void
  393. list<_Tp, _Alloc>::
  394. #if __cplusplus >= 201103L
  395. merge(list&& __x, _StrictWeakOrdering __comp)
  396. #else
  397. merge(list& __x, _StrictWeakOrdering __comp)
  398. #endif
  399. {
  400. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  401. // 300. list::merge() specification incomplete
  402. if (this != std::__addressof(__x))
  403. {
  404. _M_check_equal_allocators(__x);
  405. iterator __first1 = begin();
  406. iterator __last1 = end();
  407. iterator __first2 = __x.begin();
  408. iterator __last2 = __x.end();
  409. const size_t __orig_size = __x.size();
  410. __try
  411. {
  412. while (__first1 != __last1 && __first2 != __last2)
  413. if (__comp(*__first2, *__first1))
  414. {
  415. iterator __next = __first2;
  416. _M_transfer(__first1, __first2, ++__next);
  417. __first2 = __next;
  418. }
  419. else
  420. ++__first1;
  421. if (__first2 != __last2)
  422. _M_transfer(__last1, __first2, __last2);
  423. this->_M_inc_size(__x._M_get_size());
  424. __x._M_set_size(0);
  425. }
  426. __catch(...)
  427. {
  428. const size_t __dist = std::distance(__first2, __last2);
  429. this->_M_inc_size(__orig_size - __dist);
  430. __x._M_set_size(__dist);
  431. __throw_exception_again;
  432. }
  433. }
  434. }
  435. template<typename _Tp, typename _Alloc>
  436. void
  437. list<_Tp, _Alloc>::
  438. sort()
  439. {
  440. // Do nothing if the list has length 0 or 1.
  441. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  442. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  443. {
  444. list __carry;
  445. list __tmp[64];
  446. list * __fill = __tmp;
  447. list * __counter;
  448. __try
  449. {
  450. do
  451. {
  452. __carry.splice(__carry.begin(), *this, begin());
  453. for(__counter = __tmp;
  454. __counter != __fill && !__counter->empty();
  455. ++__counter)
  456. {
  457. __counter->merge(__carry);
  458. __carry.swap(*__counter);
  459. }
  460. __carry.swap(*__counter);
  461. if (__counter == __fill)
  462. ++__fill;
  463. }
  464. while ( !empty() );
  465. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  466. __counter->merge(*(__counter - 1));
  467. swap( *(__fill - 1) );
  468. }
  469. __catch(...)
  470. {
  471. this->splice(this->end(), __carry);
  472. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  473. this->splice(this->end(), __tmp[__i]);
  474. __throw_exception_again;
  475. }
  476. }
  477. }
  478. template<typename _Tp, typename _Alloc>
  479. template <typename _Predicate>
  480. void
  481. list<_Tp, _Alloc>::
  482. remove_if(_Predicate __pred)
  483. {
  484. iterator __first = begin();
  485. iterator __last = end();
  486. while (__first != __last)
  487. {
  488. iterator __next = __first;
  489. ++__next;
  490. if (__pred(*__first))
  491. _M_erase(__first);
  492. __first = __next;
  493. }
  494. }
  495. template<typename _Tp, typename _Alloc>
  496. template <typename _BinaryPredicate>
  497. void
  498. list<_Tp, _Alloc>::
  499. unique(_BinaryPredicate __binary_pred)
  500. {
  501. iterator __first = begin();
  502. iterator __last = end();
  503. if (__first == __last)
  504. return;
  505. iterator __next = __first;
  506. while (++__next != __last)
  507. {
  508. if (__binary_pred(*__first, *__next))
  509. _M_erase(__next);
  510. else
  511. __first = __next;
  512. __next = __first;
  513. }
  514. }
  515. template<typename _Tp, typename _Alloc>
  516. template <typename _StrictWeakOrdering>
  517. void
  518. list<_Tp, _Alloc>::
  519. sort(_StrictWeakOrdering __comp)
  520. {
  521. // Do nothing if the list has length 0 or 1.
  522. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  523. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  524. {
  525. list __carry;
  526. list __tmp[64];
  527. list * __fill = __tmp;
  528. list * __counter;
  529. __try
  530. {
  531. do
  532. {
  533. __carry.splice(__carry.begin(), *this, begin());
  534. for(__counter = __tmp;
  535. __counter != __fill && !__counter->empty();
  536. ++__counter)
  537. {
  538. __counter->merge(__carry, __comp);
  539. __carry.swap(*__counter);
  540. }
  541. __carry.swap(*__counter);
  542. if (__counter == __fill)
  543. ++__fill;
  544. }
  545. while ( !empty() );
  546. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  547. __counter->merge(*(__counter - 1), __comp);
  548. swap(*(__fill - 1));
  549. }
  550. __catch(...)
  551. {
  552. this->splice(this->end(), __carry);
  553. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  554. this->splice(this->end(), __tmp[__i]);
  555. __throw_exception_again;
  556. }
  557. }
  558. }
  559. _GLIBCXX_END_NAMESPACE_CONTAINER
  560. _GLIBCXX_END_NAMESPACE_VERSION
  561. } // namespace std
  562. #endif /* _LIST_TCC */