1 // Hashing set implementation -*- C++ -*-
3 // Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
32 * Silicon Graphics Computer Systems, Inc.
34 * Permission to use, copy, modify, distribute and sell this software
35 * and its documentation for any purpose is hereby granted without fee,
36 * provided that the above copyright notice appear in all copies and
37 * that both that copyright notice and this permission notice appear
38 * in supporting documentation. Silicon Graphics makes no
39 * representations about the suitability of this software for any
40 * purpose. It is provided "as is" without express or implied warranty.
44 * Hewlett-Packard Company
46 * Permission to use, copy, modify, distribute and sell this software
47 * and its documentation for any purpose is hereby granted without fee,
48 * provided that the above copyright notice appear in all copies and
49 * that both that copyright notice and this permission notice appear
50 * in supporting documentation. Hewlett-Packard Company makes no
51 * representations about the suitability of this software for any
52 * purpose. It is provided "as is" without express or implied warranty.
56 /** @file ext/hash_set
57 * This file is a GNU extension to the Standard C++ Library (possibly
58 * containing extensions from the HP/SGI STL subset).
64 #include <bits/c++config.h>
65 #include <ext/hashtable.h>
66 #include <bits/concept_check.h>
68 _GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT_D)
76 * This is an SGI extension.
77 * @ingroup SGIextensions
80 template<class _Value, class _HashFcn = hash<_Value>,
81 class _EqualKey = equal_to<_Value>,
82 class _Alloc = allocator<_Value> >
85 // concept requirements
86 __glibcxx_class_requires(_Value, _SGIAssignableConcept)
87 __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
88 __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
91 typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
92 _EqualKey, _Alloc> _Ht;
96 typedef typename _Ht::key_type key_type;
97 typedef typename _Ht::value_type value_type;
98 typedef typename _Ht::hasher hasher;
99 typedef typename _Ht::key_equal key_equal;
101 typedef typename _Ht::size_type size_type;
102 typedef typename _Ht::difference_type difference_type;
103 typedef typename _Alloc::pointer pointer;
104 typedef typename _Alloc::const_pointer const_pointer;
105 typedef typename _Alloc::reference reference;
106 typedef typename _Alloc::const_reference const_reference;
108 typedef typename _Ht::const_iterator iterator;
109 typedef typename _Ht::const_iterator const_iterator;
111 typedef typename _Ht::allocator_type allocator_type;
115 { return _M_ht.hash_funct(); }
119 { return _M_ht.key_eq(); }
122 get_allocator() const
123 { return _M_ht.get_allocator(); }
126 : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
129 hash_set(size_type __n)
130 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
132 hash_set(size_type __n, const hasher& __hf)
133 : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
135 hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
136 const allocator_type& __a = allocator_type())
137 : _M_ht(__n, __hf, __eql, __a) {}
139 template<class _InputIterator>
140 hash_set(_InputIterator __f, _InputIterator __l)
141 : _M_ht(100, hasher(), key_equal(), allocator_type())
142 { _M_ht.insert_unique(__f, __l); }
144 template<class _InputIterator>
145 hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
146 : _M_ht(__n, hasher(), key_equal(), allocator_type())
147 { _M_ht.insert_unique(__f, __l); }
149 template<class _InputIterator>
150 hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
152 : _M_ht(__n, __hf, key_equal(), allocator_type())
153 { _M_ht.insert_unique(__f, __l); }
155 template<class _InputIterator>
156 hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
157 const hasher& __hf, const key_equal& __eql,
158 const allocator_type& __a = allocator_type())
159 : _M_ht(__n, __hf, __eql, __a)
160 { _M_ht.insert_unique(__f, __l); }
164 { return _M_ht.size(); }
168 { return _M_ht.max_size(); }
172 { return _M_ht.empty(); }
176 { _M_ht.swap(__hs._M_ht); }
178 template<class _Val, class _HF, class _EqK, class _Al>
180 operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
181 const hash_set<_Val, _HF, _EqK, _Al>&);
185 { return _M_ht.begin(); }
189 { return _M_ht.end(); }
192 insert(const value_type& __obj)
194 pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
195 return pair<iterator,bool>(__p.first, __p.second);
198 template<class _InputIterator>
200 insert(_InputIterator __f, _InputIterator __l)
201 { _M_ht.insert_unique(__f, __l); }
204 insert_noresize(const value_type& __obj)
206 pair<typename _Ht::iterator, bool> __p
207 = _M_ht.insert_unique_noresize(__obj);
208 return pair<iterator, bool>(__p.first, __p.second);
212 find(const key_type& __key) const
213 { return _M_ht.find(__key); }
216 count(const key_type& __key) const
217 { return _M_ht.count(__key); }
219 pair<iterator, iterator>
220 equal_range(const key_type& __key) const
221 { return _M_ht.equal_range(__key); }
224 erase(const key_type& __key)
225 {return _M_ht.erase(__key); }
229 { _M_ht.erase(__it); }
232 erase(iterator __f, iterator __l)
233 { _M_ht.erase(__f, __l); }
240 resize(size_type __hint)
241 { _M_ht.resize(__hint); }
245 { return _M_ht.bucket_count(); }
248 max_bucket_count() const
249 { return _M_ht.max_bucket_count(); }
252 elems_in_bucket(size_type __n) const
253 { return _M_ht.elems_in_bucket(__n); }
256 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
258 operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
259 const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
260 { return __hs1._M_ht == __hs2._M_ht; }
262 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
264 operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
265 const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
266 { return !(__hs1 == __hs2); }
268 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
270 swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
271 hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
272 { __hs1.swap(__hs2); }
276 * This is an SGI extension.
277 * @ingroup SGIextensions
280 template<class _Value,
281 class _HashFcn = hash<_Value>,
282 class _EqualKey = equal_to<_Value>,
283 class _Alloc = allocator<_Value> >
286 // concept requirements
287 __glibcxx_class_requires(_Value, _SGIAssignableConcept)
288 __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
289 __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
292 typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
293 _EqualKey, _Alloc> _Ht;
297 typedef typename _Ht::key_type key_type;
298 typedef typename _Ht::value_type value_type;
299 typedef typename _Ht::hasher hasher;
300 typedef typename _Ht::key_equal key_equal;
302 typedef typename _Ht::size_type size_type;
303 typedef typename _Ht::difference_type difference_type;
304 typedef typename _Alloc::pointer pointer;
305 typedef typename _Alloc::const_pointer const_pointer;
306 typedef typename _Alloc::reference reference;
307 typedef typename _Alloc::const_reference const_reference;
309 typedef typename _Ht::const_iterator iterator;
310 typedef typename _Ht::const_iterator const_iterator;
312 typedef typename _Ht::allocator_type allocator_type;
316 { return _M_ht.hash_funct(); }
320 { return _M_ht.key_eq(); }
323 get_allocator() const
324 { return _M_ht.get_allocator(); }
327 : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
330 hash_multiset(size_type __n)
331 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
333 hash_multiset(size_type __n, const hasher& __hf)
334 : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
336 hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
337 const allocator_type& __a = allocator_type())
338 : _M_ht(__n, __hf, __eql, __a) {}
340 template<class _InputIterator>
341 hash_multiset(_InputIterator __f, _InputIterator __l)
342 : _M_ht(100, hasher(), key_equal(), allocator_type())
343 { _M_ht.insert_equal(__f, __l); }
345 template<class _InputIterator>
346 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
347 : _M_ht(__n, hasher(), key_equal(), allocator_type())
348 { _M_ht.insert_equal(__f, __l); }
350 template<class _InputIterator>
351 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
353 : _M_ht(__n, __hf, key_equal(), allocator_type())
354 { _M_ht.insert_equal(__f, __l); }
356 template<class _InputIterator>
357 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
358 const hasher& __hf, const key_equal& __eql,
359 const allocator_type& __a = allocator_type())
360 : _M_ht(__n, __hf, __eql, __a)
361 { _M_ht.insert_equal(__f, __l); }
365 { return _M_ht.size(); }
369 { return _M_ht.max_size(); }
373 { return _M_ht.empty(); }
376 swap(hash_multiset& hs)
377 { _M_ht.swap(hs._M_ht); }
379 template<class _Val, class _HF, class _EqK, class _Al>
381 operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
382 const hash_multiset<_Val, _HF, _EqK, _Al>&);
386 { return _M_ht.begin(); }
390 { return _M_ht.end(); }
393 insert(const value_type& __obj)
394 { return _M_ht.insert_equal(__obj); }
396 template<class _InputIterator>
398 insert(_InputIterator __f, _InputIterator __l)
399 { _M_ht.insert_equal(__f,__l); }
402 insert_noresize(const value_type& __obj)
403 { return _M_ht.insert_equal_noresize(__obj); }
406 find(const key_type& __key) const
407 { return _M_ht.find(__key); }
410 count(const key_type& __key) const
411 { return _M_ht.count(__key); }
413 pair<iterator, iterator>
414 equal_range(const key_type& __key) const
415 { return _M_ht.equal_range(__key); }
418 erase(const key_type& __key)
419 { return _M_ht.erase(__key); }
423 { _M_ht.erase(__it); }
426 erase(iterator __f, iterator __l)
427 { _M_ht.erase(__f, __l); }
434 resize(size_type __hint)
435 { _M_ht.resize(__hint); }
439 { return _M_ht.bucket_count(); }
442 max_bucket_count() const
443 { return _M_ht.max_bucket_count(); }
446 elems_in_bucket(size_type __n) const
447 { return _M_ht.elems_in_bucket(__n); }
450 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
452 operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
453 const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
454 { return __hs1._M_ht == __hs2._M_ht; }
456 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
458 operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
459 const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
460 { return !(__hs1 == __hs2); }
462 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
464 swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
465 hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
466 { __hs1.swap(__hs2); }
468 _GLIBCXX_END_NESTED_NAMESPACE
470 #ifdef _GLIBCXX_DEBUG
471 # include <debug/hash_set>
474 _GLIBCXX_BEGIN_NAMESPACE(std)
476 // Specialization of insert_iterator so that it will work for hash_set
477 // and hash_multiset.
478 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
479 class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
483 typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
485 _Container* container;
488 typedef _Container container_type;
489 typedef output_iterator_tag iterator_category;
490 typedef void value_type;
491 typedef void difference_type;
492 typedef void pointer;
493 typedef void reference;
495 insert_iterator(_Container& __x)
498 insert_iterator(_Container& __x, typename _Container::iterator)
501 insert_iterator<_Container>&
502 operator=(const typename _Container::value_type& __value)
504 container->insert(__value);
508 insert_iterator<_Container>&
512 insert_iterator<_Container>&
516 insert_iterator<_Container>&
521 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
522 class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
526 typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
528 _Container* container;
529 typename _Container::iterator iter;
532 typedef _Container container_type;
533 typedef output_iterator_tag iterator_category;
534 typedef void value_type;
535 typedef void difference_type;
536 typedef void pointer;
537 typedef void reference;
539 insert_iterator(_Container& __x)
542 insert_iterator(_Container& __x, typename _Container::iterator)
545 insert_iterator<_Container>&
546 operator=(const typename _Container::value_type& __value)
548 container->insert(__value);
552 insert_iterator<_Container>&
556 insert_iterator<_Container>&
560 insert_iterator<_Container>&
561 operator++(int) { return *this; }
564 _GLIBCXX_END_NAMESPACE