list.tcc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. // List implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2001-2021 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, (void)++__first2)
  295. *__first1 = *__first2;
  296. if (__first2 == __last2)
  297. erase(__first1, __last1);
  298. else
  299. insert(__last1, __first2, __last2);
  300. }
  301. #if __cplusplus > 201703L
  302. # define _GLIBCXX20_ONLY(__expr) __expr
  303. #else
  304. # define _GLIBCXX20_ONLY(__expr)
  305. #endif
  306. template<typename _Tp, typename _Alloc>
  307. typename list<_Tp, _Alloc>::__remove_return_type
  308. list<_Tp, _Alloc>::
  309. remove(const value_type& __value)
  310. {
  311. #if !_GLIBCXX_USE_CXX11_ABI
  312. size_type __removed __attribute__((__unused__)) = 0;
  313. #endif
  314. list __to_destroy(get_allocator());
  315. iterator __first = begin();
  316. iterator __last = end();
  317. while (__first != __last)
  318. {
  319. iterator __next = __first;
  320. ++__next;
  321. if (*__first == __value)
  322. {
  323. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  324. // 526. Is it undefined if a function in the standard changes
  325. // in parameters?
  326. __to_destroy.splice(__to_destroy.begin(), *this, __first);
  327. #if !_GLIBCXX_USE_CXX11_ABI
  328. _GLIBCXX20_ONLY( __removed++ );
  329. #endif
  330. }
  331. __first = __next;
  332. }
  333. #if !_GLIBCXX_USE_CXX11_ABI
  334. return _GLIBCXX20_ONLY( __removed );
  335. #else
  336. return _GLIBCXX20_ONLY( __to_destroy.size() );
  337. #endif
  338. }
  339. template<typename _Tp, typename _Alloc>
  340. typename list<_Tp, _Alloc>::__remove_return_type
  341. list<_Tp, _Alloc>::
  342. unique()
  343. {
  344. iterator __first = begin();
  345. iterator __last = end();
  346. if (__first == __last)
  347. return _GLIBCXX20_ONLY( 0 );
  348. #if !_GLIBCXX_USE_CXX11_ABI
  349. size_type __removed __attribute__((__unused__)) = 0;
  350. #endif
  351. list __to_destroy(get_allocator());
  352. iterator __next = __first;
  353. while (++__next != __last)
  354. {
  355. if (*__first == *__next)
  356. {
  357. __to_destroy.splice(__to_destroy.begin(), *this, __next);
  358. #if !_GLIBCXX_USE_CXX11_ABI
  359. _GLIBCXX20_ONLY( __removed++ );
  360. #endif
  361. }
  362. else
  363. __first = __next;
  364. __next = __first;
  365. }
  366. #if !_GLIBCXX_USE_CXX11_ABI
  367. return _GLIBCXX20_ONLY( __removed );
  368. #else
  369. return _GLIBCXX20_ONLY( __to_destroy.size() );
  370. #endif
  371. }
  372. template<typename _Tp, typename _Alloc>
  373. void
  374. list<_Tp, _Alloc>::
  375. #if __cplusplus >= 201103L
  376. merge(list&& __x)
  377. #else
  378. merge(list& __x)
  379. #endif
  380. {
  381. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  382. // 300. list::merge() specification incomplete
  383. if (this != std::__addressof(__x))
  384. {
  385. _M_check_equal_allocators(__x);
  386. iterator __first1 = begin();
  387. iterator __last1 = end();
  388. iterator __first2 = __x.begin();
  389. iterator __last2 = __x.end();
  390. const size_t __orig_size = __x.size();
  391. __try {
  392. while (__first1 != __last1 && __first2 != __last2)
  393. if (*__first2 < *__first1)
  394. {
  395. iterator __next = __first2;
  396. _M_transfer(__first1, __first2, ++__next);
  397. __first2 = __next;
  398. }
  399. else
  400. ++__first1;
  401. if (__first2 != __last2)
  402. _M_transfer(__last1, __first2, __last2);
  403. this->_M_inc_size(__x._M_get_size());
  404. __x._M_set_size(0);
  405. }
  406. __catch(...)
  407. {
  408. const size_t __dist = std::distance(__first2, __last2);
  409. this->_M_inc_size(__orig_size - __dist);
  410. __x._M_set_size(__dist);
  411. __throw_exception_again;
  412. }
  413. }
  414. }
  415. template<typename _Tp, typename _Alloc>
  416. template <typename _StrictWeakOrdering>
  417. void
  418. list<_Tp, _Alloc>::
  419. #if __cplusplus >= 201103L
  420. merge(list&& __x, _StrictWeakOrdering __comp)
  421. #else
  422. merge(list& __x, _StrictWeakOrdering __comp)
  423. #endif
  424. {
  425. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  426. // 300. list::merge() specification incomplete
  427. if (this != std::__addressof(__x))
  428. {
  429. _M_check_equal_allocators(__x);
  430. iterator __first1 = begin();
  431. iterator __last1 = end();
  432. iterator __first2 = __x.begin();
  433. iterator __last2 = __x.end();
  434. const size_t __orig_size = __x.size();
  435. __try
  436. {
  437. while (__first1 != __last1 && __first2 != __last2)
  438. if (__comp(*__first2, *__first1))
  439. {
  440. iterator __next = __first2;
  441. _M_transfer(__first1, __first2, ++__next);
  442. __first2 = __next;
  443. }
  444. else
  445. ++__first1;
  446. if (__first2 != __last2)
  447. _M_transfer(__last1, __first2, __last2);
  448. this->_M_inc_size(__x._M_get_size());
  449. __x._M_set_size(0);
  450. }
  451. __catch(...)
  452. {
  453. const size_t __dist = std::distance(__first2, __last2);
  454. this->_M_inc_size(__orig_size - __dist);
  455. __x._M_set_size(__dist);
  456. __throw_exception_again;
  457. }
  458. }
  459. }
  460. template<typename _Tp, typename _Alloc>
  461. void
  462. list<_Tp, _Alloc>::
  463. sort()
  464. {
  465. // Do nothing if the list has length 0 or 1.
  466. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  467. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  468. {
  469. list __carry;
  470. list __tmp[64];
  471. list * __fill = __tmp;
  472. list * __counter;
  473. __try
  474. {
  475. do
  476. {
  477. __carry.splice(__carry.begin(), *this, begin());
  478. for(__counter = __tmp;
  479. __counter != __fill && !__counter->empty();
  480. ++__counter)
  481. {
  482. __counter->merge(__carry);
  483. __carry.swap(*__counter);
  484. }
  485. __carry.swap(*__counter);
  486. if (__counter == __fill)
  487. ++__fill;
  488. }
  489. while ( !empty() );
  490. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  491. __counter->merge(*(__counter - 1));
  492. swap( *(__fill - 1) );
  493. }
  494. __catch(...)
  495. {
  496. this->splice(this->end(), __carry);
  497. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  498. this->splice(this->end(), __tmp[__i]);
  499. __throw_exception_again;
  500. }
  501. }
  502. }
  503. template<typename _Tp, typename _Alloc>
  504. template <typename _Predicate>
  505. typename list<_Tp, _Alloc>::__remove_return_type
  506. list<_Tp, _Alloc>::
  507. remove_if(_Predicate __pred)
  508. {
  509. #if !_GLIBCXX_USE_CXX11_ABI
  510. size_type __removed __attribute__((__unused__)) = 0;
  511. #endif
  512. list __to_destroy(get_allocator());
  513. iterator __first = begin();
  514. iterator __last = end();
  515. while (__first != __last)
  516. {
  517. iterator __next = __first;
  518. ++__next;
  519. if (__pred(*__first))
  520. {
  521. __to_destroy.splice(__to_destroy.begin(), *this, __first);
  522. #if !_GLIBCXX_USE_CXX11_ABI
  523. _GLIBCXX20_ONLY( __removed++ );
  524. #endif
  525. }
  526. __first = __next;
  527. }
  528. #if !_GLIBCXX_USE_CXX11_ABI
  529. return _GLIBCXX20_ONLY( __removed );
  530. #else
  531. return _GLIBCXX20_ONLY( __to_destroy.size() );
  532. #endif
  533. }
  534. template<typename _Tp, typename _Alloc>
  535. template <typename _BinaryPredicate>
  536. typename list<_Tp, _Alloc>::__remove_return_type
  537. list<_Tp, _Alloc>::
  538. unique(_BinaryPredicate __binary_pred)
  539. {
  540. iterator __first = begin();
  541. iterator __last = end();
  542. if (__first == __last)
  543. return _GLIBCXX20_ONLY(0);
  544. #if !_GLIBCXX_USE_CXX11_ABI
  545. size_type __removed __attribute__((__unused__)) = 0;
  546. #endif
  547. list __to_destroy(get_allocator());
  548. iterator __next = __first;
  549. while (++__next != __last)
  550. {
  551. if (__binary_pred(*__first, *__next))
  552. {
  553. __to_destroy.splice(__to_destroy.begin(), *this, __next);
  554. #if !_GLIBCXX_USE_CXX11_ABI
  555. _GLIBCXX20_ONLY( __removed++ );
  556. #endif
  557. }
  558. else
  559. __first = __next;
  560. __next = __first;
  561. }
  562. #if !_GLIBCXX_USE_CXX11_ABI
  563. return _GLIBCXX20_ONLY( __removed );
  564. #else
  565. return _GLIBCXX20_ONLY( __to_destroy.size() );
  566. #endif
  567. }
  568. #undef _GLIBCXX20_ONLY
  569. template<typename _Tp, typename _Alloc>
  570. template <typename _StrictWeakOrdering>
  571. void
  572. list<_Tp, _Alloc>::
  573. sort(_StrictWeakOrdering __comp)
  574. {
  575. // Do nothing if the list has length 0 or 1.
  576. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  577. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  578. {
  579. list __carry;
  580. list __tmp[64];
  581. list * __fill = __tmp;
  582. list * __counter;
  583. __try
  584. {
  585. do
  586. {
  587. __carry.splice(__carry.begin(), *this, begin());
  588. for(__counter = __tmp;
  589. __counter != __fill && !__counter->empty();
  590. ++__counter)
  591. {
  592. __counter->merge(__carry, __comp);
  593. __carry.swap(*__counter);
  594. }
  595. __carry.swap(*__counter);
  596. if (__counter == __fill)
  597. ++__fill;
  598. }
  599. while ( !empty() );
  600. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  601. __counter->merge(*(__counter - 1), __comp);
  602. swap(*(__fill - 1));
  603. }
  604. __catch(...)
  605. {
  606. this->splice(this->end(), __carry);
  607. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  608. this->splice(this->end(), __tmp[__i]);
  609. __throw_exception_again;
  610. }
  611. }
  612. }
  613. _GLIBCXX_END_NAMESPACE_CONTAINER
  614. _GLIBCXX_END_NAMESPACE_VERSION
  615. } // namespace std
  616. #endif /* _LIST_TCC */