1 // unordered_set implementation -*- C++ -*-
2 
3 // Copyright (C) 2010, 2011 Free Software Foundation, Inc.
4 //
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 3, or (at your option)
9 // any later version.
10 
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.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/unordered_set.h
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{unordered_set}
28  */
29 
30 #ifndef _UNORDERED_SET_H
31 #define _UNORDERED_SET_H
32 
33 namespace std _GLIBCXX_VISIBILITY(default)
34 {
35 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
36 
37   // NB: When we get typedef templates these class definitions
38   // will be unnecessary.
39   template<class _Value,
40 	   class _Hash = hash<_Value>,
41 	   class _Pred = std::equal_to<_Value>,
42 	   class _Alloc = std::allocator<_Value>,
43 	   bool __cache_hash_code =
44 	     __not_<__and_<is_integral<_Value>, is_empty<_Hash>,
45 			   integral_constant<bool, !__is_final(_Hash)>,
46 			   __detail::__is_noexcept_hash<_Value, _Hash>>>::value>
47     class __unordered_set
48     : public _Hashtable<_Value, _Value, _Alloc,
49 			std::_Identity<_Value>, _Pred,
50 			_Hash, __detail::_Mod_range_hashing,
51 			__detail::_Default_ranged_hash,
52 			__detail::_Prime_rehash_policy,
53 			__cache_hash_code, true, true>
54     {
55       typedef _Hashtable<_Value, _Value, _Alloc,
56 			 std::_Identity<_Value>, _Pred,
57 			 _Hash, __detail::_Mod_range_hashing,
58 			 __detail::_Default_ranged_hash,
59 			 __detail::_Prime_rehash_policy,
60 			 __cache_hash_code, true, true>
61         _Base;
62 
63     public:
64       typedef typename _Base::value_type      value_type;
65       typedef typename _Base::size_type       size_type;
66       typedef typename _Base::hasher          hasher;
67       typedef typename _Base::key_equal       key_equal;
68       typedef typename _Base::allocator_type  allocator_type;
69       typedef typename _Base::iterator        iterator;
70       typedef typename _Base::const_iterator  const_iterator;
71 
72       explicit
73       __unordered_set(size_type __n = 10,
74 		      const hasher& __hf = hasher(),
75 		      const key_equal& __eql = key_equal(),
76 		      const allocator_type& __a = allocator_type())
77       : _Base(__n, __hf, __detail::_Mod_range_hashing(),
78 	      __detail::_Default_ranged_hash(), __eql,
79 	      std::_Identity<value_type>(), __a)
80       { }
81 
82       template<typename _InputIterator>
83         __unordered_set(_InputIterator __f, _InputIterator __l,
84 			size_type __n = 0,
85 			const hasher& __hf = hasher(),
86 			const key_equal& __eql = key_equal(),
87 			const allocator_type& __a = allocator_type())
88 	: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
89 		__detail::_Default_ranged_hash(), __eql,
90 		std::_Identity<value_type>(), __a)
91         { }
92 
93       __unordered_set(initializer_list<value_type> __l,
94 		      size_type __n = 0,
95 		      const hasher& __hf = hasher(),
96 		      const key_equal& __eql = key_equal(),
97 		      const allocator_type& __a = allocator_type())
98       : _Base(__l.begin(), __l.end(), __n, __hf,
99 	      __detail::_Mod_range_hashing(),
100 	      __detail::_Default_ranged_hash(), __eql,
101 	      std::_Identity<value_type>(), __a)
102       { }
103 
104       __unordered_set&
105       operator=(initializer_list<value_type> __l)
106       {
107 	this->clear();
108 	this->insert(__l.begin(), __l.end());
109 	return *this;
110       }
111 
112       using _Base::insert;
113 
114       std::pair<iterator, bool>
115       insert(value_type&& __v)
116       { return this->_M_insert(std::move(__v), std::true_type()); }
117 
118       iterator
119       insert(const_iterator, value_type&& __v)
120       { return insert(std::move(__v)).first; }
121     };
122 
123   template<class _Value,
124 	   class _Hash = hash<_Value>,
125 	   class _Pred = std::equal_to<_Value>,
126 	   class _Alloc = std::allocator<_Value>,
127 	   bool __cache_hash_code =
128 	     __not_<__and_<is_integral<_Value>, is_empty<_Hash>,
129 			   integral_constant<bool, !__is_final(_Hash)>,
130 			   __detail::__is_noexcept_hash<_Value, _Hash>>>::value>
131     class __unordered_multiset
132     : public _Hashtable<_Value, _Value, _Alloc,
133 			std::_Identity<_Value>, _Pred,
134 			_Hash, __detail::_Mod_range_hashing,
135 			__detail::_Default_ranged_hash,
136 			__detail::_Prime_rehash_policy,
137 			__cache_hash_code, true, false>
138     {
139       typedef _Hashtable<_Value, _Value, _Alloc,
140 			 std::_Identity<_Value>, _Pred,
141 			 _Hash, __detail::_Mod_range_hashing,
142 			 __detail::_Default_ranged_hash,
143 			 __detail::_Prime_rehash_policy,
144 			 __cache_hash_code, true, false>
145         _Base;
146 
147     public:
148       typedef typename _Base::value_type      value_type;
149       typedef typename _Base::size_type       size_type;
150       typedef typename _Base::hasher          hasher;
151       typedef typename _Base::key_equal       key_equal;
152       typedef typename _Base::allocator_type  allocator_type;
153       typedef typename _Base::iterator        iterator;
154       typedef typename _Base::const_iterator  const_iterator;
155 
156       explicit
157       __unordered_multiset(size_type __n = 10,
158 			   const hasher& __hf = hasher(),
159 			   const key_equal& __eql = key_equal(),
160 			   const allocator_type& __a = allocator_type())
161       : _Base(__n, __hf, __detail::_Mod_range_hashing(),
162 	      __detail::_Default_ranged_hash(), __eql,
163 	      std::_Identity<value_type>(), __a)
164       { }
165 
166 
167       template<typename _InputIterator>
168         __unordered_multiset(_InputIterator __f, _InputIterator __l,
169 			     size_type __n = 0,
170 			     const hasher& __hf = hasher(),
171 			     const key_equal& __eql = key_equal(),
172 			     const allocator_type& __a = allocator_type())
173 	: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
174 		__detail::_Default_ranged_hash(), __eql,
175 		std::_Identity<value_type>(), __a)
176         { }
177 
178       __unordered_multiset(initializer_list<value_type> __l,
179 			   size_type __n = 0,
180 			   const hasher& __hf = hasher(),
181 			   const key_equal& __eql = key_equal(),
182 			   const allocator_type& __a = allocator_type())
183       : _Base(__l.begin(), __l.end(), __n, __hf,
184 	      __detail::_Mod_range_hashing(),
185 	      __detail::_Default_ranged_hash(), __eql,
186 	      std::_Identity<value_type>(), __a)
187       { }
188 
189       __unordered_multiset&
190       operator=(initializer_list<value_type> __l)
191       {
192 	this->clear();
193 	this->insert(__l.begin(), __l.end());
194 	return *this;
195       }
196 
197       using _Base::insert;
198 
199       iterator
200       insert(value_type&& __v)
201       { return this->_M_insert(std::move(__v), std::false_type()); }
202 
203       iterator
204       insert(const_iterator, value_type&& __v)
205       { return insert(std::move(__v)); }
206     };
207 
208   template<class _Value, class _Hash, class _Pred, class _Alloc,
209 	   bool __cache_hash_code>
210     inline void
211     swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x,
212 	 __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y)
213     { __x.swap(__y); }
214 
215   template<class _Value, class _Hash, class _Pred, class _Alloc,
216 	   bool __cache_hash_code>
217     inline void
218     swap(__unordered_multiset<_Value, _Hash, _Pred,
219 	 _Alloc, __cache_hash_code>& __x,
220 	 __unordered_multiset<_Value, _Hash, _Pred,
221 	 _Alloc, __cache_hash_code>& __y)
222     { __x.swap(__y); }
223 
224   template<class _Value, class _Hash, class _Pred, class _Alloc,
225 	   bool __cache_hash_code>
226     inline bool
227     operator==(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
228 	       __cache_hash_code>& __x,
229 	       const __unordered_set<_Value, _Hash, _Pred, _Alloc,
230 	       __cache_hash_code>& __y)
231     { return __x._M_equal(__y); }
232 
233   template<class _Value, class _Hash, class _Pred, class _Alloc,
234 	   bool __cache_hash_code>
235     inline bool
236     operator!=(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
237 	       __cache_hash_code>& __x,
238 	       const __unordered_set<_Value, _Hash, _Pred, _Alloc,
239 	       __cache_hash_code>& __y)
240     { return !(__x == __y); }
241 
242   template<class _Value, class _Hash, class _Pred, class _Alloc,
243 	   bool __cache_hash_code>
244     inline bool
245     operator==(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
246 	       __cache_hash_code>& __x,
247 	       const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
248 	       __cache_hash_code>& __y)
249     { return __x._M_equal(__y); }
250 
251   template<class _Value, class _Hash, class _Pred, class _Alloc,
252 	   bool __cache_hash_code>
253     inline bool
254     operator!=(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
255 	       __cache_hash_code>& __x,
256 	       const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
257 	       __cache_hash_code>& __y)
258     { return !(__x == __y); }
259 
260   /**
261    *  @brief A standard container composed of unique keys (containing
262    *  at most one of each key value) in which the elements' keys are
263    *  the elements themselves.
264    *
265    *  @ingroup unordered_associative_containers
266    *
267    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
268    *  <a href="tables.html#xx">unordered associative container</a>
269    *
270    *  @param  Value  Type of key objects.
271    *  @param  Hash  Hashing function object type, defaults to hash<Value>.
272    *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
273    *  @param  Alloc  Allocator type, defaults to allocator<Key>.
274    */
275   template<class _Value,
276 	   class _Hash = hash<_Value>,
277 	   class _Pred = std::equal_to<_Value>,
278 	   class _Alloc = std::allocator<_Value> >
279     class unordered_set
280     : public __unordered_set<_Value, _Hash, _Pred, _Alloc>
281     {
282       typedef __unordered_set<_Value, _Hash, _Pred, _Alloc>  _Base;
283 
284     public:
285       typedef typename _Base::value_type      value_type;
286       typedef typename _Base::size_type       size_type;
287       typedef typename _Base::hasher          hasher;
288       typedef typename _Base::key_equal       key_equal;
289       typedef typename _Base::allocator_type  allocator_type;
290 
291       explicit
292       unordered_set(size_type __n = 10,
293 		    const hasher& __hf = hasher(),
294 		    const key_equal& __eql = key_equal(),
295 		    const allocator_type& __a = allocator_type())
296       : _Base(__n, __hf, __eql, __a)
297       { }
298 
299       template<typename _InputIterator>
300         unordered_set(_InputIterator __f, _InputIterator __l,
301 		      size_type __n = 0,
302 		      const hasher& __hf = hasher(),
303 		      const key_equal& __eql = key_equal(),
304 		      const allocator_type& __a = allocator_type())
305 	: _Base(__f, __l, __n, __hf, __eql, __a)
306         { }
307 
308       unordered_set(initializer_list<value_type> __l,
309 		    size_type __n = 0,
310 		    const hasher& __hf = hasher(),
311 		    const key_equal& __eql = key_equal(),
312 		    const allocator_type& __a = allocator_type())
313       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
314       { }
315 
316       unordered_set&
317       operator=(initializer_list<value_type> __l)
318       {
319 	this->clear();
320 	this->insert(__l.begin(), __l.end());
321 	return *this;
322       }
323     };
324 
325   /**
326    *  @brief A standard container composed of equivalent keys
327    *  (possibly containing multiple of each key value) in which the
328    *  elements' keys are the elements themselves.
329    *
330    *  @ingroup unordered_associative_containers
331    *
332    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
333    *  <a href="tables.html#xx">unordered associative container</a>
334    *
335    *  @param  Value  Type of key objects.
336    *  @param  Hash  Hashing function object type, defaults to hash<Value>.
337    *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
338    *  @param  Alloc  Allocator type, defaults to allocator<Key>.
339    */
340   template<class _Value,
341 	   class _Hash = hash<_Value>,
342 	   class _Pred = std::equal_to<_Value>,
343 	   class _Alloc = std::allocator<_Value> >
344     class unordered_multiset
345     : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc>
346     {
347       typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc>  _Base;
348 
349     public:
350       typedef typename _Base::value_type      value_type;
351       typedef typename _Base::size_type       size_type;
352       typedef typename _Base::hasher          hasher;
353       typedef typename _Base::key_equal       key_equal;
354       typedef typename _Base::allocator_type  allocator_type;
355 
356       explicit
357       unordered_multiset(size_type __n = 10,
358 			 const hasher& __hf = hasher(),
359 			 const key_equal& __eql = key_equal(),
360 			 const allocator_type& __a = allocator_type())
361       : _Base(__n, __hf, __eql, __a)
362       { }
363 
364 
365       template<typename _InputIterator>
366         unordered_multiset(_InputIterator __f, _InputIterator __l,
367 			   size_type __n = 0,
368 			   const hasher& __hf = hasher(),
369 			   const key_equal& __eql = key_equal(),
370 			   const allocator_type& __a = allocator_type())
371 	: _Base(__f, __l, __n, __hf, __eql, __a)
372         { }
373 
374       unordered_multiset(initializer_list<value_type> __l,
375 			 size_type __n = 0,
376 			 const hasher& __hf = hasher(),
377 			 const key_equal& __eql = key_equal(),
378 			 const allocator_type& __a = allocator_type())
379       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
380       { }
381 
382       unordered_multiset&
383       operator=(initializer_list<value_type> __l)
384       {
385 	this->clear();
386 	this->insert(__l.begin(), __l.end());
387 	return *this;
388       }
389     };
390 
391   template<class _Value, class _Hash, class _Pred, class _Alloc>
392     inline void
393     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
394 	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
395     { __x.swap(__y); }
396 
397   template<class _Value, class _Hash, class _Pred, class _Alloc>
398     inline void
399     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
400 	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
401     { __x.swap(__y); }
402 
403   template<class _Value, class _Hash, class _Pred, class _Alloc>
404     inline bool
405     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
406 	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
407     { return __x._M_equal(__y); }
408 
409   template<class _Value, class _Hash, class _Pred, class _Alloc>
410     inline bool
411     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
412 	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
413     { return !(__x == __y); }
414 
415   template<class _Value, class _Hash, class _Pred, class _Alloc>
416     inline bool
417     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
418 	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
419     { return __x._M_equal(__y); }
420 
421   template<class _Value, class _Hash, class _Pred, class _Alloc>
422     inline bool
423     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
424 	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
425     { return !(__x == __y); }
426 
427 _GLIBCXX_END_NAMESPACE_CONTAINER
428 } // namespace std
429 
430 #endif /* _UNORDERED_SET_H */
431 
432