1// Hashtable implementation used by containers -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/*
27 * Copyright (c) 1996,1997
28 * Silicon Graphics Computer Systems, Inc.
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation.  Silicon Graphics makes no
35 * representations about the suitability of this software for any
36 * purpose.  It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1994
40 * Hewlett-Packard Company
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation.  Hewlett-Packard Company makes no
47 * representations about the suitability of this software for any
48 * purpose.  It is provided "as is" without express or implied warranty.
49 *
50 */
51
52/** @file backward/hashtable.h
53 *  This file is a GNU extension to the Standard C++ Library (possibly
54 *  containing extensions from the HP/SGI STL subset).
55 */
56
57#ifndef _BACKWARD_HASHTABLE_H
58#define _BACKWARD_HASHTABLE_H 1
59
60// Hashtable class, used to implement the hashed associative containers
61// hash_set, hash_map, hash_multiset, and hash_multimap.
62
63#include <vector>
64#include <iterator>
65#include <algorithm>
66#include <bits/stl_function.h>
67#include <backward/hash_fun.h>
68
69namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
70{
71_GLIBCXX_BEGIN_NAMESPACE_VERSION
72
73  using std::size_t;
74  using std::ptrdiff_t;
75  using std::forward_iterator_tag;
76  using std::input_iterator_tag;
77  using std::_Construct;
78  using std::_Destroy;
79  using std::distance;
80  using std::vector;
81  using std::pair;
82  using std::__iterator_category;
83
84  template<class _Val>
85    struct _Hashtable_node
86    {
87      _Hashtable_node* _M_next;
88      _Val _M_val;
89    };
90
91  template<class _Val, class _Key, class _HashFcn, class _ExtractKey,
92	   class _EqualKey, class _Alloc = std::allocator<_Val> >
93    class hashtable;
94
95  template<class _Val, class _Key, class _HashFcn,
96	   class _ExtractKey, class _EqualKey, class _Alloc>
97    struct _Hashtable_iterator;
98
99  template<class _Val, class _Key, class _HashFcn,
100	   class _ExtractKey, class _EqualKey, class _Alloc>
101    struct _Hashtable_const_iterator;
102
103  template<class _Val, class _Key, class _HashFcn,
104	   class _ExtractKey, class _EqualKey, class _Alloc>
105    struct _Hashtable_iterator
106    {
107      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
108        _Hashtable;
109      typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
110				  _ExtractKey, _EqualKey, _Alloc>
111        iterator;
112      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
113					_ExtractKey, _EqualKey, _Alloc>
114        const_iterator;
115      typedef _Hashtable_node<_Val> _Node;
116      typedef forward_iterator_tag iterator_category;
117      typedef _Val value_type;
118      typedef ptrdiff_t difference_type;
119      typedef size_t size_type;
120      typedef _Val& reference;
121      typedef _Val* pointer;
122
123      _Node* _M_cur;
124      _Hashtable* _M_ht;
125
126      _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
127      : _M_cur(__n), _M_ht(__tab) { }
128
129      _Hashtable_iterator() { }
130
131      reference
132      operator*() const
133      { return _M_cur->_M_val; }
134
135      pointer
136      operator->() const
137      { return &(operator*()); }
138
139      iterator&
140      operator++();
141
142      iterator
143      operator++(int);
144
145      bool
146      operator==(const iterator& __it) const
147      { return _M_cur == __it._M_cur; }
148
149      bool
150      operator!=(const iterator& __it) const
151      { return _M_cur != __it._M_cur; }
152    };
153
154  template<class _Val, class _Key, class _HashFcn,
155	   class _ExtractKey, class _EqualKey, class _Alloc>
156    struct _Hashtable_const_iterator
157    {
158      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
159        _Hashtable;
160      typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
161				  _ExtractKey,_EqualKey,_Alloc>
162        iterator;
163      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
164					_ExtractKey, _EqualKey, _Alloc>
165        const_iterator;
166      typedef _Hashtable_node<_Val> _Node;
167
168      typedef forward_iterator_tag iterator_category;
169      typedef _Val value_type;
170      typedef ptrdiff_t difference_type;
171      typedef size_t size_type;
172      typedef const _Val& reference;
173      typedef const _Val* pointer;
174
175      const _Node* _M_cur;
176      const _Hashtable* _M_ht;
177
178      _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
179      : _M_cur(__n), _M_ht(__tab) { }
180
181      _Hashtable_const_iterator() { }
182
183      _Hashtable_const_iterator(const iterator& __it)
184      : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
185
186      reference
187      operator*() const
188      { return _M_cur->_M_val; }
189
190      pointer
191      operator->() const
192      { return &(operator*()); }
193
194      const_iterator&
195      operator++();
196
197      const_iterator
198      operator++(int);
199
200      bool
201      operator==(const const_iterator& __it) const
202      { return _M_cur == __it._M_cur; }
203
204      bool
205      operator!=(const const_iterator& __it) const
206      { return _M_cur != __it._M_cur; }
207    };
208
209  // Note: assumes long is at least 32 bits.
210  enum { _S_num_primes = 29 };
211
212  template<typename _PrimeType>
213    struct _Hashtable_prime_list
214    {
215      static const _PrimeType  __stl_prime_list[_S_num_primes];
216
217      static const _PrimeType*
218      _S_get_prime_list();
219    };
220
221  template<typename _PrimeType> const _PrimeType
222  _Hashtable_prime_list<_PrimeType>::__stl_prime_list[_S_num_primes] =
223    {
224      5ul,          53ul,         97ul,         193ul,       389ul,
225      769ul,        1543ul,       3079ul,       6151ul,      12289ul,
226      24593ul,      49157ul,      98317ul,      196613ul,    393241ul,
227      786433ul,     1572869ul,    3145739ul,    6291469ul,   12582917ul,
228      25165843ul,   50331653ul,   100663319ul,  201326611ul, 402653189ul,
229      805306457ul,  1610612741ul, 3221225473ul, 4294967291ul
230    };
231
232 template<class _PrimeType> inline const _PrimeType*
233 _Hashtable_prime_list<_PrimeType>::_S_get_prime_list()
234 {
235   return __stl_prime_list;
236 }
237
238  inline unsigned long
239  __stl_next_prime(unsigned long __n)
240  {
241    const unsigned long* __first = _Hashtable_prime_list<unsigned long>::_S_get_prime_list();
242    const unsigned long* __last = __first + (int)_S_num_primes;
243    const unsigned long* pos = std::lower_bound(__first, __last, __n);
244    return pos == __last ? *(__last - 1) : *pos;
245  }
246
247  // Forward declaration of operator==.
248  template<class _Val, class _Key, class _HF, class _Ex,
249	   class _Eq, class _All>
250    class hashtable;
251
252  template<class _Val, class _Key, class _HF, class _Ex,
253	   class _Eq, class _All>
254    bool
255    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
256	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
257
258  // Hashtables handle allocators a bit differently than other
259  // containers do.  If we're using standard-conforming allocators, then
260  // a hashtable unconditionally has a member variable to hold its
261  // allocator, even if it so happens that all instances of the
262  // allocator type are identical.  This is because, for hashtables,
263  // this extra storage is negligible.  Additionally, a base class
264  // wouldn't serve any other purposes; it wouldn't, for example,
265  // simplify the exception-handling code.
266  template<class _Val, class _Key, class _HashFcn,
267	   class _ExtractKey, class _EqualKey, class _Alloc>
268    class hashtable
269    {
270    public:
271      typedef _Key key_type;
272      typedef _Val value_type;
273      typedef _HashFcn hasher;
274      typedef _EqualKey key_equal;
275
276      typedef size_t            size_type;
277      typedef ptrdiff_t         difference_type;
278      typedef value_type*       pointer;
279      typedef const value_type* const_pointer;
280      typedef value_type&       reference;
281      typedef const value_type& const_reference;
282
283      hasher
284      hash_funct() const
285      { return _M_hash; }
286
287      key_equal
288      key_eq() const
289      { return _M_equals; }
290
291    private:
292      typedef _Hashtable_node<_Val> _Node;
293
294    public:
295      typedef typename _Alloc::template rebind<value_type>::other allocator_type;
296      allocator_type
297      get_allocator() const
298      { return _M_node_allocator; }
299
300    private:
301      typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
302      typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
303      typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
304
305      _Node_Alloc _M_node_allocator;
306
307      _Node*
308      _M_get_node()
309      { return _M_node_allocator.allocate(1); }
310
311      void
312      _M_put_node(_Node* __p)
313      { _M_node_allocator.deallocate(__p, 1); }
314
315    private:
316      hasher                _M_hash;
317      key_equal             _M_equals;
318      _ExtractKey           _M_get_key;
319      _Vector_type          _M_buckets;
320      size_type             _M_num_elements;
321
322    public:
323      typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
324				  _EqualKey, _Alloc>
325        iterator;
326      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
327					_EqualKey, _Alloc>
328        const_iterator;
329
330      friend struct
331      _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
332
333      friend struct
334      _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
335				_EqualKey, _Alloc>;
336
337    public:
338      hashtable(size_type __n, const _HashFcn& __hf,
339		const _EqualKey& __eql, const _ExtractKey& __ext,
340		const allocator_type& __a = allocator_type())
341      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
342	_M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
343      { _M_initialize_buckets(__n); }
344
345      hashtable(size_type __n, const _HashFcn& __hf,
346		const _EqualKey& __eql,
347		const allocator_type& __a = allocator_type())
348      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
349	_M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
350      { _M_initialize_buckets(__n); }
351
352      hashtable(const hashtable& __ht)
353      : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
354      _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
355      _M_buckets(__ht.get_allocator()), _M_num_elements(0)
356      { _M_copy_from(__ht); }
357
358      hashtable&
359      operator= (const hashtable& __ht)
360      {
361	if (&__ht != this)
362	  {
363	    clear();
364	    _M_hash = __ht._M_hash;
365	    _M_equals = __ht._M_equals;
366	    _M_get_key = __ht._M_get_key;
367	    _M_copy_from(__ht);
368	  }
369	return *this;
370      }
371
372      ~hashtable()
373      { clear(); }
374
375      size_type
376      size() const
377      { return _M_num_elements; }
378
379      size_type
380      max_size() const
381      { return size_type(-1); }
382
383      bool
384      empty() const
385      { return size() == 0; }
386
387      void
388      swap(hashtable& __ht)
389      {
390	std::swap(_M_hash, __ht._M_hash);
391	std::swap(_M_equals, __ht._M_equals);
392	std::swap(_M_get_key, __ht._M_get_key);
393	_M_buckets.swap(__ht._M_buckets);
394	std::swap(_M_num_elements, __ht._M_num_elements);
395      }
396
397      iterator
398      begin()
399      {
400	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
401	  if (_M_buckets[__n])
402	    return iterator(_M_buckets[__n], this);
403	return end();
404      }
405
406      iterator
407      end()
408      { return iterator(0, this); }
409
410      const_iterator
411      begin() const
412      {
413	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
414	  if (_M_buckets[__n])
415	    return const_iterator(_M_buckets[__n], this);
416	return end();
417      }
418
419      const_iterator
420      end() const
421      { return const_iterator(0, this); }
422
423      template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
424		class _Al>
425        friend bool
426        operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
427		   const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
428
429    public:
430      size_type
431      bucket_count() const
432      { return _M_buckets.size(); }
433
434      size_type
435      max_bucket_count() const
436      { return _Hashtable_prime_list<unsigned long>::
437               _S_get_prime_list()[(int)_S_num_primes - 1];
438      }
439
440      size_type
441      elems_in_bucket(size_type __bucket) const
442      {
443	size_type __result = 0;
444	for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
445	  __result += 1;
446	return __result;
447      }
448
449      pair<iterator, bool>
450      insert_unique(const value_type& __obj)
451      {
452	resize(_M_num_elements + 1);
453	return insert_unique_noresize(__obj);
454      }
455
456      iterator
457      insert_equal(const value_type& __obj)
458      {
459	resize(_M_num_elements + 1);
460	return insert_equal_noresize(__obj);
461      }
462
463      pair<iterator, bool>
464      insert_unique_noresize(const value_type& __obj);
465
466      iterator
467      insert_equal_noresize(const value_type& __obj);
468
469      template<class _InputIterator>
470        void
471        insert_unique(_InputIterator __f, _InputIterator __l)
472        { insert_unique(__f, __l, __iterator_category(__f)); }
473
474      template<class _InputIterator>
475        void
476        insert_equal(_InputIterator __f, _InputIterator __l)
477        { insert_equal(__f, __l, __iterator_category(__f)); }
478
479      template<class _InputIterator>
480        void
481        insert_unique(_InputIterator __f, _InputIterator __l,
482		      input_iterator_tag)
483        {
484	  for ( ; __f != __l; ++__f)
485	    insert_unique(*__f);
486	}
487
488      template<class _InputIterator>
489        void
490        insert_equal(_InputIterator __f, _InputIterator __l,
491		     input_iterator_tag)
492        {
493	  for ( ; __f != __l; ++__f)
494	    insert_equal(*__f);
495	}
496
497      template<class _ForwardIterator>
498        void
499        insert_unique(_ForwardIterator __f, _ForwardIterator __l,
500		      forward_iterator_tag)
501        {
502	  size_type __n = distance(__f, __l);
503	  resize(_M_num_elements + __n);
504	  for ( ; __n > 0; --__n, ++__f)
505	    insert_unique_noresize(*__f);
506	}
507
508      template<class _ForwardIterator>
509        void
510        insert_equal(_ForwardIterator __f, _ForwardIterator __l,
511		     forward_iterator_tag)
512        {
513	  size_type __n = distance(__f, __l);
514	  resize(_M_num_elements + __n);
515	  for ( ; __n > 0; --__n, ++__f)
516	    insert_equal_noresize(*__f);
517	}
518
519      reference
520      find_or_insert(const value_type& __obj);
521
522      iterator
523      find(const key_type& __key)
524      {
525	size_type __n = _M_bkt_num_key(__key);
526	_Node* __first;
527	for (__first = _M_buckets[__n];
528	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
529	     __first = __first->_M_next)
530	  { }
531	return iterator(__first, this);
532      }
533
534      const_iterator
535      find(const key_type& __key) const
536      {
537	size_type __n = _M_bkt_num_key(__key);
538	const _Node* __first;
539	for (__first = _M_buckets[__n];
540	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
541	     __first = __first->_M_next)
542	  { }
543	return const_iterator(__first, this);
544      }
545
546      size_type
547      count(const key_type& __key) const
548      {
549	const size_type __n = _M_bkt_num_key(__key);
550	size_type __result = 0;
551
552	for (const _Node* __cur = _M_buckets[__n]; __cur;
553	     __cur = __cur->_M_next)
554	  if (_M_equals(_M_get_key(__cur->_M_val), __key))
555	    ++__result;
556	return __result;
557      }
558
559      pair<iterator, iterator>
560      equal_range(const key_type& __key);
561
562      pair<const_iterator, const_iterator>
563      equal_range(const key_type& __key) const;
564
565      size_type
566      erase(const key_type& __key);
567
568      void
569      erase(const iterator& __it);
570
571      void
572      erase(iterator __first, iterator __last);
573
574      void
575      erase(const const_iterator& __it);
576
577      void
578      erase(const_iterator __first, const_iterator __last);
579
580      void
581      resize(size_type __num_elements_hint);
582
583      void
584      clear();
585
586    private:
587      size_type
588      _M_next_size(size_type __n) const
589      { return __stl_next_prime(__n); }
590
591      void
592      _M_initialize_buckets(size_type __n)
593      {
594	const size_type __n_buckets = _M_next_size(__n);
595	_M_buckets.reserve(__n_buckets);
596	_M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
597	_M_num_elements = 0;
598      }
599
600      size_type
601      _M_bkt_num_key(const key_type& __key) const
602      { return _M_bkt_num_key(__key, _M_buckets.size()); }
603
604      size_type
605      _M_bkt_num(const value_type& __obj) const
606      { return _M_bkt_num_key(_M_get_key(__obj)); }
607
608      size_type
609      _M_bkt_num_key(const key_type& __key, size_t __n) const
610      { return _M_hash(__key) % __n; }
611
612      size_type
613      _M_bkt_num(const value_type& __obj, size_t __n) const
614      { return _M_bkt_num_key(_M_get_key(__obj), __n); }
615
616      _Node*
617      _M_new_node(const value_type& __obj)
618      {
619	_Node* __n = _M_get_node();
620	__n->_M_next = 0;
621	__try
622	  {
623	    this->get_allocator().construct(&__n->_M_val, __obj);
624	    return __n;
625	  }
626	__catch(...)
627	  {
628	    _M_put_node(__n);
629	    __throw_exception_again;
630	  }
631      }
632
633      void
634      _M_delete_node(_Node* __n)
635      {
636	this->get_allocator().destroy(&__n->_M_val);
637	_M_put_node(__n);
638      }
639
640      void
641      _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
642
643      void
644      _M_erase_bucket(const size_type __n, _Node* __last);
645
646      void
647      _M_copy_from(const hashtable& __ht);
648    };
649
650  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
651	    class _All>
652    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
653    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
654    operator++()
655    {
656      const _Node* __old = _M_cur;
657      _M_cur = _M_cur->_M_next;
658      if (!_M_cur)
659	{
660	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
661	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
662	    _M_cur = _M_ht->_M_buckets[__bucket];
663	}
664      return *this;
665    }
666
667  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
668	    class _All>
669    inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
670    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
671    operator++(int)
672    {
673      iterator __tmp = *this;
674      ++*this;
675      return __tmp;
676    }
677
678  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
679	    class _All>
680    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
681    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
682    operator++()
683    {
684      const _Node* __old = _M_cur;
685      _M_cur = _M_cur->_M_next;
686      if (!_M_cur)
687	{
688	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
689	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
690	    _M_cur = _M_ht->_M_buckets[__bucket];
691	}
692      return *this;
693    }
694
695  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
696	    class _All>
697    inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
698    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
699    operator++(int)
700    {
701      const_iterator __tmp = *this;
702      ++*this;
703      return __tmp;
704    }
705
706  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
707    bool
708    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
709	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
710    {
711      typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
712
713      if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
714	return false;
715
716      for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
717	{
718	  _Node* __cur1 = __ht1._M_buckets[__n];
719	  _Node* __cur2 = __ht2._M_buckets[__n];
720	  // Check same length of lists
721	  for (; __cur1 && __cur2;
722	       __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
723	    { }
724	  if (__cur1 || __cur2)
725	    return false;
726	  // Now check one's elements are in the other
727	  for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
728	       __cur1 = __cur1->_M_next)
729	    {
730	      bool _found__cur1 = false;
731	      for (__cur2 = __ht2._M_buckets[__n];
732		   __cur2; __cur2 = __cur2->_M_next)
733		{
734		  if (__cur1->_M_val == __cur2->_M_val)
735		    {
736		      _found__cur1 = true;
737		      break;
738		    }
739		}
740	      if (!_found__cur1)
741		return false;
742	    }
743	}
744      return true;
745    }
746
747  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
748    inline bool
749    operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
750	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
751    { return !(__ht1 == __ht2); }
752
753  template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
754	    class _All>
755    inline void
756    swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
757	 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
758    { __ht1.swap(__ht2); }
759
760  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
761    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
762    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
763    insert_unique_noresize(const value_type& __obj)
764    {
765      const size_type __n = _M_bkt_num(__obj);
766      _Node* __first = _M_buckets[__n];
767
768      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
769	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
770	  return pair<iterator, bool>(iterator(__cur, this), false);
771
772      _Node* __tmp = _M_new_node(__obj);
773      __tmp->_M_next = __first;
774      _M_buckets[__n] = __tmp;
775      ++_M_num_elements;
776      return pair<iterator, bool>(iterator(__tmp, this), true);
777    }
778
779  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
780    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
781    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
782    insert_equal_noresize(const value_type& __obj)
783    {
784      const size_type __n = _M_bkt_num(__obj);
785      _Node* __first = _M_buckets[__n];
786
787      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
788	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
789	  {
790	    _Node* __tmp = _M_new_node(__obj);
791	    __tmp->_M_next = __cur->_M_next;
792	    __cur->_M_next = __tmp;
793	    ++_M_num_elements;
794	    return iterator(__tmp, this);
795	  }
796
797      _Node* __tmp = _M_new_node(__obj);
798      __tmp->_M_next = __first;
799      _M_buckets[__n] = __tmp;
800      ++_M_num_elements;
801      return iterator(__tmp, this);
802    }
803
804  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
805    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
806    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
807    find_or_insert(const value_type& __obj)
808    {
809      resize(_M_num_elements + 1);
810
811      size_type __n = _M_bkt_num(__obj);
812      _Node* __first = _M_buckets[__n];
813
814      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
815	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
816	  return __cur->_M_val;
817
818      _Node* __tmp = _M_new_node(__obj);
819      __tmp->_M_next = __first;
820      _M_buckets[__n] = __tmp;
821      ++_M_num_elements;
822      return __tmp->_M_val;
823    }
824
825  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
826    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
827	 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
828    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
829    equal_range(const key_type& __key)
830    {
831      typedef pair<iterator, iterator> _Pii;
832      const size_type __n = _M_bkt_num_key(__key);
833
834      for (_Node* __first = _M_buckets[__n]; __first;
835	   __first = __first->_M_next)
836	if (_M_equals(_M_get_key(__first->_M_val), __key))
837	  {
838	    for (_Node* __cur = __first->_M_next; __cur;
839		 __cur = __cur->_M_next)
840	      if (!_M_equals(_M_get_key(__cur->_M_val), __key))
841		return _Pii(iterator(__first, this), iterator(__cur, this));
842	    for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
843	      if (_M_buckets[__m])
844		return _Pii(iterator(__first, this),
845			    iterator(_M_buckets[__m], this));
846	    return _Pii(iterator(__first, this), end());
847	  }
848      return _Pii(end(), end());
849    }
850
851  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
852    pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
853	 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
854    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
855    equal_range(const key_type& __key) const
856    {
857      typedef pair<const_iterator, const_iterator> _Pii;
858      const size_type __n = _M_bkt_num_key(__key);
859
860      for (const _Node* __first = _M_buckets[__n]; __first;
861	   __first = __first->_M_next)
862	{
863	  if (_M_equals(_M_get_key(__first->_M_val), __key))
864	    {
865	      for (const _Node* __cur = __first->_M_next; __cur;
866		   __cur = __cur->_M_next)
867		if (!_M_equals(_M_get_key(__cur->_M_val), __key))
868		  return _Pii(const_iterator(__first, this),
869			      const_iterator(__cur, this));
870	      for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
871		if (_M_buckets[__m])
872		  return _Pii(const_iterator(__first, this),
873			      const_iterator(_M_buckets[__m], this));
874	      return _Pii(const_iterator(__first, this), end());
875	    }
876	}
877      return _Pii(end(), end());
878    }
879
880  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
881    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
882    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
883    erase(const key_type& __key)
884    {
885      const size_type __n = _M_bkt_num_key(__key);
886      _Node* __first = _M_buckets[__n];
887      _Node* __saved_slot = 0;
888      size_type __erased = 0;
889
890      if (__first)
891	{
892	  _Node* __cur = __first;
893	  _Node* __next = __cur->_M_next;
894	  while (__next)
895	    {
896	      if (_M_equals(_M_get_key(__next->_M_val), __key))
897		{
898		  if (&_M_get_key(__next->_M_val) != &__key)
899		    {
900		      __cur->_M_next = __next->_M_next;
901		      _M_delete_node(__next);
902		      __next = __cur->_M_next;
903		      ++__erased;
904		      --_M_num_elements;
905		    }
906		  else
907		    {
908		      __saved_slot = __cur;
909		      __cur = __next;
910		      __next = __cur->_M_next;
911		    }
912		}
913	      else
914		{
915		  __cur = __next;
916		  __next = __cur->_M_next;
917		}
918	    }
919	  bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key);
920	  if (__saved_slot)
921	    {
922	      __next = __saved_slot->_M_next;
923	      __saved_slot->_M_next = __next->_M_next;
924	      _M_delete_node(__next);
925	      ++__erased;
926	      --_M_num_elements;
927	    }
928	  if (__delete_first)
929	    {
930	      _M_buckets[__n] = __first->_M_next;
931	      _M_delete_node(__first);
932	      ++__erased;
933	      --_M_num_elements;
934	    }
935	}
936      return __erased;
937    }
938
939  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
940    void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
941    erase(const iterator& __it)
942    {
943      _Node* __p = __it._M_cur;
944      if (__p)
945	{
946	  const size_type __n = _M_bkt_num(__p->_M_val);
947	  _Node* __cur = _M_buckets[__n];
948
949	  if (__cur == __p)
950	    {
951	      _M_buckets[__n] = __cur->_M_next;
952	      _M_delete_node(__cur);
953	      --_M_num_elements;
954	    }
955	  else
956	    {
957	      _Node* __next = __cur->_M_next;
958	      while (__next)
959		{
960		  if (__next == __p)
961		    {
962		      __cur->_M_next = __next->_M_next;
963		      _M_delete_node(__next);
964		      --_M_num_elements;
965		      break;
966		    }
967		  else
968		    {
969		      __cur = __next;
970		      __next = __cur->_M_next;
971		    }
972		}
973	    }
974	}
975    }
976
977  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
978    void
979    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
980    erase(iterator __first, iterator __last)
981    {
982      size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
983	                                    : _M_buckets.size();
984
985      size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
986	                                   : _M_buckets.size();
987
988      if (__first._M_cur == __last._M_cur)
989	return;
990      else if (__f_bucket == __l_bucket)
991	_M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
992      else
993	{
994	  _M_erase_bucket(__f_bucket, __first._M_cur, 0);
995	  for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
996	    _M_erase_bucket(__n, 0);
997	  if (__l_bucket != _M_buckets.size())
998	    _M_erase_bucket(__l_bucket, __last._M_cur);
999	}
1000    }
1001
1002  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1003    inline void
1004    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1005    erase(const_iterator __first, const_iterator __last)
1006    {
1007      erase(iterator(const_cast<_Node*>(__first._M_cur),
1008		     const_cast<hashtable*>(__first._M_ht)),
1009	    iterator(const_cast<_Node*>(__last._M_cur),
1010		     const_cast<hashtable*>(__last._M_ht)));
1011    }
1012
1013  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1014    inline void
1015    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1016    erase(const const_iterator& __it)
1017    { erase(iterator(const_cast<_Node*>(__it._M_cur),
1018		     const_cast<hashtable*>(__it._M_ht))); }
1019
1020  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1021    void
1022    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1023    resize(size_type __num_elements_hint)
1024    {
1025      const size_type __old_n = _M_buckets.size();
1026      if (__num_elements_hint > __old_n)
1027	{
1028	  const size_type __n = _M_next_size(__num_elements_hint);
1029	  if (__n > __old_n)
1030	    {
1031	      _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
1032	      __try
1033		{
1034		  for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
1035		    {
1036		      _Node* __first = _M_buckets[__bucket];
1037		      while (__first)
1038			{
1039			  size_type __new_bucket = _M_bkt_num(__first->_M_val,
1040							      __n);
1041			  _M_buckets[__bucket] = __first->_M_next;
1042			  __first->_M_next = __tmp[__new_bucket];
1043			  __tmp[__new_bucket] = __first;
1044			  __first = _M_buckets[__bucket];
1045			}
1046		    }
1047		  _M_buckets.swap(__tmp);
1048		}
1049	      __catch(...)
1050		{
1051		  for (size_type __bucket = 0; __bucket < __tmp.size();
1052		       ++__bucket)
1053		    {
1054		      while (__tmp[__bucket])
1055			{
1056			  _Node* __next = __tmp[__bucket]->_M_next;
1057			  _M_delete_node(__tmp[__bucket]);
1058			  __tmp[__bucket] = __next;
1059			}
1060		    }
1061		  __throw_exception_again;
1062		}
1063	    }
1064	}
1065    }
1066
1067  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1068    void
1069    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1070    _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
1071    {
1072      _Node* __cur = _M_buckets[__n];
1073      if (__cur == __first)
1074	_M_erase_bucket(__n, __last);
1075      else
1076	{
1077	  _Node* __next;
1078	  for (__next = __cur->_M_next;
1079	       __next != __first;
1080	       __cur = __next, __next = __cur->_M_next)
1081	    ;
1082	  while (__next != __last)
1083	    {
1084	      __cur->_M_next = __next->_M_next;
1085	      _M_delete_node(__next);
1086	      __next = __cur->_M_next;
1087	      --_M_num_elements;
1088	    }
1089	}
1090    }
1091
1092  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1093    void
1094    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1095    _M_erase_bucket(const size_type __n, _Node* __last)
1096    {
1097      _Node* __cur = _M_buckets[__n];
1098      while (__cur != __last)
1099	{
1100	  _Node* __next = __cur->_M_next;
1101	  _M_delete_node(__cur);
1102	  __cur = __next;
1103	  _M_buckets[__n] = __cur;
1104	  --_M_num_elements;
1105	}
1106    }
1107
1108  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1109    void
1110    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1111    clear()
1112    {
1113      if (_M_num_elements == 0)
1114	return;
1115
1116      for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
1117	{
1118	  _Node* __cur = _M_buckets[__i];
1119	  while (__cur != 0)
1120	    {
1121	      _Node* __next = __cur->_M_next;
1122	      _M_delete_node(__cur);
1123	      __cur = __next;
1124	    }
1125	  _M_buckets[__i] = 0;
1126	}
1127      _M_num_elements = 0;
1128    }
1129
1130  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
1131    void
1132    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1133    _M_copy_from(const hashtable& __ht)
1134    {
1135      _M_buckets.clear();
1136      _M_buckets.reserve(__ht._M_buckets.size());
1137      _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
1138      __try
1139	{
1140	  for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
1141	    const _Node* __cur = __ht._M_buckets[__i];
1142	    if (__cur)
1143	      {
1144		_Node* __local_copy = _M_new_node(__cur->_M_val);
1145		_M_buckets[__i] = __local_copy;
1146
1147		for (_Node* __next = __cur->_M_next;
1148		     __next;
1149		     __cur = __next, __next = __cur->_M_next)
1150		  {
1151		    __local_copy->_M_next = _M_new_node(__next->_M_val);
1152		    __local_copy = __local_copy->_M_next;
1153		  }
1154	      }
1155	  }
1156	  _M_num_elements = __ht._M_num_elements;
1157	}
1158      __catch(...)
1159	{
1160	  clear();
1161	  __throw_exception_again;
1162	}
1163    }
1164
1165_GLIBCXX_END_NAMESPACE_VERSION
1166} // namespace
1167
1168#endif
1169