map.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. // Profiling map 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. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Under Section 7 of GPL version 3, you are granted additional
  15. // permissions described in the GCC Runtime Library Exception, version
  16. // 3.1, as published by the Free Software Foundation.
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING3. If not see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file profile/map.h
  21. * This file is a GNU profile extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_PROFILE_MAP_H
  24. #define _GLIBCXX_PROFILE_MAP_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::map wrapper with performance instrumentation.
  32. template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
  33. typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
  34. class map
  35. : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>,
  36. public _Ordered_profile<map<_Key, _Tp, _Compare, _Allocator> >
  37. {
  38. typedef _GLIBCXX_STD_C::map<_Key, _Tp, _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 _Tp mapped_type;
  45. typedef typename _Base::value_type value_type;
  46. typedef _Compare key_compare;
  47. typedef typename _Base::reference reference;
  48. typedef typename _Base::const_reference const_reference;
  49. typedef __iterator_tracker<_Base_iterator, map> iterator;
  50. typedef __iterator_tracker<_Base_const_iterator,
  51. map> const_iterator;
  52. typedef std::reverse_iterator<iterator> reverse_iterator;
  53. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  54. typedef typename _Base::size_type size_type;
  55. typedef typename _Base::difference_type difference_type;
  56. // 23.3.1.1 construct/copy/destroy:
  57. #if __cplusplus < 201103L
  58. map()
  59. : _Base() { }
  60. map(const map& __x)
  61. : _Base(__x) { }
  62. ~map()
  63. { }
  64. #else
  65. map() = default;
  66. map(const map&) = default;
  67. map(map&&) = default;
  68. ~map() = default;
  69. #endif
  70. explicit
  71. map(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. map(_InputIterator __first, _InputIterator __last,
  81. const _Compare& __comp = _Compare(),
  82. const _Allocator& __a = _Allocator())
  83. : _Base(__first, __last, __comp, __a) { }
  84. map(const _Base& __x)
  85. : _Base(__x) { }
  86. #if __cplusplus >= 201103L
  87. map(initializer_list<value_type> __l,
  88. const _Compare& __c = _Compare(),
  89. const _Allocator& __a = _Allocator())
  90. : _Base(__l, __c, __a) { }
  91. explicit
  92. map(const _Allocator& __a)
  93. : _Base(__a) { }
  94. map(const map& __x, const _Allocator& __a)
  95. : _Base(__x, __a) { }
  96. map(map&& __x, const _Allocator& __a)
  97. noexcept( noexcept(_Base(std::move(__x), __a)) )
  98. : _Base(std::move(__x), __a) { }
  99. map(initializer_list<value_type> __l, const _Allocator& __a)
  100. : _Base(__l, __a) { }
  101. template<typename _InputIterator>
  102. map(_InputIterator __first, _InputIterator __last,
  103. const _Allocator& __a)
  104. : _Base(__first, __last, __a) { }
  105. #endif
  106. #if __cplusplus < 201103L
  107. map&
  108. operator=(const map& __x)
  109. {
  110. this->_M_profile_destruct();
  111. _M_base() = __x;
  112. this->_M_profile_construct();
  113. return *this;
  114. }
  115. #else
  116. map&
  117. operator=(const map&) = default;
  118. map&
  119. operator=(map&&) = default;
  120. map&
  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. // 23.3.1.2 element access:
  189. mapped_type&
  190. operator[](const key_type& __k)
  191. {
  192. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  193. return _Base::operator[](__k);
  194. }
  195. #if __cplusplus >= 201103L
  196. mapped_type&
  197. operator[](key_type&& __k)
  198. {
  199. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  200. return _Base::operator[](std::move(__k));
  201. }
  202. #endif
  203. mapped_type&
  204. at(const key_type& __k)
  205. {
  206. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  207. return _Base::at(__k);
  208. }
  209. const mapped_type&
  210. at(const key_type& __k) const
  211. {
  212. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  213. return _Base::at(__k);
  214. }
  215. // modifiers:
  216. #if __cplusplus >= 201103L
  217. template<typename... _Args>
  218. std::pair<iterator, bool>
  219. emplace(_Args&&... __args)
  220. {
  221. // The cost is the same whether or not the element is inserted so we
  222. // always report insertion of 1 element.
  223. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1);
  224. auto __base_ret = _Base::emplace(std::forward<_Args>(__args)...);
  225. return std::make_pair(iterator(__base_ret.first, this),
  226. __base_ret.second);
  227. }
  228. template<typename... _Args>
  229. iterator
  230. emplace_hint(const_iterator __pos, _Args&&... __args)
  231. {
  232. auto size_before = this->size();
  233. auto __res
  234. = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...);
  235. __profcxx_map2umap_insert(this->_M_map2umap_info,
  236. size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1);
  237. return iterator(__res, this);
  238. }
  239. #endif
  240. std::pair<iterator, bool>
  241. insert(const value_type& __x)
  242. {
  243. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1);
  244. std::pair<_Base_iterator, bool> __base_ret = _Base::insert(__x);
  245. return std::make_pair(iterator(__base_ret.first, this),
  246. __base_ret.second);
  247. }
  248. #if __cplusplus >= 201103L
  249. template<typename _Pair, typename = typename
  250. std::enable_if<std::is_constructible<value_type,
  251. _Pair&&>::value>::type>
  252. std::pair<iterator, bool>
  253. insert(_Pair&& __x)
  254. {
  255. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1);
  256. auto __base_ret= _Base::insert(std::forward<_Pair>(__x));
  257. return std::make_pair(iterator(__base_ret.first, this),
  258. __base_ret.second);
  259. }
  260. #endif
  261. #if __cplusplus >= 201103L
  262. void
  263. insert(std::initializer_list<value_type> __list)
  264. { insert(__list.begin(), __list.end()); }
  265. #endif
  266. iterator
  267. #if __cplusplus >= 201103L
  268. insert(const_iterator __pos, const value_type& __x)
  269. #else
  270. insert(iterator __pos, const value_type& __x)
  271. #endif
  272. {
  273. size_type size_before = this->size();
  274. _Base_iterator __res = _Base::insert(__pos.base(), __x);
  275. __profcxx_map2umap_insert(this->_M_map2umap_info,
  276. size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1);
  277. return iterator(__res, this);
  278. }
  279. #if __cplusplus >= 201103L
  280. template<typename _Pair, typename = typename
  281. std::enable_if<std::is_constructible<value_type,
  282. _Pair&&>::value>::type>
  283. iterator
  284. insert(const_iterator __pos, _Pair&& __x)
  285. {
  286. size_type size_before = this->size();
  287. auto __res = _Base::insert(__pos.base(), std::forward<_Pair>(__x));
  288. __profcxx_map2umap_insert(this->_M_map2umap_info,
  289. size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1);
  290. return iterator(__res, this);
  291. }
  292. #endif
  293. template<typename _InputIterator>
  294. void
  295. insert(_InputIterator __first, _InputIterator __last)
  296. {
  297. for (; __first != __last; ++__first)
  298. insert(*__first);
  299. }
  300. #if __cplusplus >= 201103L
  301. iterator
  302. erase(const_iterator __pos)
  303. {
  304. __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1);
  305. return iterator(_Base::erase(__pos.base()), this);
  306. }
  307. iterator
  308. erase(iterator __pos)
  309. {
  310. __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1);
  311. return iterator(_Base::erase(__pos.base()), this);
  312. }
  313. #else
  314. void
  315. erase(iterator __pos)
  316. {
  317. __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1);
  318. _Base::erase(__pos.base());
  319. }
  320. #endif
  321. size_type
  322. erase(const key_type& __x)
  323. {
  324. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  325. __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1);
  326. return _Base::erase(__x);
  327. }
  328. #if __cplusplus >= 201103L
  329. iterator
  330. erase(const_iterator __first, const_iterator __last)
  331. {
  332. if (__first != __last)
  333. {
  334. iterator __ret;
  335. for (; __first != __last;)
  336. __ret = erase(__first++);
  337. return __ret;
  338. }
  339. else
  340. return iterator(_Base::erase(__first.base(), __last.base()), this);
  341. }
  342. #else
  343. void
  344. erase(iterator __first, iterator __last)
  345. {
  346. for (; __first != __last;)
  347. erase(__first++);
  348. }
  349. #endif
  350. void
  351. swap(map& __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.3.1.3 map operations:
  365. iterator
  366. find(const key_type& __x)
  367. {
  368. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  369. return iterator(_Base::find(__x), this);
  370. }
  371. #if __cplusplus > 201103L
  372. template<typename _Kt,
  373. typename _Req =
  374. typename __has_is_transparent<_Compare, _Kt>::type>
  375. iterator
  376. find(const _Kt& __x)
  377. {
  378. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  379. return { _Base::find(__x), this };
  380. }
  381. #endif
  382. const_iterator
  383. find(const key_type& __x) const
  384. {
  385. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  386. return const_iterator(_Base::find(__x), this);
  387. }
  388. #if __cplusplus > 201103L
  389. template<typename _Kt,
  390. typename _Req =
  391. typename __has_is_transparent<_Compare, _Kt>::type>
  392. const_iterator
  393. find(const _Kt& __x) const
  394. {
  395. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  396. return { _Base::find(__x), this };
  397. }
  398. #endif
  399. size_type
  400. count(const key_type& __x) const
  401. {
  402. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  403. return _Base::count(__x);
  404. }
  405. #if __cplusplus > 201103L
  406. template<typename _Kt,
  407. typename _Req =
  408. typename __has_is_transparent<_Compare, _Kt>::type>
  409. size_type
  410. count(const _Kt& __x) const
  411. {
  412. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  413. return _Base::count(__x);
  414. }
  415. #endif
  416. iterator
  417. lower_bound(const key_type& __x)
  418. {
  419. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  420. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  421. return iterator(_Base::lower_bound(__x), this);
  422. }
  423. #if __cplusplus > 201103L
  424. template<typename _Kt,
  425. typename _Req =
  426. typename __has_is_transparent<_Compare, _Kt>::type>
  427. iterator
  428. lower_bound(const _Kt& __x)
  429. {
  430. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  431. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  432. return { _Base::lower_bound(__x), this };
  433. }
  434. #endif
  435. const_iterator
  436. lower_bound(const key_type& __x) const
  437. {
  438. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  439. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  440. return const_iterator(_Base::lower_bound(__x), this);
  441. }
  442. #if __cplusplus > 201103L
  443. template<typename _Kt,
  444. typename _Req =
  445. typename __has_is_transparent<_Compare, _Kt>::type>
  446. const_iterator
  447. lower_bound(const _Kt& __x) const
  448. {
  449. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  450. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  451. return { _Base::lower_bound(__x), this };
  452. }
  453. #endif
  454. iterator
  455. upper_bound(const key_type& __x)
  456. {
  457. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  458. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  459. return iterator(_Base::upper_bound(__x), this);
  460. }
  461. #if __cplusplus > 201103L
  462. template<typename _Kt,
  463. typename _Req =
  464. typename __has_is_transparent<_Compare, _Kt>::type>
  465. iterator
  466. upper_bound(const _Kt& __x)
  467. {
  468. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  469. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  470. return { _Base::upper_bound(__x), this };
  471. }
  472. #endif
  473. const_iterator
  474. upper_bound(const key_type& __x) const
  475. {
  476. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  477. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  478. return const_iterator(_Base::upper_bound(__x), this);
  479. }
  480. #if __cplusplus > 201103L
  481. template<typename _Kt,
  482. typename _Req =
  483. typename __has_is_transparent<_Compare, _Kt>::type>
  484. const_iterator
  485. upper_bound(const _Kt& __x) const
  486. {
  487. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  488. __profcxx_map2umap_invalidate(this->_M_map2umap_info);
  489. return { _Base::upper_bound(__x), this };
  490. }
  491. #endif
  492. std::pair<iterator,iterator>
  493. equal_range(const key_type& __x)
  494. {
  495. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  496. std::pair<_Base_iterator, _Base_iterator> __base_ret
  497. = _Base::equal_range(__x);
  498. return std::make_pair(iterator(__base_ret.first, this),
  499. iterator(__base_ret.second, this));
  500. }
  501. #if __cplusplus > 201103L
  502. template<typename _Kt,
  503. typename _Req =
  504. typename __has_is_transparent<_Compare, _Kt>::type>
  505. std::pair<iterator, iterator>
  506. equal_range(const _Kt& __x)
  507. {
  508. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  509. auto __res = _Base::equal_range(__x);
  510. return { { __res.first, this }, { __res.second, this } };
  511. }
  512. #endif
  513. std::pair<const_iterator,const_iterator>
  514. equal_range(const key_type& __x) const
  515. {
  516. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  517. std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret
  518. = _Base::equal_range(__x);
  519. return std::make_pair(const_iterator(__base_ret.first, this),
  520. const_iterator(__base_ret.second, this));
  521. }
  522. #if __cplusplus > 201103L
  523. template<typename _Kt,
  524. typename _Req =
  525. typename __has_is_transparent<_Compare, _Kt>::type>
  526. std::pair<const_iterator, const_iterator>
  527. equal_range(const _Kt& __x) const
  528. {
  529. __profcxx_map2umap_find(this->_M_map2umap_info, this->size());
  530. auto __res = _Base::equal_range(__x);
  531. return { { __res.first, this }, { __res.second, this } };
  532. }
  533. #endif
  534. _Base&
  535. _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  536. const _Base&
  537. _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  538. private:
  539. /** If hint is used we consider that the map and unordered_map
  540. * operations have equivalent insertion cost so we do not update metrics
  541. * about it.
  542. * Note that to find out if hint has been used is libstdc++
  543. * implementation dependent.
  544. */
  545. bool
  546. _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res)
  547. {
  548. return (__hint == __res
  549. || (__hint == _M_base().end() && ++__res == _M_base().end())
  550. || (__hint != _M_base().end() && (++__hint == __res
  551. || ++__res == --__hint)));
  552. }
  553. template<typename _K1, typename _T1, typename _C1, typename _A1>
  554. friend bool
  555. operator==(const map<_K1, _T1, _C1, _A1>&,
  556. const map<_K1, _T1, _C1, _A1>&);
  557. template<typename _K1, typename _T1, typename _C1, typename _A1>
  558. friend bool
  559. operator<(const map<_K1, _T1, _C1, _A1>&,
  560. const map<_K1, _T1, _C1, _A1>&);
  561. };
  562. template<typename _Key, typename _Tp,
  563. typename _Compare, typename _Allocator>
  564. inline bool
  565. operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  566. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  567. {
  568. __profcxx_map2umap_invalidate(__lhs._M_map2umap_info);
  569. __profcxx_map2umap_invalidate(__rhs._M_map2umap_info);
  570. return __lhs._M_base() == __rhs._M_base();
  571. }
  572. template<typename _Key, typename _Tp,
  573. typename _Compare, typename _Allocator>
  574. inline bool
  575. operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  576. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  577. {
  578. __profcxx_map2umap_invalidate(__lhs._M_map2umap_info);
  579. __profcxx_map2umap_invalidate(__rhs._M_map2umap_info);
  580. return __lhs._M_base() < __rhs._M_base();
  581. }
  582. template<typename _Key, typename _Tp,
  583. typename _Compare, typename _Allocator>
  584. inline bool
  585. operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  586. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  587. { return !(__lhs == __rhs); }
  588. template<typename _Key, typename _Tp,
  589. typename _Compare, typename _Allocator>
  590. inline bool
  591. operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  592. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  593. { return !(__rhs < __lhs); }
  594. template<typename _Key, typename _Tp,
  595. typename _Compare, typename _Allocator>
  596. inline bool
  597. operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  598. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  599. { return !(__lhs < __rhs); }
  600. template<typename _Key, typename _Tp,
  601. typename _Compare, typename _Allocator>
  602. inline bool
  603. operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  604. const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  605. { return __rhs < __lhs; }
  606. template<typename _Key, typename _Tp,
  607. typename _Compare, typename _Allocator>
  608. inline void
  609. swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
  610. map<_Key, _Tp, _Compare, _Allocator>& __rhs)
  611. _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
  612. { __lhs.swap(__rhs); }
  613. } // namespace __profile
  614. } // namespace std
  615. #endif