multiset.h 18 KB

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