PR c++/64359
[official-gcc.git] / libstdc++-v3 / include / backward / hash_map
blob90019cf6d4a85b9604f0fc3a21377c8cce888d6b
1 // Hashing map implementation -*- C++ -*-
3 // Copyright (C) 2001-2014 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.
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 // 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.
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/>.
26  * Copyright (c) 1996
27  * Silicon Graphics Computer Systems, Inc.
28  *
29  * Permission to use, copy, modify, distribute and sell this software
30  * and its documentation for any purpose is hereby granted without fee,
31  * provided that the above copyright notice appear in all copies and
32  * that both that copyright notice and this permission notice appear
33  * in supporting documentation.  Silicon Graphics makes no
34  * representations about the suitability of this software for any
35  * purpose.  It is provided "as is" without express or implied warranty.
36  *
37  *
38  * Copyright (c) 1994
39  * Hewlett-Packard Company
40  *
41  * Permission to use, copy, modify, distribute and sell this software
42  * and its documentation for any purpose is hereby granted without fee,
43  * provided that the above copyright notice appear in all copies and
44  * that both that copyright notice and this permission notice appear
45  * in supporting documentation.  Hewlett-Packard Company makes no
46  * representations about the suitability of this software for any
47  * purpose.  It is provided "as is" without express or implied warranty.
48  *
49  */
51 /** @file backward/hash_map
52  *  This file is a GNU extension to the Standard C++ Library (possibly
53  *  containing extensions from the HP/SGI STL subset).
54  */
56 #ifndef _BACKWARD_HASH_MAP
57 #define _BACKWARD_HASH_MAP 1
59 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
60 #include "backward_warning.h"
61 #endif
63 #include <bits/c++config.h>
64 #include <backward/hashtable.h>
65 #include <bits/concept_check.h>
67 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
69 _GLIBCXX_BEGIN_NAMESPACE_VERSION
71   using std::equal_to;
72   using std::allocator;
73   using std::pair;
74   using std::_Select1st;
76   /**
77    *  This is an SGI extension.
78    *  @ingroup SGIextensions
79    *  @doctodo
80    */
81   template<class _Key, class _Tp, class _HashFn = hash<_Key>,
82            class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
83     class hash_map
84     {
85     private:
86       typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
87                         _Select1st<pair<const _Key, _Tp> >,
88                         _EqualKey, _Alloc> _Ht;
90       _Ht _M_ht;
92     public:
93       typedef typename _Ht::key_type key_type;
94       typedef _Tp data_type;
95       typedef _Tp mapped_type;
96       typedef typename _Ht::value_type value_type;
97       typedef typename _Ht::hasher hasher;
98       typedef typename _Ht::key_equal key_equal;
99       
100       typedef typename _Ht::size_type size_type;
101       typedef typename _Ht::difference_type difference_type;
102       typedef typename _Ht::pointer pointer;
103       typedef typename _Ht::const_pointer const_pointer;
104       typedef typename _Ht::reference reference;
105       typedef typename _Ht::const_reference const_reference;
106       
107       typedef typename _Ht::iterator iterator;
108       typedef typename _Ht::const_iterator const_iterator;
109       
110       typedef typename _Ht::allocator_type allocator_type;
111       
112       hasher
113       hash_funct() const
114       { return _M_ht.hash_funct(); }
116       key_equal
117       key_eq() const
118       { return _M_ht.key_eq(); }
120       allocator_type
121       get_allocator() const
122       { return _M_ht.get_allocator(); }
124       hash_map()
125       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
126   
127       explicit
128       hash_map(size_type __n)
129       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
131       hash_map(size_type __n, const hasher& __hf)
132       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
134       hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
135                const allocator_type& __a = allocator_type())
136       : _M_ht(__n, __hf, __eql, __a) {}
138       template<class _InputIterator>
139         hash_map(_InputIterator __f, _InputIterator __l)
140         : _M_ht(100, hasher(), key_equal(), allocator_type())
141         { _M_ht.insert_unique(__f, __l); }
143       template<class _InputIterator>
144         hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
145         : _M_ht(__n, hasher(), key_equal(), allocator_type())
146         { _M_ht.insert_unique(__f, __l); }
148       template<class _InputIterator>
149         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
150                  const hasher& __hf)
151         : _M_ht(__n, __hf, key_equal(), allocator_type())
152         { _M_ht.insert_unique(__f, __l); }
154       template<class _InputIterator>
155         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
156                  const hasher& __hf, const key_equal& __eql,
157                  const allocator_type& __a = allocator_type())
158         : _M_ht(__n, __hf, __eql, __a)
159         { _M_ht.insert_unique(__f, __l); }
161       size_type
162       size() const
163       { return _M_ht.size(); }
164       
165       size_type
166       max_size() const
167       { return _M_ht.max_size(); }
168       
169       bool
170       empty() const
171       { return _M_ht.empty(); }
172   
173       void
174       swap(hash_map& __hs)
175       { _M_ht.swap(__hs._M_ht); }
177       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
178         friend bool
179         operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
180                     const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
182       iterator
183       begin()
184       { return _M_ht.begin(); }
186       iterator
187       end()
188       { return _M_ht.end(); }
190       const_iterator
191       begin() const
192       { return _M_ht.begin(); }
194       const_iterator
195       end() const
196       { return _M_ht.end(); }
198       pair<iterator, bool>
199       insert(const value_type& __obj)
200       { return _M_ht.insert_unique(__obj); }
202       template<class _InputIterator>
203         void
204         insert(_InputIterator __f, _InputIterator __l)
205         { _M_ht.insert_unique(__f, __l); }
207       pair<iterator, bool>
208       insert_noresize(const value_type& __obj)
209       { return _M_ht.insert_unique_noresize(__obj); }
211       iterator
212       find(const key_type& __key)
213       { return _M_ht.find(__key); }
215       const_iterator
216       find(const key_type& __key) const
217       { return _M_ht.find(__key); }
219       _Tp&
220       operator[](const key_type& __key)
221       { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
223       size_type
224       count(const key_type& __key) const
225       { return _M_ht.count(__key); }
227       pair<iterator, iterator>
228       equal_range(const key_type& __key)
229       { return _M_ht.equal_range(__key); }
231       pair<const_iterator, const_iterator>
232       equal_range(const key_type& __key) const
233       { return _M_ht.equal_range(__key); }
235       size_type
236       erase(const key_type& __key)
237       {return _M_ht.erase(__key); }
239       void
240       erase(iterator __it)
241       { _M_ht.erase(__it); }
243       void
244       erase(iterator __f, iterator __l)
245       { _M_ht.erase(__f, __l); }
247       void
248       clear()
249       { _M_ht.clear(); }
251       void
252       resize(size_type __hint)
253       { _M_ht.resize(__hint); }
255       size_type
256       bucket_count() const
257       { return _M_ht.bucket_count(); }
259       size_type
260       max_bucket_count() const
261       { return _M_ht.max_bucket_count(); }
263       size_type
264       elems_in_bucket(size_type __n) const
265       { return _M_ht.elems_in_bucket(__n); }
266     };
268   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
269     inline bool
270     operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
271                const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
272     { return __hm1._M_ht == __hm2._M_ht; }
274   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
275     inline bool
276     operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
277                const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
278     { return !(__hm1 == __hm2); }
280   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
281     inline void
282     swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
283          hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
284     { __hm1.swap(__hm2); }
287   /**
288    *  This is an SGI extension.
289    *  @ingroup SGIextensions
290    *  @doctodo
291    */
292   template<class _Key, class _Tp,
293            class _HashFn = hash<_Key>,
294            class _EqualKey = equal_to<_Key>,
295            class _Alloc = allocator<_Tp> >
296     class hash_multimap
297     {
298       // concept requirements
299       __glibcxx_class_requires(_Key, _SGIAssignableConcept)
300       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
301       __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept)
302       __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept)
303         
304     private:
305       typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
306                         _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
307           _Ht;
309       _Ht _M_ht;
311     public:
312       typedef typename _Ht::key_type key_type;
313       typedef _Tp data_type;
314       typedef _Tp mapped_type;
315       typedef typename _Ht::value_type value_type;
316       typedef typename _Ht::hasher hasher;
317       typedef typename _Ht::key_equal key_equal;
318       
319       typedef typename _Ht::size_type size_type;
320       typedef typename _Ht::difference_type difference_type;
321       typedef typename _Ht::pointer pointer;
322       typedef typename _Ht::const_pointer const_pointer;
323       typedef typename _Ht::reference reference;
324       typedef typename _Ht::const_reference const_reference;
325       
326       typedef typename _Ht::iterator iterator;
327       typedef typename _Ht::const_iterator const_iterator;
328       
329       typedef typename _Ht::allocator_type allocator_type;
330       
331       hasher
332       hash_funct() const
333       { return _M_ht.hash_funct(); }
335       key_equal
336       key_eq() const
337       { return _M_ht.key_eq(); }
339       allocator_type
340       get_allocator() const
341       { return _M_ht.get_allocator(); }
343       hash_multimap()
344       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
346       explicit
347       hash_multimap(size_type __n)
348       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
350       hash_multimap(size_type __n, const hasher& __hf)
351       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
353       hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
354                     const allocator_type& __a = allocator_type())
355       : _M_ht(__n, __hf, __eql, __a) {}
357       template<class _InputIterator>
358         hash_multimap(_InputIterator __f, _InputIterator __l)
359         : _M_ht(100, hasher(), key_equal(), allocator_type())
360         { _M_ht.insert_equal(__f, __l); }
362       template<class _InputIterator>
363         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
364         : _M_ht(__n, hasher(), key_equal(), allocator_type())
365         { _M_ht.insert_equal(__f, __l); }
367       template<class _InputIterator>
368         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
369                       const hasher& __hf)
370         : _M_ht(__n, __hf, key_equal(), allocator_type())
371         { _M_ht.insert_equal(__f, __l); }
373       template<class _InputIterator>
374         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
375                       const hasher& __hf, const key_equal& __eql,
376                       const allocator_type& __a = allocator_type())
377         : _M_ht(__n, __hf, __eql, __a)
378         { _M_ht.insert_equal(__f, __l); }
380       size_type
381       size() const
382       { return _M_ht.size(); }
384       size_type
385       max_size() const
386       { return _M_ht.max_size(); }
388       bool
389       empty() const
390       { return _M_ht.empty(); }
392       void
393       swap(hash_multimap& __hs)
394       { _M_ht.swap(__hs._M_ht); }
396       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
397         friend bool
398         operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
399                    const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
401       iterator
402       begin()
403       { return _M_ht.begin(); }
405       iterator
406       end()
407       { return _M_ht.end(); }
409       const_iterator
410       begin() const
411       { return _M_ht.begin(); }
413       const_iterator
414       end() const
415       { return _M_ht.end(); }
417       iterator
418       insert(const value_type& __obj)
419       { return _M_ht.insert_equal(__obj); }
421       template<class _InputIterator>
422         void
423         insert(_InputIterator __f, _InputIterator __l)
424         { _M_ht.insert_equal(__f,__l); }
426       iterator
427       insert_noresize(const value_type& __obj)
428       { return _M_ht.insert_equal_noresize(__obj); }
430       iterator
431       find(const key_type& __key)
432       { return _M_ht.find(__key); }
434       const_iterator
435       find(const key_type& __key) const
436       { return _M_ht.find(__key); }
438       size_type
439       count(const key_type& __key) const
440       { return _M_ht.count(__key); }
442       pair<iterator, iterator>
443       equal_range(const key_type& __key)
444       { return _M_ht.equal_range(__key); }
446       pair<const_iterator, const_iterator>
447       equal_range(const key_type& __key) const
448       { return _M_ht.equal_range(__key); }
450       size_type
451       erase(const key_type& __key)
452       { return _M_ht.erase(__key); }
454       void
455       erase(iterator __it)
456       { _M_ht.erase(__it); }
458       void
459       erase(iterator __f, iterator __l)
460       { _M_ht.erase(__f, __l); }
462       void
463       clear()
464       { _M_ht.clear(); }
466       void
467       resize(size_type __hint)
468       { _M_ht.resize(__hint); }
470       size_type
471       bucket_count() const
472       { return _M_ht.bucket_count(); }
474       size_type
475       max_bucket_count() const
476       { return _M_ht.max_bucket_count(); }
477       
478       size_type
479       elems_in_bucket(size_type __n) const
480       { return _M_ht.elems_in_bucket(__n); }
481     };
483   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
484     inline bool
485     operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
486                const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
487     { return __hm1._M_ht == __hm2._M_ht; }
489   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
490     inline bool
491     operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
492                const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
493     { return !(__hm1 == __hm2); }
495   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
496     inline void
497     swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
498          hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
499     { __hm1.swap(__hm2); }
501 _GLIBCXX_END_NAMESPACE_VERSION
502 } // namespace
504 namespace std _GLIBCXX_VISIBILITY(default)
506 _GLIBCXX_BEGIN_NAMESPACE_VERSION
508   // Specialization of insert_iterator so that it will work for hash_map
509   // and hash_multimap.
510   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
511     class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, 
512                                               _EqKey, _Alloc> >
513     {
514     protected:
515       typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
516         _Container;
517       _Container* container;
519     public:
520       typedef _Container          container_type;
521       typedef output_iterator_tag iterator_category;
522       typedef void                value_type;
523       typedef void                difference_type;
524       typedef void                pointer;
525       typedef void                reference;
526       
527       insert_iterator(_Container& __x)
528       : container(&__x) {}
530       insert_iterator(_Container& __x, typename _Container::iterator)
531       : container(&__x) {}
533       insert_iterator<_Container>&
534       operator=(const typename _Container::value_type& __value)
535       {
536         container->insert(__value);
537         return *this;
538       }
540       insert_iterator<_Container>&
541       operator*()
542       { return *this; }
544       insert_iterator<_Container>&
545       operator++() { return *this; }
547       insert_iterator<_Container>&
548       operator++(int)
549       { return *this; }
550     };
552   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
553     class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
554                                                    _EqKey, _Alloc> >
555     {
556     protected:
557       typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
558         _Container;
559       _Container* container;
560       typename _Container::iterator iter;
562     public:
563       typedef _Container          container_type;
564       typedef output_iterator_tag iterator_category;
565       typedef void                value_type;
566       typedef void                difference_type;
567       typedef void                pointer;
568       typedef void                reference;
570       insert_iterator(_Container& __x)
571       : container(&__x) {}
573       insert_iterator(_Container& __x, typename _Container::iterator)
574       : container(&__x) {}
576       insert_iterator<_Container>&
577       operator=(const typename _Container::value_type& __value)
578       {
579         container->insert(__value);
580         return *this;
581       }
583       insert_iterator<_Container>&
584       operator*()
585       { return *this; }
587       insert_iterator<_Container>&
588       operator++()
589       { return *this; }
591       insert_iterator<_Container>&
592       operator++(int)
593       { return *this; }
594     };
596 _GLIBCXX_END_NAMESPACE_VERSION
597 } // namespace
599 #endif