1// unordered_set implementation -*- C++ -*-
2
3// Copyright (C) 2010 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 *  You should not attempt to use it directly.
28 */
29
30#ifndef _UNORDERED_SET_H
31#define _UNORDERED_SET_H
32
33_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
34
35  // XXX When we get typedef templates these class definitions
36  // will be unnecessary.
37  template<class _Value,
38	   class _Hash = hash<_Value>,
39	   class _Pred = std::equal_to<_Value>,
40	   class _Alloc = std::allocator<_Value>,
41	   bool __cache_hash_code = false>
42    class __unordered_set
43    : public _Hashtable<_Value, _Value, _Alloc,
44			std::_Identity<_Value>, _Pred,
45			_Hash, __detail::_Mod_range_hashing,
46			__detail::_Default_ranged_hash,
47			__detail::_Prime_rehash_policy,
48			__cache_hash_code, true, true>
49    {
50      typedef _Hashtable<_Value, _Value, _Alloc,
51			 std::_Identity<_Value>, _Pred,
52			 _Hash, __detail::_Mod_range_hashing,
53			 __detail::_Default_ranged_hash,
54			 __detail::_Prime_rehash_policy,
55			 __cache_hash_code, true, true>
56        _Base;
57
58    public:
59      typedef typename _Base::size_type       size_type;
60      typedef typename _Base::hasher          hasher;
61      typedef typename _Base::key_equal       key_equal;
62      typedef typename _Base::allocator_type  allocator_type;
63
64      explicit
65      __unordered_set(size_type __n = 10,
66		      const hasher& __hf = hasher(),
67		      const key_equal& __eql = key_equal(),
68		      const allocator_type& __a = allocator_type())
69      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
70	      __detail::_Default_ranged_hash(), __eql,
71	      std::_Identity<_Value>(), __a)
72      { }
73
74      template<typename _InputIterator>
75        __unordered_set(_InputIterator __f, _InputIterator __l,
76			size_type __n = 10,
77			const hasher& __hf = hasher(),
78			const key_equal& __eql = key_equal(),
79			const allocator_type& __a = allocator_type())
80	: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
81		__detail::_Default_ranged_hash(), __eql,
82		std::_Identity<_Value>(), __a)
83        { }
84
85      __unordered_set(__unordered_set&& __x)
86      : _Base(std::forward<_Base>(__x)) { }
87    };
88
89  template<class _Value,
90	   class _Hash = hash<_Value>,
91	   class _Pred = std::equal_to<_Value>,
92	   class _Alloc = std::allocator<_Value>,
93	   bool __cache_hash_code = false>
94    class __unordered_multiset
95    : public _Hashtable<_Value, _Value, _Alloc,
96			std::_Identity<_Value>, _Pred,
97			_Hash, __detail::_Mod_range_hashing,
98			__detail::_Default_ranged_hash,
99			__detail::_Prime_rehash_policy,
100			__cache_hash_code, true, false>
101    {
102      typedef _Hashtable<_Value, _Value, _Alloc,
103			 std::_Identity<_Value>, _Pred,
104			 _Hash, __detail::_Mod_range_hashing,
105			 __detail::_Default_ranged_hash,
106			 __detail::_Prime_rehash_policy,
107			 __cache_hash_code, true, false>
108        _Base;
109
110    public:
111      typedef typename _Base::size_type       size_type;
112      typedef typename _Base::hasher          hasher;
113      typedef typename _Base::key_equal       key_equal;
114      typedef typename _Base::allocator_type  allocator_type;
115
116      explicit
117      __unordered_multiset(size_type __n = 10,
118			   const hasher& __hf = hasher(),
119			   const key_equal& __eql = key_equal(),
120			   const allocator_type& __a = allocator_type())
121      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
122	      __detail::_Default_ranged_hash(), __eql,
123	      std::_Identity<_Value>(), __a)
124      { }
125
126
127      template<typename _InputIterator>
128        __unordered_multiset(_InputIterator __f, _InputIterator __l,
129			     typename _Base::size_type __n = 0,
130			     const hasher& __hf = hasher(),
131			     const key_equal& __eql = key_equal(),
132			     const allocator_type& __a = allocator_type())
133	: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
134		__detail::_Default_ranged_hash(), __eql,
135		std::_Identity<_Value>(), __a)
136        { }
137
138      __unordered_multiset(__unordered_multiset&& __x)
139      : _Base(std::forward<_Base>(__x)) { }
140    };
141
142  template<class _Value, class _Hash, class _Pred, class _Alloc,
143	   bool __cache_hash_code>
144    inline void
145    swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x,
146	 __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y)
147    { __x.swap(__y); }
148
149  template<class _Value, class _Hash, class _Pred, class _Alloc,
150	   bool __cache_hash_code>
151    inline void
152    swap(__unordered_multiset<_Value, _Hash, _Pred,
153	 _Alloc, __cache_hash_code>& __x,
154	 __unordered_multiset<_Value, _Hash, _Pred,
155	 _Alloc, __cache_hash_code>& __y)
156    { __x.swap(__y); }
157
158  template<class _Value, class _Hash, class _Pred, class _Alloc,
159	   bool __cache_hash_code>
160    inline bool
161    operator==(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
162	       __cache_hash_code>& __x,
163	       const __unordered_set<_Value, _Hash, _Pred, _Alloc,
164	       __cache_hash_code>& __y)
165    { return __x._M_equal(__y); }
166
167  template<class _Value, class _Hash, class _Pred, class _Alloc,
168	   bool __cache_hash_code>
169    inline bool
170    operator!=(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
171	       __cache_hash_code>& __x,
172	       const __unordered_set<_Value, _Hash, _Pred, _Alloc,
173	       __cache_hash_code>& __y)
174    { return !(__x == __y); }
175
176  template<class _Value, class _Hash, class _Pred, class _Alloc,
177	   bool __cache_hash_code>
178    inline bool
179    operator==(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
180	       __cache_hash_code>& __x,
181	       const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
182	       __cache_hash_code>& __y)
183    { return __x._M_equal(__y); }
184
185  template<class _Value, class _Hash, class _Pred, class _Alloc,
186	   bool __cache_hash_code>
187    inline bool
188    operator!=(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
189	       __cache_hash_code>& __x,
190	       const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
191	       __cache_hash_code>& __y)
192    { return !(__x == __y); }
193
194  /**
195   *  @brief A standard container composed of unique keys (containing
196   *  at most one of each key value) in which the elements' keys are
197   *  the elements themselves.
198   *
199   *  @ingroup unordered_associative_containers
200   *
201   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
202   *  <a href="tables.html#xx">unordered associative container</a>
203   *
204   *  @param  Value  Type of key objects.
205   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
206   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
207   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
208   */
209  template<class _Value,
210	   class _Hash = hash<_Value>,
211	   class _Pred = std::equal_to<_Value>,
212	   class _Alloc = std::allocator<_Value> >
213    class unordered_set
214    : public __unordered_set<_Value, _Hash, _Pred, _Alloc>
215    {
216      typedef __unordered_set<_Value, _Hash, _Pred, _Alloc>  _Base;
217
218    public:
219      typedef typename _Base::value_type      value_type;
220      typedef typename _Base::size_type       size_type;
221      typedef typename _Base::hasher          hasher;
222      typedef typename _Base::key_equal       key_equal;
223      typedef typename _Base::allocator_type  allocator_type;
224
225      explicit
226      unordered_set(size_type __n = 10,
227		    const hasher& __hf = hasher(),
228		    const key_equal& __eql = key_equal(),
229		    const allocator_type& __a = allocator_type())
230      : _Base(__n, __hf, __eql, __a)
231      { }
232
233      template<typename _InputIterator>
234        unordered_set(_InputIterator __f, _InputIterator __l,
235		      size_type __n = 10,
236		      const hasher& __hf = hasher(),
237		      const key_equal& __eql = key_equal(),
238		      const allocator_type& __a = allocator_type())
239	: _Base(__f, __l, __n, __hf, __eql, __a)
240        { }
241
242      unordered_set(unordered_set&& __x)
243      : _Base(std::forward<_Base>(__x)) { }
244
245      unordered_set(initializer_list<value_type> __l,
246		    size_type __n = 10,
247		    const hasher& __hf = hasher(),
248		    const key_equal& __eql = key_equal(),
249		    const allocator_type& __a = allocator_type())
250	: _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
251      { }
252
253      unordered_set&
254      operator=(unordered_set&& __x)
255      {
256	// NB: DR 1204.
257	// NB: DR 675.
258	this->clear();
259	this->swap(__x);
260	return *this;
261      }
262
263      unordered_set&
264      operator=(initializer_list<value_type> __l)
265      {
266	this->clear();
267	this->insert(__l.begin(), __l.end());
268	return *this;
269      }
270    };
271
272  /**
273   *  @brief A standard container composed of equivalent keys
274   *  (possibly containing multiple of each key value) in which the
275   *  elements' keys are the elements themselves.
276   *
277   *  @ingroup unordered_associative_containers
278   *
279   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
280   *  <a href="tables.html#xx">unordered associative container</a>
281   *
282   *  @param  Value  Type of key objects.
283   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
284   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
285   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
286   */
287  template<class _Value,
288	   class _Hash = hash<_Value>,
289	   class _Pred = std::equal_to<_Value>,
290	   class _Alloc = std::allocator<_Value> >
291    class unordered_multiset
292    : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc>
293    {
294      typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc>  _Base;
295
296    public:
297      typedef typename _Base::value_type      value_type;
298      typedef typename _Base::size_type       size_type;
299      typedef typename _Base::hasher          hasher;
300      typedef typename _Base::key_equal       key_equal;
301      typedef typename _Base::allocator_type  allocator_type;
302
303      explicit
304      unordered_multiset(size_type __n = 10,
305			 const hasher& __hf = hasher(),
306			 const key_equal& __eql = key_equal(),
307			 const allocator_type& __a = allocator_type())
308      : _Base(__n, __hf, __eql, __a)
309      { }
310
311
312      template<typename _InputIterator>
313        unordered_multiset(_InputIterator __f, _InputIterator __l,
314			   typename _Base::size_type __n = 0,
315			   const hasher& __hf = hasher(),
316			   const key_equal& __eql = key_equal(),
317			   const allocator_type& __a = allocator_type())
318	: _Base(__f, __l, __n, __hf, __eql, __a)
319        { }
320
321      unordered_multiset(unordered_multiset&& __x)
322      : _Base(std::forward<_Base>(__x)) { }
323
324      unordered_multiset(initializer_list<value_type> __l,
325			 size_type __n = 10,
326			 const hasher& __hf = hasher(),
327			 const key_equal& __eql = key_equal(),
328			 const allocator_type& __a = allocator_type())
329	: _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
330      { }
331
332      unordered_multiset&
333      operator=(unordered_multiset&& __x)
334      {
335	// NB: DR 1204.
336	// NB: DR 675.
337	this->clear();
338	this->swap(__x);
339	return *this;
340      }
341
342      unordered_multiset&
343      operator=(initializer_list<value_type> __l)
344      {
345	this->clear();
346	this->insert(__l.begin(), __l.end());
347	return *this;
348      }
349    };
350
351  template<class _Value, class _Hash, class _Pred, class _Alloc>
352    inline void
353    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
354	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
355    { __x.swap(__y); }
356
357  template<class _Value, class _Hash, class _Pred, class _Alloc>
358    inline void
359    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
360	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
361    { __x.swap(__y); }
362
363  template<class _Value, class _Hash, class _Pred, class _Alloc>
364    inline bool
365    operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
366	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
367    { return __x._M_equal(__y); }
368
369  template<class _Value, class _Hash, class _Pred, class _Alloc>
370    inline bool
371    operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
372	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
373    { return !(__x == __y); }
374
375  template<class _Value, class _Hash, class _Pred, class _Alloc>
376    inline bool
377    operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
378	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
379    { return __x._M_equal(__y); }
380
381  template<class _Value, class _Hash, class _Pred, class _Alloc>
382    inline bool
383    operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
384	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
385    { return !(__x == __y); }
386
387_GLIBCXX_END_NESTED_NAMESPACE
388
389#endif /* _UNORDERED_SET_H */
390
391