You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

600 lines
17KB

  1. // Hashing map implementation -*- 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. * Copyright (c) 1996
  22. * Silicon Graphics Computer Systems, Inc.
  23. *
  24. * Permission to use, copy, modify, distribute and sell this software
  25. * and its documentation for any purpose is hereby granted without fee,
  26. * provided that the above copyright notice appear in all copies and
  27. * that both that copyright notice and this permission notice appear
  28. * in supporting documentation. Silicon Graphics makes no
  29. * representations about the suitability of this software for any
  30. * purpose. It is provided "as is" without express or implied warranty.
  31. *
  32. *
  33. * Copyright (c) 1994
  34. * Hewlett-Packard Company
  35. *
  36. * Permission to use, copy, modify, distribute and sell this software
  37. * and its documentation for any purpose is hereby granted without fee,
  38. * provided that the above copyright notice appear in all copies and
  39. * that both that copyright notice and this permission notice appear
  40. * in supporting documentation. Hewlett-Packard Company makes no
  41. * representations about the suitability of this software for any
  42. * purpose. It is provided "as is" without express or implied warranty.
  43. *
  44. */
  45. /** @file backward/hash_map
  46. * This file is a GNU extension to the Standard C++ Library (possibly
  47. * containing extensions from the HP/SGI STL subset).
  48. */
  49. #ifndef _BACKWARD_HASH_MAP
  50. #define _BACKWARD_HASH_MAP 1
  51. #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
  52. #include <backward/backward_warning.h>
  53. #endif
  54. #include <bits/c++config.h>
  55. #include <backward/hashtable.h>
  56. #include <bits/concept_check.h>
  57. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  58. {
  59. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  60. using std::equal_to;
  61. using std::allocator;
  62. using std::pair;
  63. using std::_Select1st;
  64. /**
  65. * This is an SGI extension.
  66. * @ingroup SGIextensions
  67. * @doctodo
  68. */
  69. template<class _Key, class _Tp, class _HashFn = hash<_Key>,
  70. class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
  71. class hash_map
  72. {
  73. private:
  74. typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
  75. _Select1st<pair<const _Key, _Tp> >,
  76. _EqualKey, _Alloc> _Ht;
  77. _Ht _M_ht;
  78. public:
  79. typedef typename _Ht::key_type key_type;
  80. typedef _Tp data_type;
  81. typedef _Tp mapped_type;
  82. typedef typename _Ht::value_type value_type;
  83. typedef typename _Ht::hasher hasher;
  84. typedef typename _Ht::key_equal key_equal;
  85. typedef typename _Ht::size_type size_type;
  86. typedef typename _Ht::difference_type difference_type;
  87. typedef typename _Ht::pointer pointer;
  88. typedef typename _Ht::const_pointer const_pointer;
  89. typedef typename _Ht::reference reference;
  90. typedef typename _Ht::const_reference const_reference;
  91. typedef typename _Ht::iterator iterator;
  92. typedef typename _Ht::const_iterator const_iterator;
  93. typedef typename _Ht::allocator_type allocator_type;
  94. hasher
  95. hash_funct() const
  96. { return _M_ht.hash_funct(); }
  97. key_equal
  98. key_eq() const
  99. { return _M_ht.key_eq(); }
  100. allocator_type
  101. get_allocator() const
  102. { return _M_ht.get_allocator(); }
  103. hash_map()
  104. : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
  105. explicit
  106. hash_map(size_type __n)
  107. : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
  108. hash_map(size_type __n, const hasher& __hf)
  109. : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
  110. hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
  111. const allocator_type& __a = allocator_type())
  112. : _M_ht(__n, __hf, __eql, __a) {}
  113. template<class _InputIterator>
  114. hash_map(_InputIterator __f, _InputIterator __l)
  115. : _M_ht(100, hasher(), key_equal(), allocator_type())
  116. { _M_ht.insert_unique(__f, __l); }
  117. template<class _InputIterator>
  118. hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
  119. : _M_ht(__n, hasher(), key_equal(), allocator_type())
  120. { _M_ht.insert_unique(__f, __l); }
  121. template<class _InputIterator>
  122. hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
  123. const hasher& __hf)
  124. : _M_ht(__n, __hf, key_equal(), allocator_type())
  125. { _M_ht.insert_unique(__f, __l); }
  126. template<class _InputIterator>
  127. hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
  128. const hasher& __hf, const key_equal& __eql,
  129. const allocator_type& __a = allocator_type())
  130. : _M_ht(__n, __hf, __eql, __a)
  131. { _M_ht.insert_unique(__f, __l); }
  132. size_type
  133. size() const
  134. { return _M_ht.size(); }
  135. size_type
  136. max_size() const
  137. { return _M_ht.max_size(); }
  138. _GLIBCXX_NODISCARD bool
  139. empty() const
  140. { return _M_ht.empty(); }
  141. void
  142. swap(hash_map& __hs)
  143. { _M_ht.swap(__hs._M_ht); }
  144. template<class _K1, class _T1, class _HF, class _EqK, class _Al>
  145. friend bool
  146. operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
  147. const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
  148. iterator
  149. begin()
  150. { return _M_ht.begin(); }
  151. iterator
  152. end()
  153. { return _M_ht.end(); }
  154. const_iterator
  155. begin() const
  156. { return _M_ht.begin(); }
  157. const_iterator
  158. end() const
  159. { return _M_ht.end(); }
  160. pair<iterator, bool>
  161. insert(const value_type& __obj)
  162. { return _M_ht.insert_unique(__obj); }
  163. template<class _InputIterator>
  164. void
  165. insert(_InputIterator __f, _InputIterator __l)
  166. { _M_ht.insert_unique(__f, __l); }
  167. pair<iterator, bool>
  168. insert_noresize(const value_type& __obj)
  169. { return _M_ht.insert_unique_noresize(__obj); }
  170. iterator
  171. find(const key_type& __key)
  172. { return _M_ht.find(__key); }
  173. const_iterator
  174. find(const key_type& __key) const
  175. { return _M_ht.find(__key); }
  176. _Tp&
  177. operator[](const key_type& __key)
  178. { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
  179. size_type
  180. count(const key_type& __key) const
  181. { return _M_ht.count(__key); }
  182. pair<iterator, iterator>
  183. equal_range(const key_type& __key)
  184. { return _M_ht.equal_range(__key); }
  185. pair<const_iterator, const_iterator>
  186. equal_range(const key_type& __key) const
  187. { return _M_ht.equal_range(__key); }
  188. size_type
  189. erase(const key_type& __key)
  190. {return _M_ht.erase(__key); }
  191. void
  192. erase(iterator __it)
  193. { _M_ht.erase(__it); }
  194. void
  195. erase(iterator __f, iterator __l)
  196. { _M_ht.erase(__f, __l); }
  197. void
  198. clear()
  199. { _M_ht.clear(); }
  200. void
  201. resize(size_type __hint)
  202. { _M_ht.resize(__hint); }
  203. size_type
  204. bucket_count() const
  205. { return _M_ht.bucket_count(); }
  206. size_type
  207. max_bucket_count() const
  208. { return _M_ht.max_bucket_count(); }
  209. size_type
  210. elems_in_bucket(size_type __n) const
  211. { return _M_ht.elems_in_bucket(__n); }
  212. };
  213. template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
  214. inline bool
  215. operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
  216. const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
  217. { return __hm1._M_ht == __hm2._M_ht; }
  218. template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
  219. inline bool
  220. operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
  221. const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
  222. { return !(__hm1 == __hm2); }
  223. template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
  224. inline void
  225. swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
  226. hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
  227. { __hm1.swap(__hm2); }
  228. /**
  229. * This is an SGI extension.
  230. * @ingroup SGIextensions
  231. * @doctodo
  232. */
  233. template<class _Key, class _Tp,
  234. class _HashFn = hash<_Key>,
  235. class _EqualKey = equal_to<_Key>,
  236. class _Alloc = allocator<_Tp> >
  237. class hash_multimap
  238. {
  239. // concept requirements
  240. __glibcxx_class_requires(_Key, _SGIAssignableConcept)
  241. __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
  242. __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept)
  243. __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept)
  244. private:
  245. typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
  246. _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
  247. _Ht;
  248. _Ht _M_ht;
  249. public:
  250. typedef typename _Ht::key_type key_type;
  251. typedef _Tp data_type;
  252. typedef _Tp mapped_type;
  253. typedef typename _Ht::value_type value_type;
  254. typedef typename _Ht::hasher hasher;
  255. typedef typename _Ht::key_equal key_equal;
  256. typedef typename _Ht::size_type size_type;
  257. typedef typename _Ht::difference_type difference_type;
  258. typedef typename _Ht::pointer pointer;
  259. typedef typename _Ht::const_pointer const_pointer;
  260. typedef typename _Ht::reference reference;
  261. typedef typename _Ht::const_reference const_reference;
  262. typedef typename _Ht::iterator iterator;
  263. typedef typename _Ht::const_iterator const_iterator;
  264. typedef typename _Ht::allocator_type allocator_type;
  265. hasher
  266. hash_funct() const
  267. { return _M_ht.hash_funct(); }
  268. key_equal
  269. key_eq() const
  270. { return _M_ht.key_eq(); }
  271. allocator_type
  272. get_allocator() const
  273. { return _M_ht.get_allocator(); }
  274. hash_multimap()
  275. : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
  276. explicit
  277. hash_multimap(size_type __n)
  278. : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
  279. hash_multimap(size_type __n, const hasher& __hf)
  280. : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
  281. hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
  282. const allocator_type& __a = allocator_type())
  283. : _M_ht(__n, __hf, __eql, __a) {}
  284. template<class _InputIterator>
  285. hash_multimap(_InputIterator __f, _InputIterator __l)
  286. : _M_ht(100, hasher(), key_equal(), allocator_type())
  287. { _M_ht.insert_equal(__f, __l); }
  288. template<class _InputIterator>
  289. hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
  290. : _M_ht(__n, hasher(), key_equal(), allocator_type())
  291. { _M_ht.insert_equal(__f, __l); }
  292. template<class _InputIterator>
  293. hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
  294. const hasher& __hf)
  295. : _M_ht(__n, __hf, key_equal(), allocator_type())
  296. { _M_ht.insert_equal(__f, __l); }
  297. template<class _InputIterator>
  298. hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
  299. const hasher& __hf, const key_equal& __eql,
  300. const allocator_type& __a = allocator_type())
  301. : _M_ht(__n, __hf, __eql, __a)
  302. { _M_ht.insert_equal(__f, __l); }
  303. size_type
  304. size() const
  305. { return _M_ht.size(); }
  306. size_type
  307. max_size() const
  308. { return _M_ht.max_size(); }
  309. _GLIBCXX_NODISCARD bool
  310. empty() const
  311. { return _M_ht.empty(); }
  312. void
  313. swap(hash_multimap& __hs)
  314. { _M_ht.swap(__hs._M_ht); }
  315. template<class _K1, class _T1, class _HF, class _EqK, class _Al>
  316. friend bool
  317. operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
  318. const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
  319. iterator
  320. begin()
  321. { return _M_ht.begin(); }
  322. iterator
  323. end()
  324. { return _M_ht.end(); }
  325. const_iterator
  326. begin() const
  327. { return _M_ht.begin(); }
  328. const_iterator
  329. end() const
  330. { return _M_ht.end(); }
  331. iterator
  332. insert(const value_type& __obj)
  333. { return _M_ht.insert_equal(__obj); }
  334. template<class _InputIterator>
  335. void
  336. insert(_InputIterator __f, _InputIterator __l)
  337. { _M_ht.insert_equal(__f,__l); }
  338. iterator
  339. insert_noresize(const value_type& __obj)
  340. { return _M_ht.insert_equal_noresize(__obj); }
  341. iterator
  342. find(const key_type& __key)
  343. { return _M_ht.find(__key); }
  344. const_iterator
  345. find(const key_type& __key) const
  346. { return _M_ht.find(__key); }
  347. size_type
  348. count(const key_type& __key) const
  349. { return _M_ht.count(__key); }
  350. pair<iterator, iterator>
  351. equal_range(const key_type& __key)
  352. { return _M_ht.equal_range(__key); }
  353. pair<const_iterator, const_iterator>
  354. equal_range(const key_type& __key) const
  355. { return _M_ht.equal_range(__key); }
  356. size_type
  357. erase(const key_type& __key)
  358. { return _M_ht.erase(__key); }
  359. void
  360. erase(iterator __it)
  361. { _M_ht.erase(__it); }
  362. void
  363. erase(iterator __f, iterator __l)
  364. { _M_ht.erase(__f, __l); }
  365. void
  366. clear()
  367. { _M_ht.clear(); }
  368. void
  369. resize(size_type __hint)
  370. { _M_ht.resize(__hint); }
  371. size_type
  372. bucket_count() const
  373. { return _M_ht.bucket_count(); }
  374. size_type
  375. max_bucket_count() const
  376. { return _M_ht.max_bucket_count(); }
  377. size_type
  378. elems_in_bucket(size_type __n) const
  379. { return _M_ht.elems_in_bucket(__n); }
  380. };
  381. template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
  382. inline bool
  383. operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
  384. const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
  385. { return __hm1._M_ht == __hm2._M_ht; }
  386. template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
  387. inline bool
  388. operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
  389. const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
  390. { return !(__hm1 == __hm2); }
  391. template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
  392. inline void
  393. swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
  394. hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
  395. { __hm1.swap(__hm2); }
  396. _GLIBCXX_END_NAMESPACE_VERSION
  397. } // namespace
  398. namespace std _GLIBCXX_VISIBILITY(default)
  399. {
  400. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  401. // Specialization of insert_iterator so that it will work for hash_map
  402. // and hash_multimap.
  403. template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
  404. class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn,
  405. _EqKey, _Alloc> >
  406. {
  407. protected:
  408. typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
  409. _Container;
  410. _Container* container;
  411. public:
  412. typedef _Container container_type;
  413. typedef output_iterator_tag iterator_category;
  414. typedef void value_type;
  415. typedef void difference_type;
  416. typedef void pointer;
  417. typedef void reference;
  418. insert_iterator(_Container& __x)
  419. : container(&__x) {}
  420. insert_iterator(_Container& __x, typename _Container::iterator)
  421. : container(&__x) {}
  422. insert_iterator<_Container>&
  423. operator=(const typename _Container::value_type& __value)
  424. {
  425. container->insert(__value);
  426. return *this;
  427. }
  428. insert_iterator<_Container>&
  429. operator*()
  430. { return *this; }
  431. insert_iterator<_Container>&
  432. operator++() { return *this; }
  433. insert_iterator<_Container>&
  434. operator++(int)
  435. { return *this; }
  436. };
  437. template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
  438. class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
  439. _EqKey, _Alloc> >
  440. {
  441. protected:
  442. typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
  443. _Container;
  444. _Container* container;
  445. typename _Container::iterator iter;
  446. public:
  447. typedef _Container container_type;
  448. typedef output_iterator_tag iterator_category;
  449. typedef void value_type;
  450. typedef void difference_type;
  451. typedef void pointer;
  452. typedef void reference;
  453. insert_iterator(_Container& __x)
  454. : container(&__x) {}
  455. insert_iterator(_Container& __x, typename _Container::iterator)
  456. : container(&__x) {}
  457. insert_iterator<_Container>&
  458. operator=(const typename _Container::value_type& __value)
  459. {
  460. container->insert(__value);
  461. return *this;
  462. }
  463. insert_iterator<_Container>&
  464. operator*()
  465. { return *this; }
  466. insert_iterator<_Container>&
  467. operator++()
  468. { return *this; }
  469. insert_iterator<_Container>&
  470. operator++(int)
  471. { return *this; }
  472. };
  473. _GLIBCXX_END_NAMESPACE_VERSION
  474. } // namespace
  475. #endif