list 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. // Profiling list implementation -*- C++ -*-
  2. // Copyright (C) 2009-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. /** @file profile/list
  21. * This file is a GNU profile extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_PROFILE_LIST
  24. #define _GLIBCXX_PROFILE_LIST 1
  25. #include <list>
  26. #include <profile/base.h>
  27. #include <profile/iterator_tracker.h>
  28. namespace std _GLIBCXX_VISIBILITY(default)
  29. {
  30. namespace __profile
  31. {
  32. template<typename _List>
  33. class _List_profile
  34. {
  35. _List&
  36. _M_conjure()
  37. { return *static_cast<_List*>(this); }
  38. public:
  39. __gnu_profile::__list2slist_info* _M_list2slist_info;
  40. __gnu_profile::__list2vector_info* _M_list2vector_info;
  41. _List_profile() _GLIBCXX_NOEXCEPT
  42. { _M_profile_construct(); }
  43. void
  44. _M_profile_construct() _GLIBCXX_NOEXCEPT
  45. {
  46. _M_list2slist_info = __profcxx_list2slist_construct();
  47. _M_list2vector_info = __profcxx_list2vector_construct();
  48. }
  49. void
  50. _M_profile_destruct() _GLIBCXX_NOEXCEPT
  51. {
  52. __profcxx_list2vector_destruct(_M_list2vector_info);
  53. _M_list2vector_info = 0;
  54. __profcxx_list2slist_destruct(_M_list2slist_info);
  55. _M_list2slist_info = 0;
  56. }
  57. void
  58. _M_swap(_List_profile& __other)
  59. {
  60. std::swap(_M_list2slist_info, __other._M_list2slist_info);
  61. std::swap(_M_list2vector_info, __other._M_list2vector_info);
  62. }
  63. #if __cplusplus >= 201103L
  64. _List_profile(const _List_profile&) noexcept
  65. : _List_profile() { }
  66. _List_profile(_List_profile&& __other) noexcept
  67. : _List_profile()
  68. { _M_swap(__other); }
  69. _List_profile&
  70. operator=(const _List_profile&) noexcept
  71. {
  72. _M_profile_destruct();
  73. _M_profile_construct();
  74. }
  75. _List_profile&
  76. operator=(_List_profile&& __other) noexcept
  77. {
  78. _M_swap(__other);
  79. __other._M_profile_destruct();
  80. __other._M_profile_construct();
  81. }
  82. #endif
  83. ~_List_profile()
  84. { _M_profile_destruct(); }
  85. };
  86. /** @brief List wrapper with performance instrumentation. */
  87. template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
  88. class list
  89. : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
  90. public _List_profile<list<_Tp, _Allocator> >
  91. {
  92. typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
  93. public:
  94. typedef typename _Base::reference reference;
  95. typedef typename _Base::const_reference const_reference;
  96. typedef __iterator_tracker<typename _Base::iterator, list>
  97. iterator;
  98. typedef __iterator_tracker<typename _Base::const_iterator, list>
  99. const_iterator;
  100. typedef typename _Base::size_type size_type;
  101. typedef typename _Base::difference_type difference_type;
  102. typedef _Tp value_type;
  103. typedef _Allocator allocator_type;
  104. typedef typename _Base::pointer pointer;
  105. typedef typename _Base::const_pointer const_pointer;
  106. typedef std::reverse_iterator<iterator> reverse_iterator;
  107. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  108. // 23.2.2.1 construct/copy/destroy:
  109. #if __cplusplus < 201103L
  110. list() { }
  111. list(const list& __x)
  112. : _Base(__x) { }
  113. ~list() { }
  114. #else
  115. list() = default;
  116. list(const list&) = default;
  117. list(list&&) = default;
  118. ~list() = default;
  119. list(initializer_list<value_type> __l,
  120. const allocator_type& __a = allocator_type())
  121. : _Base(__l, __a) { }
  122. list(const list& __x, const allocator_type& __a)
  123. : _Base(__x, __a) { }
  124. list(list&& __x, const allocator_type& __a)
  125. : _Base(std::move(__x), __a) { }
  126. #endif
  127. explicit
  128. list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
  129. : _Base(__a) { }
  130. #if __cplusplus >= 201103L
  131. explicit
  132. list(size_type __n, const allocator_type& __a = allocator_type())
  133. : _Base(__n, __a) { }
  134. list(size_type __n, const _Tp& __value,
  135. const _Allocator& __a = _Allocator())
  136. : _Base(__n, __value, __a) { }
  137. #else
  138. explicit
  139. list(size_type __n, const _Tp& __value = _Tp(),
  140. const _Allocator& __a = _Allocator())
  141. : _Base(__n, __value, __a) { }
  142. #endif
  143. #if __cplusplus >= 201103L
  144. template<typename _InputIterator,
  145. typename = std::_RequireInputIter<_InputIterator>>
  146. #else
  147. template<class _InputIterator>
  148. #endif
  149. list(_InputIterator __first, _InputIterator __last,
  150. const _Allocator& __a = _Allocator())
  151. : _Base(__first, __last, __a) { }
  152. list(const _Base& __x)
  153. : _Base(__x) { }
  154. #if __cplusplus < 201103L
  155. list&
  156. operator=(const list& __x)
  157. {
  158. this->_M_profile_destruct();
  159. _M_base() = __x;
  160. this->_M_profile_construct();
  161. return *this;
  162. }
  163. #else
  164. list&
  165. operator=(const list&) = default;
  166. list&
  167. operator=(list&&) = default;
  168. list&
  169. operator=(initializer_list<value_type> __l)
  170. {
  171. this->_M_profile_destruct();
  172. _M_base() = __l;
  173. this->_M_profile_construct();
  174. return *this;
  175. }
  176. #endif
  177. // iterators:
  178. iterator
  179. begin() _GLIBCXX_NOEXCEPT
  180. { return iterator(_Base::begin(), this); }
  181. const_iterator
  182. begin() const _GLIBCXX_NOEXCEPT
  183. { return const_iterator(_Base::begin(), this); }
  184. iterator
  185. end() _GLIBCXX_NOEXCEPT
  186. {
  187. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  188. return iterator(_Base::end(), this);
  189. }
  190. const_iterator
  191. end() const _GLIBCXX_NOEXCEPT
  192. {
  193. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  194. return const_iterator(_Base::end(), this);
  195. }
  196. reverse_iterator
  197. rbegin() _GLIBCXX_NOEXCEPT
  198. {
  199. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  200. return reverse_iterator(end());
  201. }
  202. const_reverse_iterator
  203. rbegin() const _GLIBCXX_NOEXCEPT
  204. {
  205. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  206. return const_reverse_iterator(end());
  207. }
  208. reverse_iterator
  209. rend() _GLIBCXX_NOEXCEPT
  210. { return reverse_iterator(begin()); }
  211. const_reverse_iterator
  212. rend() const _GLIBCXX_NOEXCEPT
  213. { return const_reverse_iterator(begin()); }
  214. #if __cplusplus >= 201103L
  215. const_iterator
  216. cbegin() const noexcept
  217. { return const_iterator(_Base::cbegin(), this); }
  218. const_iterator
  219. cend() const noexcept
  220. { return const_iterator(_Base::cend(), this); }
  221. const_reverse_iterator
  222. crbegin() const noexcept
  223. { return const_reverse_iterator(end()); }
  224. const_reverse_iterator
  225. crend() const noexcept
  226. { return const_reverse_iterator(begin()); }
  227. #endif
  228. // 23.2.2.2 capacity:
  229. reference
  230. back() _GLIBCXX_NOEXCEPT
  231. {
  232. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  233. return _Base::back();
  234. }
  235. const_reference
  236. back() const _GLIBCXX_NOEXCEPT
  237. {
  238. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  239. return _Base::back();
  240. }
  241. // 23.2.2.3 modifiers:
  242. void
  243. push_front(const value_type& __x)
  244. {
  245. __profcxx_list2vector_invalid_operator(this->_M_list2vector_info);
  246. __profcxx_list2slist_operation(this->_M_list2slist_info);
  247. _Base::push_front(__x);
  248. }
  249. void
  250. pop_front() _GLIBCXX_NOEXCEPT
  251. {
  252. __profcxx_list2slist_operation(this->_M_list2slist_info);
  253. _Base::pop_front();
  254. }
  255. void
  256. pop_back() _GLIBCXX_NOEXCEPT
  257. {
  258. _Base::pop_back();
  259. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  260. }
  261. #if __cplusplus >= 201103L
  262. template<typename... _Args>
  263. iterator
  264. emplace(const_iterator __position, _Args&&... __args)
  265. {
  266. return iterator(_Base::emplace(__position.base(),
  267. std::forward<_Args>(__args)...),
  268. this);
  269. }
  270. #endif
  271. iterator
  272. #if __cplusplus >= 201103L
  273. insert(const_iterator __pos, const _Tp& __x)
  274. #else
  275. insert(iterator __pos, const _Tp& __x)
  276. #endif
  277. {
  278. _M_profile_insert(__pos, this->size());
  279. return iterator(_Base::insert(__pos.base(), __x), this);
  280. }
  281. #if __cplusplus >= 201103L
  282. iterator
  283. insert(const_iterator __pos, _Tp&& __x)
  284. {
  285. _M_profile_insert(__pos, this->size());
  286. return iterator(_Base::emplace(__pos.base(), std::move(__x)),
  287. this);
  288. }
  289. iterator
  290. insert(const_iterator __pos, initializer_list<value_type> __l)
  291. {
  292. _M_profile_insert(__pos, this->size());
  293. return iterator(_Base::insert(__pos.base(), __l), this);
  294. }
  295. #endif
  296. #if __cplusplus >= 201103L
  297. iterator
  298. insert(const_iterator __pos, size_type __n, const _Tp& __x)
  299. {
  300. _M_profile_insert(__pos, this->size());
  301. return iterator(_Base::insert(__pos.base(), __n, __x), this);
  302. }
  303. #else
  304. void
  305. insert(iterator __pos, size_type __n, const _Tp& __x)
  306. {
  307. _M_profile_insert(__pos, this->size());
  308. _Base::insert(__pos.base(), __n, __x);
  309. }
  310. #endif
  311. #if __cplusplus >= 201103L
  312. template<typename _InputIterator,
  313. typename = std::_RequireInputIter<_InputIterator>>
  314. iterator
  315. insert(const_iterator __pos, _InputIterator __first,
  316. _InputIterator __last)
  317. {
  318. _M_profile_insert(__pos, this->size());
  319. return iterator(_Base::insert(__pos.base(), __first, __last),
  320. this);
  321. }
  322. #else
  323. template<class _InputIterator>
  324. void
  325. insert(iterator __pos, _InputIterator __first,
  326. _InputIterator __last)
  327. {
  328. _M_profile_insert(__pos, this->size());
  329. _Base::insert(__pos.base(), __first, __last);
  330. }
  331. #endif
  332. iterator
  333. #if __cplusplus >= 201103L
  334. erase(const_iterator __pos) noexcept
  335. #else
  336. erase(iterator __pos)
  337. #endif
  338. { return iterator(_Base::erase(__pos.base()), this); }
  339. iterator
  340. #if __cplusplus >= 201103L
  341. erase(const_iterator __pos, const_iterator __last) noexcept
  342. #else
  343. erase(iterator __pos, iterator __last)
  344. #endif
  345. {
  346. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  347. // 151. can't currently clear() empty container
  348. return iterator(_Base::erase(__pos.base(), __last.base()), this);
  349. }
  350. void
  351. swap(list& __x)
  352. _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
  353. {
  354. _Base::swap(__x);
  355. this->_M_swap(__x);
  356. }
  357. void
  358. clear() _GLIBCXX_NOEXCEPT
  359. {
  360. this->_M_profile_destruct();
  361. _Base::clear();
  362. this->_M_profile_construct();
  363. }
  364. // 23.2.2.4 list operations:
  365. void
  366. #if __cplusplus >= 201103L
  367. splice(const_iterator __pos, list&& __x) noexcept
  368. #else
  369. splice(iterator __pos, list& __x)
  370. #endif
  371. { this->splice(__pos, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }
  372. #if __cplusplus >= 201103L
  373. void
  374. splice(const_iterator __pos, list& __x) noexcept
  375. { this->splice(__pos, std::move(__x)); }
  376. void
  377. splice(const_iterator __pos, list& __x, const_iterator __i)
  378. { this->splice(__pos, std::move(__x), __i); }
  379. #endif
  380. void
  381. #if __cplusplus >= 201103L
  382. splice(const_iterator __pos, list&& __x, const_iterator __i) noexcept
  383. #else
  384. splice(iterator __pos, list& __x, iterator __i)
  385. #endif
  386. {
  387. // We used to perform the splice_alloc check: not anymore, redundant
  388. // after implementing the relevant bits of N1599.
  389. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  390. _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()),
  391. __i.base());
  392. }
  393. void
  394. #if __cplusplus >= 201103L
  395. splice(const_iterator __pos, list&& __x, const_iterator __first,
  396. const_iterator __last) noexcept
  397. #else
  398. splice(iterator __pos, list& __x, iterator __first,
  399. iterator __last)
  400. #endif
  401. {
  402. _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()),
  403. __first.base(), __last.base());
  404. }
  405. #if __cplusplus >= 201103L
  406. void
  407. splice(const_iterator __pos, list& __x,
  408. const_iterator __first, const_iterator __last) noexcept
  409. { this->splice(__pos, std::move(__x), __first, __last); }
  410. #endif
  411. void
  412. remove(const _Tp& __value)
  413. {
  414. for (iterator __x = begin(); __x != end(); )
  415. {
  416. if (*__x == __value)
  417. __x = erase(__x);
  418. else
  419. ++__x;
  420. }
  421. }
  422. template<class _Predicate>
  423. void
  424. remove_if(_Predicate __pred)
  425. {
  426. for (iterator __x = begin(); __x != end(); )
  427. {
  428. __profcxx_list2slist_operation(this->_M_list2slist_info);
  429. if (__pred(*__x))
  430. __x = erase(__x);
  431. else
  432. ++__x;
  433. }
  434. }
  435. void
  436. unique()
  437. {
  438. iterator __first = begin();
  439. iterator __last = end();
  440. if (__first == __last)
  441. return;
  442. iterator __next = __first;
  443. while (++__next != __last)
  444. {
  445. __profcxx_list2slist_operation(this->_M_list2slist_info);
  446. if (*__first == *__next)
  447. erase(__next);
  448. else
  449. __first = __next;
  450. __next = __first;
  451. }
  452. }
  453. template<class _BinaryPredicate>
  454. void
  455. unique(_BinaryPredicate __binary_pred)
  456. {
  457. iterator __first = begin();
  458. iterator __last = end();
  459. if (__first == __last)
  460. return;
  461. iterator __next = __first;
  462. while (++__next != __last)
  463. {
  464. __profcxx_list2slist_operation(this->_M_list2slist_info);
  465. if (__binary_pred(*__first, *__next))
  466. erase(__next);
  467. else
  468. __first = __next;
  469. __next = __first;
  470. }
  471. }
  472. void
  473. #if __cplusplus >= 201103L
  474. merge(list&& __x)
  475. #else
  476. merge(list& __x)
  477. #endif
  478. { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
  479. #if __cplusplus >= 201103L
  480. void
  481. merge(list& __x)
  482. { this->merge(std::move(__x)); }
  483. #endif
  484. template<class _Compare>
  485. void
  486. #if __cplusplus >= 201103L
  487. merge(list&& __x, _Compare __comp)
  488. #else
  489. merge(list& __x, _Compare __comp)
  490. #endif
  491. { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
  492. #if __cplusplus >= 201103L
  493. template<typename _Compare>
  494. void
  495. merge(list& __x, _Compare __comp)
  496. { this->merge(std::move(__x), __comp); }
  497. #endif
  498. _Base&
  499. _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  500. const _Base&
  501. _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  502. void _M_profile_iterate(int __rewind = 0) const
  503. {
  504. __profcxx_list2slist_operation(this->_M_list2slist_info);
  505. __profcxx_list2vector_iterate(this->_M_list2vector_info, __rewind);
  506. if (__rewind)
  507. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  508. }
  509. private:
  510. size_type
  511. _M_profile_insert(const_iterator __pos, size_type __size)
  512. {
  513. size_type __shift = 0;
  514. typename _Base::const_iterator __it = __pos.base();
  515. for (; __it != _Base::end(); ++__it)
  516. __shift++;
  517. __profcxx_list2slist_rewind(this->_M_list2slist_info);
  518. __profcxx_list2slist_operation(this->_M_list2slist_info);
  519. __profcxx_list2vector_insert(this->_M_list2vector_info, __shift, __size);
  520. }
  521. };
  522. template<typename _Tp, typename _Alloc>
  523. inline bool
  524. operator==(const list<_Tp, _Alloc>& __lhs,
  525. const list<_Tp, _Alloc>& __rhs)
  526. { return __lhs._M_base() == __rhs._M_base(); }
  527. template<typename _Tp, typename _Alloc>
  528. inline bool
  529. operator!=(const list<_Tp, _Alloc>& __lhs,
  530. const list<_Tp, _Alloc>& __rhs)
  531. { return __lhs._M_base() != __rhs._M_base(); }
  532. template<typename _Tp, typename _Alloc>
  533. inline bool
  534. operator<(const list<_Tp, _Alloc>& __lhs,
  535. const list<_Tp, _Alloc>& __rhs)
  536. { return __lhs._M_base() < __rhs._M_base(); }
  537. template<typename _Tp, typename _Alloc>
  538. inline bool
  539. operator<=(const list<_Tp, _Alloc>& __lhs,
  540. const list<_Tp, _Alloc>& __rhs)
  541. { return __lhs._M_base() <= __rhs._M_base(); }
  542. template<typename _Tp, typename _Alloc>
  543. inline bool
  544. operator>=(const list<_Tp, _Alloc>& __lhs,
  545. const list<_Tp, _Alloc>& __rhs)
  546. { return __lhs._M_base() >= __rhs._M_base(); }
  547. template<typename _Tp, typename _Alloc>
  548. inline bool
  549. operator>(const list<_Tp, _Alloc>& __lhs,
  550. const list<_Tp, _Alloc>& __rhs)
  551. { return __lhs._M_base() > __rhs._M_base(); }
  552. template<typename _Tp, typename _Alloc>
  553. inline void
  554. swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
  555. _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
  556. { __lhs.swap(__rhs); }
  557. } // namespace __profile
  558. } // namespace std
  559. #endif