list.tcc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. // List implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2001-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /*
  21. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 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. size_type __removed __attribute__((__unused__)) = 0;
  312. iterator __first = begin();
  313. iterator __last = end();
  314. iterator __extra = __last;
  315. while (__first != __last)
  316. {
  317. iterator __next = __first;
  318. ++__next;
  319. if (*__first == __value)
  320. {
  321. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  322. // 526. Is it undefined if a function in the standard changes
  323. // in parameters?
  324. if (std::__addressof(*__first) != std::__addressof(__value))
  325. {
  326. _M_erase(__first);
  327. _GLIBCXX20_ONLY( __removed++ );
  328. }
  329. else
  330. __extra = __first;
  331. }
  332. __first = __next;
  333. }
  334. if (__extra != __last)
  335. {
  336. _M_erase(__extra);
  337. _GLIBCXX20_ONLY( __removed++ );
  338. }
  339. return _GLIBCXX20_ONLY( __removed );
  340. }
  341. template<typename _Tp, typename _Alloc>
  342. typename list<_Tp, _Alloc>::__remove_return_type
  343. list<_Tp, _Alloc>::
  344. unique()
  345. {
  346. iterator __first = begin();
  347. iterator __last = end();
  348. if (__first == __last)
  349. return _GLIBCXX20_ONLY( 0 );
  350. size_type __removed __attribute__((__unused__)) = 0;
  351. iterator __next = __first;
  352. while (++__next != __last)
  353. {
  354. if (*__first == *__next)
  355. {
  356. _M_erase(__next);
  357. _GLIBCXX20_ONLY( __removed++ );
  358. }
  359. else
  360. __first = __next;
  361. __next = __first;
  362. }
  363. return _GLIBCXX20_ONLY( __removed );
  364. }
  365. template<typename _Tp, typename _Alloc>
  366. void
  367. list<_Tp, _Alloc>::
  368. #if __cplusplus >= 201103L
  369. merge(list&& __x)
  370. #else
  371. merge(list& __x)
  372. #endif
  373. {
  374. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  375. // 300. list::merge() specification incomplete
  376. if (this != std::__addressof(__x))
  377. {
  378. _M_check_equal_allocators(__x);
  379. iterator __first1 = begin();
  380. iterator __last1 = end();
  381. iterator __first2 = __x.begin();
  382. iterator __last2 = __x.end();
  383. const size_t __orig_size = __x.size();
  384. __try {
  385. while (__first1 != __last1 && __first2 != __last2)
  386. if (*__first2 < *__first1)
  387. {
  388. iterator __next = __first2;
  389. _M_transfer(__first1, __first2, ++__next);
  390. __first2 = __next;
  391. }
  392. else
  393. ++__first1;
  394. if (__first2 != __last2)
  395. _M_transfer(__last1, __first2, __last2);
  396. this->_M_inc_size(__x._M_get_size());
  397. __x._M_set_size(0);
  398. }
  399. __catch(...)
  400. {
  401. const size_t __dist = std::distance(__first2, __last2);
  402. this->_M_inc_size(__orig_size - __dist);
  403. __x._M_set_size(__dist);
  404. __throw_exception_again;
  405. }
  406. }
  407. }
  408. template<typename _Tp, typename _Alloc>
  409. template <typename _StrictWeakOrdering>
  410. void
  411. list<_Tp, _Alloc>::
  412. #if __cplusplus >= 201103L
  413. merge(list&& __x, _StrictWeakOrdering __comp)
  414. #else
  415. merge(list& __x, _StrictWeakOrdering __comp)
  416. #endif
  417. {
  418. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  419. // 300. list::merge() specification incomplete
  420. if (this != std::__addressof(__x))
  421. {
  422. _M_check_equal_allocators(__x);
  423. iterator __first1 = begin();
  424. iterator __last1 = end();
  425. iterator __first2 = __x.begin();
  426. iterator __last2 = __x.end();
  427. const size_t __orig_size = __x.size();
  428. __try
  429. {
  430. while (__first1 != __last1 && __first2 != __last2)
  431. if (__comp(*__first2, *__first1))
  432. {
  433. iterator __next = __first2;
  434. _M_transfer(__first1, __first2, ++__next);
  435. __first2 = __next;
  436. }
  437. else
  438. ++__first1;
  439. if (__first2 != __last2)
  440. _M_transfer(__last1, __first2, __last2);
  441. this->_M_inc_size(__x._M_get_size());
  442. __x._M_set_size(0);
  443. }
  444. __catch(...)
  445. {
  446. const size_t __dist = std::distance(__first2, __last2);
  447. this->_M_inc_size(__orig_size - __dist);
  448. __x._M_set_size(__dist);
  449. __throw_exception_again;
  450. }
  451. }
  452. }
  453. template<typename _Tp, typename _Alloc>
  454. void
  455. list<_Tp, _Alloc>::
  456. sort()
  457. {
  458. // Do nothing if the list has length 0 or 1.
  459. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  460. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  461. {
  462. list __carry;
  463. list __tmp[64];
  464. list * __fill = __tmp;
  465. list * __counter;
  466. __try
  467. {
  468. do
  469. {
  470. __carry.splice(__carry.begin(), *this, begin());
  471. for(__counter = __tmp;
  472. __counter != __fill && !__counter->empty();
  473. ++__counter)
  474. {
  475. __counter->merge(__carry);
  476. __carry.swap(*__counter);
  477. }
  478. __carry.swap(*__counter);
  479. if (__counter == __fill)
  480. ++__fill;
  481. }
  482. while ( !empty() );
  483. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  484. __counter->merge(*(__counter - 1));
  485. swap( *(__fill - 1) );
  486. }
  487. __catch(...)
  488. {
  489. this->splice(this->end(), __carry);
  490. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  491. this->splice(this->end(), __tmp[__i]);
  492. __throw_exception_again;
  493. }
  494. }
  495. }
  496. template<typename _Tp, typename _Alloc>
  497. template <typename _Predicate>
  498. typename list<_Tp, _Alloc>::__remove_return_type
  499. list<_Tp, _Alloc>::
  500. remove_if(_Predicate __pred)
  501. {
  502. size_type __removed __attribute__((__unused__)) = 0;
  503. iterator __first = begin();
  504. iterator __last = end();
  505. while (__first != __last)
  506. {
  507. iterator __next = __first;
  508. ++__next;
  509. if (__pred(*__first))
  510. {
  511. _M_erase(__first);
  512. _GLIBCXX20_ONLY( __removed++ );
  513. }
  514. __first = __next;
  515. }
  516. return _GLIBCXX20_ONLY( __removed );
  517. }
  518. template<typename _Tp, typename _Alloc>
  519. template <typename _BinaryPredicate>
  520. typename list<_Tp, _Alloc>::__remove_return_type
  521. list<_Tp, _Alloc>::
  522. unique(_BinaryPredicate __binary_pred)
  523. {
  524. iterator __first = begin();
  525. iterator __last = end();
  526. if (__first == __last)
  527. return _GLIBCXX20_ONLY(0);
  528. size_type __removed __attribute__((__unused__)) = 0;
  529. iterator __next = __first;
  530. while (++__next != __last)
  531. {
  532. if (__binary_pred(*__first, *__next))
  533. {
  534. _M_erase(__next);
  535. _GLIBCXX20_ONLY( __removed++ );
  536. }
  537. else
  538. __first = __next;
  539. __next = __first;
  540. }
  541. return _GLIBCXX20_ONLY( __removed );
  542. }
  543. #undef _GLIBCXX20_ONLY
  544. template<typename _Tp, typename _Alloc>
  545. template <typename _StrictWeakOrdering>
  546. void
  547. list<_Tp, _Alloc>::
  548. sort(_StrictWeakOrdering __comp)
  549. {
  550. // Do nothing if the list has length 0 or 1.
  551. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  552. && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  553. {
  554. list __carry;
  555. list __tmp[64];
  556. list * __fill = __tmp;
  557. list * __counter;
  558. __try
  559. {
  560. do
  561. {
  562. __carry.splice(__carry.begin(), *this, begin());
  563. for(__counter = __tmp;
  564. __counter != __fill && !__counter->empty();
  565. ++__counter)
  566. {
  567. __counter->merge(__carry, __comp);
  568. __carry.swap(*__counter);
  569. }
  570. __carry.swap(*__counter);
  571. if (__counter == __fill)
  572. ++__fill;
  573. }
  574. while ( !empty() );
  575. for (__counter = __tmp + 1; __counter != __fill; ++__counter)
  576. __counter->merge(*(__counter - 1), __comp);
  577. swap(*(__fill - 1));
  578. }
  579. __catch(...)
  580. {
  581. this->splice(this->end(), __carry);
  582. for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
  583. this->splice(this->end(), __tmp[__i]);
  584. __throw_exception_again;
  585. }
  586. }
  587. }
  588. _GLIBCXX_END_NAMESPACE_CONTAINER
  589. _GLIBCXX_END_NAMESPACE_VERSION
  590. } // namespace std
  591. #endif /* _LIST_TCC */