summaryrefslogtreecommitdiff
path: root/gcc/hash-table.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/hash-table.h')
-rw-r--r--gcc/hash-table.h590
1 files changed, 27 insertions, 563 deletions
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 447eaff1b1c..f6375d1ec71 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -278,7 +278,6 @@ struct pointer_hash : typed_noop_remove <Type>
{
typedef Type *value_type;
typedef Type *compare_type;
- typedef int store_values_directly;
static inline hashval_t hash (const value_type &);
@@ -310,7 +309,6 @@ struct ggc_hasher
{
typedef T value_type;
typedef T compare_type;
- typedef int store_values_directly;
static void remove (T) {}
@@ -342,7 +340,6 @@ struct ggc_cache_hasher
{
typedef T value_type;
typedef T compare_type;
- typedef int store_values_directly;
static void remove (T &) {}
@@ -438,26 +435,6 @@ hash_table_mod2 (hashval_t hash, unsigned int index)
return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
}
-/* The below is some template meta programming to decide if we should use the
- hash table partial specialization that directly stores value_type instead of
- pointers to value_type. If the Descriptor type defines the type
- Descriptor::store_values_directly then values are stored directly otherwise
- pointers to them are stored. */
-template<typename T> struct notype { typedef void type; };
-
-template<typename T, typename = void>
-struct storage_tester
-{
- static const bool value = false;
-};
-
-template<typename T>
-struct storage_tester<T, typename notype<typename
- T::store_values_directly>::type>
-{
- static const bool value = true;
-};
-
template<typename Traits>
struct has_is_deleted
{
@@ -576,9 +553,7 @@ struct mark_empty_helper<Type *, Traits, false>
/* User-facing hash table type.
- The table stores elements of type Descriptor::value_type, or pointers to
- objects of type value_type if the descriptor does not define the type
- store_values_directly.
+ The table stores elements of type Descriptor::value_type.
It hashes values with the hash member function.
The table currently works with relatively weak hash functions.
@@ -601,518 +576,9 @@ struct mark_empty_helper<Type *, Traits, false>
*/
template <typename Descriptor,
- template<typename Type> class Allocator= xcallocator,
- bool Storage = storage_tester<Descriptor>::value>
+ template<typename Type> class Allocator = xcallocator>
class hash_table
{
-};
-
-template <typename Descriptor,
- template<typename Type> class Allocator>
-class hash_table<Descriptor, Allocator, false>
-{
- typedef typename Descriptor::value_type value_type;
- typedef typename Descriptor::compare_type compare_type;
-
-public:
- hash_table (size_t CXX_MEM_STAT_INFO);
- ~hash_table ();
-
- /* Current size (in entries) of the hash table. */
- size_t size () const { return m_size; }
-
- /* Return the current number of elements in this hash table. */
- size_t elements () const { return m_n_elements - m_n_deleted; }
-
- /* Return the current number of elements in this hash table. */
- size_t elements_with_deleted () const { return m_n_elements; }
-
- /* This function clears all entries in the given hash table. */
- void empty ();
-
- /* This function clears a specified SLOT in a hash table. It is
- useful when you've already done the lookup and don't want to do it
- again. */
-
- void clear_slot (value_type **);
-
- /* This function searches for a hash table entry equal to the given
- COMPARABLE element starting with the given HASH value. It cannot
- be used to insert or delete an element. */
- value_type *find_with_hash (const compare_type *, hashval_t);
-
-/* Like find_slot_with_hash, but compute the hash value from the element. */
- value_type *find (const value_type *value)
- {
- return find_with_hash (value, Descriptor::hash (value));
- }
-
- value_type **find_slot (const value_type *value, insert_option insert)
- {
- return find_slot_with_hash (value, Descriptor::hash (value), insert);
- }
-
- /* This function searches for a hash table slot containing an entry
- equal to the given COMPARABLE element and starting with the given
- HASH. To delete an entry, call this with insert=NO_INSERT, then
- call clear_slot on the slot returned (possibly after doing some
- checks). To insert an entry, call this with insert=INSERT, then
- write the value you want into the returned slot. When inserting an
- entry, NULL may be returned if memory allocation fails. */
- value_type **find_slot_with_hash (const compare_type *comparable,
- hashval_t hash, enum insert_option insert);
-
- /* This function deletes an element with the given COMPARABLE value
- from hash table starting with the given HASH. If there is no
- matching element in the hash table, this function does nothing. */
- void remove_elt_with_hash (const compare_type *, hashval_t);
-
-/* Like remove_elt_with_hash, but compute the hash value from the element. */
- void remove_elt (const value_type *value)
- {
- remove_elt_with_hash (value, Descriptor::hash (value));
- }
-
- /* This function scans over the entire hash table calling CALLBACK for
- each live entry. If CALLBACK returns false, the iteration stops.
- ARGUMENT is passed as CALLBACK's second argument. */
- template <typename Argument,
- int (*Callback) (value_type **slot, Argument argument)>
- void traverse_noresize (Argument argument);
-
- /* Like traverse_noresize, but does resize the table when it is too empty
- to improve effectivity of subsequent calls. */
- template <typename Argument,
- int (*Callback) (value_type **slot, Argument argument)>
- void traverse (Argument argument);
-
- class iterator
- {
- public:
- iterator () : m_slot (NULL), m_limit (NULL) {}
-
- iterator (value_type **slot, value_type **limit) :
- m_slot (slot), m_limit (limit) {}
-
- inline value_type *operator * () { return *m_slot; }
- void slide ();
- inline iterator &operator ++ ();
- bool operator != (const iterator &other) const
- {
- return m_slot != other.m_slot || m_limit != other.m_limit;
- }
-
- private:
- value_type **m_slot;
- value_type **m_limit;
- };
-
- iterator begin () const
- {
- iterator iter (m_entries, m_entries + m_size);
- iter.slide ();
- return iter;
- }
-
- iterator end () const { return iterator (); }
-
- double collisions () const
- {
- return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
- }
-
-private:
-
- value_type **find_empty_slot_for_expand (hashval_t);
- void expand ();
-
- /* Table itself. */
- typename Descriptor::value_type **m_entries;
-
- size_t m_size;
-
- /* Current number of elements including also deleted elements. */
- size_t m_n_elements;
-
- /* Current number of deleted elements in the table. */
- size_t m_n_deleted;
-
- /* The following member is used for debugging. Its value is number
- of all calls of `htab_find_slot' for the hash table. */
- unsigned int m_searches;
-
- /* The following member is used for debugging. Its value is number
- of collisions fixed for time of work with the hash table. */
- unsigned int m_collisions;
-
- /* Current size (in entries) of the hash table, as an index into the
- table of primes. */
- unsigned int m_size_prime_index;
-};
-
-template<typename Descriptor, template<typename Type> class Allocator>
-hash_table<Descriptor, Allocator, false>::hash_table (size_t size
- MEM_STAT_DECL) :
- m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0)
-{
- unsigned int size_prime_index;
-
- size_prime_index = hash_table_higher_prime_index (size);
- size = prime_tab[size_prime_index].prime;
-
- m_entries = Allocator <value_type*> ::data_alloc (size);
- gcc_assert (m_entries != NULL);
- m_size = size;
- m_size_prime_index = size_prime_index;
-}
-
-template<typename Descriptor, template<typename Type> class Allocator>
-hash_table<Descriptor, Allocator, false>::~hash_table ()
-{
- for (size_t i = m_size - 1; i < m_size; i--)
- if (m_entries[i] != HTAB_EMPTY_ENTRY && m_entries[i] != HTAB_DELETED_ENTRY)
- Descriptor::remove (m_entries[i]);
-
- Allocator <value_type *> ::data_free (m_entries);
-}
-
-/* Similar to find_slot, but without several unwanted side effects:
- - Does not call equal when it finds an existing entry.
- - Does not change the count of elements/searches/collisions in the
- hash table.
- This function also assumes there are no deleted entries in the table.
- HASH is the hash value for the element to be inserted. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, false>::value_type **
-hash_table<Descriptor, Allocator, false>
-::find_empty_slot_for_expand (hashval_t hash)
-{
- hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
- size_t size = m_size;
- value_type **slot = m_entries + index;
- hashval_t hash2;
-
- if (*slot == HTAB_EMPTY_ENTRY)
- return slot;
- gcc_checking_assert (*slot != HTAB_DELETED_ENTRY);
-
- hash2 = hash_table_mod2 (hash, m_size_prime_index);
- for (;;)
- {
- index += hash2;
- if (index >= size)
- index -= size;
-
- slot = m_entries + index;
- if (*slot == HTAB_EMPTY_ENTRY)
- return slot;
- gcc_checking_assert (*slot != HTAB_DELETED_ENTRY);
- }
-}
-
-/* The following function changes size of memory allocated for the
- entries and repeatedly inserts the table elements. The occupancy
- of the table after the call will be about 50%. Naturally the hash
- table must already exist. Remember also that the place of the
- table entries is changed. If memory allocation fails, this function
- will abort. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Allocator, false>::expand ()
-{
- value_type **oentries = m_entries;
- unsigned int oindex = m_size_prime_index;
- size_t osize = size ();
- value_type **olimit = oentries + osize;
- size_t elts = elements ();
-
- /* Resize only when table after removal of unused elements is either
- too full or too empty. */
- unsigned int nindex;
- size_t nsize;
- if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
- {
- nindex = hash_table_higher_prime_index (elts * 2);
- nsize = prime_tab[nindex].prime;
- }
- else
- {
- nindex = oindex;
- nsize = osize;
- }
-
- value_type **nentries = Allocator <value_type *> ::data_alloc (nsize);
- gcc_assert (nentries != NULL);
- m_entries = nentries;
- m_size = nsize;
- m_size_prime_index = nindex;
- m_n_elements -= m_n_deleted;
- m_n_deleted = 0;
-
- value_type **p = oentries;
- do
- {
- value_type *x = *p;
-
- if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
- {
- value_type **q = find_empty_slot_for_expand (Descriptor::hash (x));
-
- *q = x;
- }
-
- p++;
- }
- while (p < olimit);
-
- Allocator <value_type *> ::data_free (oentries);
-}
-
-template<typename Descriptor, template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Allocator, false>::empty ()
-{
- size_t size = m_size;
- value_type **entries = m_entries;
- int i;
-
- for (i = size - 1; i >= 0; i--)
- if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
- Descriptor::remove (entries[i]);
-
- /* Instead of clearing megabyte, downsize the table. */
- if (size > 1024*1024 / sizeof (PTR))
- {
- int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
- int nsize = prime_tab[nindex].prime;
-
- Allocator <value_type *> ::data_free (m_entries);
- m_entries = Allocator <value_type *> ::data_alloc (nsize);
- m_size = nsize;
- m_size_prime_index = nindex;
- }
- else
- memset (entries, 0, size * sizeof (value_type *));
- m_n_deleted = 0;
- m_n_elements = 0;
-}
-
-/* This function clears a specified SLOT in a hash table. It is
- useful when you've already done the lookup and don't want to do it
- again. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Allocator, false>::clear_slot (value_type **slot)
-{
- gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
- || *slot == HTAB_EMPTY_ENTRY
- || *slot == HTAB_DELETED_ENTRY));
-
- Descriptor::remove (*slot);
-
- *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
- m_n_deleted++;
-}
-
-/* This function searches for a hash table entry equal to the given
- COMPARABLE element starting with the given HASH value. It cannot
- be used to insert or delete an element. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, false>::value_type *
-hash_table<Descriptor, Allocator, false>
-::find_with_hash (const compare_type *comparable, hashval_t hash)
-{
- m_searches++;
- size_t size = m_size;
- hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
-
- value_type *entry = m_entries[index];
- if (entry == HTAB_EMPTY_ENTRY
- || (entry != HTAB_DELETED_ENTRY && Descriptor::equal (entry, comparable)))
- return entry;
-
- hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
- for (;;)
- {
- m_collisions++;
- index += hash2;
- if (index >= size)
- index -= size;
-
- entry = m_entries[index];
- if (entry == HTAB_EMPTY_ENTRY
- || (entry != HTAB_DELETED_ENTRY
- && Descriptor::equal (entry, comparable)))
- return entry;
- }
-}
-
-/* This function searches for a hash table slot containing an entry
- equal to the given COMPARABLE element and starting with the given
- HASH. To delete an entry, call this with insert=NO_INSERT, then
- call clear_slot on the slot returned (possibly after doing some
- checks). To insert an entry, call this with insert=INSERT, then
- write the value you want into the returned slot. When inserting an
- entry, NULL may be returned if memory allocation fails. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, false>::value_type **
-hash_table<Descriptor, Allocator, false>
-::find_slot_with_hash (const compare_type *comparable, hashval_t hash,
- enum insert_option insert)
-{
- if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
- expand ();
-
- m_searches++;
-
- value_type **first_deleted_slot = NULL;
- hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
- hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
- value_type *entry = m_entries[index];
- size_t size = m_size;
- if (entry == HTAB_EMPTY_ENTRY)
- goto empty_entry;
- else if (entry == HTAB_DELETED_ENTRY)
- first_deleted_slot = &m_entries[index];
- else if (Descriptor::equal (entry, comparable))
- return &m_entries[index];
-
- for (;;)
- {
- m_collisions++;
- index += hash2;
- if (index >= size)
- index -= size;
-
- entry = m_entries[index];
- if (entry == HTAB_EMPTY_ENTRY)
- goto empty_entry;
- else if (entry == HTAB_DELETED_ENTRY)
- {
- if (!first_deleted_slot)
- first_deleted_slot = &m_entries[index];
- }
- else if (Descriptor::equal (entry, comparable))
- return &m_entries[index];
- }
-
- empty_entry:
- if (insert == NO_INSERT)
- return NULL;
-
- if (first_deleted_slot)
- {
- m_n_deleted--;
- *first_deleted_slot = static_cast <value_type *> (HTAB_EMPTY_ENTRY);
- return first_deleted_slot;
- }
-
- m_n_elements++;
- return &m_entries[index];
-}
-
-/* This function deletes an element with the given COMPARABLE value
- from hash table starting with the given HASH. If there is no
- matching element in the hash table, this function does nothing. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Allocator, false>
-::remove_elt_with_hash (const compare_type *comparable, hashval_t hash)
-{
- value_type **slot = find_slot_with_hash (comparable, hash, NO_INSERT);
- if (*slot == HTAB_EMPTY_ENTRY)
- return;
-
- Descriptor::remove (*slot);
-
- *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
- m_n_deleted++;
-}
-
-/* This function scans over the entire hash table calling CALLBACK for
- each live entry. If CALLBACK returns false, the iteration stops.
- ARGUMENT is passed as CALLBACK's second argument. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-template<typename Argument,
- int (*Callback) (typename hash_table<Descriptor, Allocator,
- false>::value_type **slot,
- Argument argument)>
-void
-hash_table<Descriptor, Allocator, false>::traverse_noresize (Argument argument)
-{
- value_type **slot = m_entries;
- value_type **limit = slot + size ();
-
- do
- {
- value_type *x = *slot;
-
- if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
- if (! Callback (slot, argument))
- break;
- }
- while (++slot < limit);
-}
-
-/* Like traverse_noresize, but does resize the table when it is too empty
- to improve effectivity of subsequent calls. */
-
-template <typename Descriptor,
- template <typename Type> class Allocator>
-template <typename Argument,
- int (*Callback) (typename hash_table<Descriptor, Allocator,
- false>::value_type **slot,
- Argument argument)>
-void
-hash_table<Descriptor, Allocator, false>::traverse (Argument argument)
-{
- size_t size = m_size;
- if (elements () * 8 < size && size > 32)
- expand ();
-
- traverse_noresize <Argument, Callback> (argument);
-}
-
-/* Slide down the iterator slots until an active entry is found. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Allocator, false>::iterator::slide ()
-{
- for ( ; m_slot < m_limit; ++m_slot )
- {
- value_type *x = *m_slot;
- if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
- return;
- }
- m_slot = NULL;
- m_limit = NULL;
-}
-
-/* Bump the iterator. */
-
-template<typename Descriptor, template<typename Type> class Allocator>
-inline typename hash_table<Descriptor, Allocator, false>::iterator &
-hash_table<Descriptor, Allocator, false>::iterator::operator ++ ()
-{
- ++m_slot;
- slide ();
- return *this;
-}
-
-/* A partial specialization used when values should be stored directly. */
-
-template <typename Descriptor,
- template<typename Type> class Allocator>
-class hash_table<Descriptor, Allocator, true>
-{
typedef typename Descriptor::value_type value_type;
typedef typename Descriptor::compare_type compare_type;
@@ -1296,7 +762,7 @@ private:
};
template<typename Descriptor, template<typename Type> class Allocator>
-hash_table<Descriptor, Allocator, true>::hash_table (size_t size, bool ggc
+hash_table<Descriptor, Allocator>::hash_table (size_t size, bool ggc
MEM_STAT_DECL) :
m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0),
m_ggc (ggc)
@@ -1312,7 +778,7 @@ hash_table<Descriptor, Allocator, true>::hash_table (size_t size, bool ggc
}
template<typename Descriptor, template<typename Type> class Allocator>
-hash_table<Descriptor, Allocator, true>::~hash_table ()
+hash_table<Descriptor, Allocator>::~hash_table ()
{
for (size_t i = m_size - 1; i < m_size; i--)
if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i]))
@@ -1327,9 +793,8 @@ hash_table<Descriptor, Allocator, true>::~hash_table ()
/* This function returns an array of empty hash table elements. */
template<typename Descriptor, template<typename Type> class Allocator>
-inline typename hash_table<Descriptor, Allocator, true>::value_type *
-hash_table<Descriptor, Allocator, true>::alloc_entries
- (size_t n MEM_STAT_DECL) const
+inline typename hash_table<Descriptor, Allocator>::value_type *
+hash_table<Descriptor, Allocator>::alloc_entries (size_t n MEM_STAT_DECL) const
{
value_type *nentries;
@@ -1353,9 +818,8 @@ hash_table<Descriptor, Allocator, true>::alloc_entries
HASH is the hash value for the element to be inserted. */
template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, true>::value_type *
-hash_table<Descriptor, Allocator, true>
-::find_empty_slot_for_expand (hashval_t hash)
+typename hash_table<Descriptor, Allocator>::value_type *
+hash_table<Descriptor, Allocator>::find_empty_slot_for_expand (hashval_t hash)
{
hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
size_t size = m_size;
@@ -1393,7 +857,7 @@ hash_table<Descriptor, Allocator, true>
template<typename Descriptor, template<typename Type> class Allocator>
void
-hash_table<Descriptor, Allocator, true>::expand ()
+hash_table<Descriptor, Allocator>::expand ()
{
value_type *oentries = m_entries;
unsigned int oindex = m_size_prime_index;
@@ -1447,7 +911,7 @@ hash_table<Descriptor, Allocator, true>::expand ()
template<typename Descriptor, template<typename Type> class Allocator>
void
-hash_table<Descriptor, Allocator, true>::empty ()
+hash_table<Descriptor, Allocator>::empty ()
{
size_t size = m_size;
value_type *entries = m_entries;
@@ -1484,7 +948,7 @@ hash_table<Descriptor, Allocator, true>::empty ()
template<typename Descriptor, template<typename Type> class Allocator>
void
-hash_table<Descriptor, Allocator, true>::clear_slot (value_type *slot)
+hash_table<Descriptor, Allocator>::clear_slot (value_type *slot)
{
gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
|| is_empty (*slot) || is_deleted (*slot)));
@@ -1500,8 +964,8 @@ hash_table<Descriptor, Allocator, true>::clear_slot (value_type *slot)
be used to insert or delete an element. */
template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, true>::value_type &
-hash_table<Descriptor, Allocator, true>
+typename hash_table<Descriptor, Allocator>::value_type &
+hash_table<Descriptor, Allocator>
::find_with_hash (const compare_type &comparable, hashval_t hash)
{
m_searches++;
@@ -1537,8 +1001,8 @@ hash_table<Descriptor, Allocator, true>
entry, NULL may be returned if memory allocation fails. */
template<typename Descriptor, template<typename Type> class Allocator>
-typename hash_table<Descriptor, Allocator, true>::value_type *
-hash_table<Descriptor, Allocator, true>
+typename hash_table<Descriptor, Allocator>::value_type *
+hash_table<Descriptor, Allocator>
::find_slot_with_hash (const compare_type &comparable, hashval_t hash,
enum insert_option insert)
{
@@ -1599,7 +1063,7 @@ hash_table<Descriptor, Allocator, true>
template<typename Descriptor, template<typename Type> class Allocator>
void
-hash_table<Descriptor, Allocator, true>
+hash_table<Descriptor, Allocator>
::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
{
value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
@@ -1619,11 +1083,11 @@ hash_table<Descriptor, Allocator, true>
template<typename Descriptor,
template<typename Type> class Allocator>
template<typename Argument,
- int (*Callback) (typename hash_table<Descriptor, Allocator,
- true>::value_type *slot,
- Argument argument)>
+ int (*Callback)
+ (typename hash_table<Descriptor, Allocator>::value_type *slot,
+ Argument argument)>
void
-hash_table<Descriptor, Allocator, true>::traverse_noresize (Argument argument)
+hash_table<Descriptor, Allocator>::traverse_noresize (Argument argument)
{
value_type *slot = m_entries;
value_type *limit = slot + size ();
@@ -1645,11 +1109,11 @@ hash_table<Descriptor, Allocator, true>::traverse_noresize (Argument argument)
template <typename Descriptor,
template <typename Type> class Allocator>
template <typename Argument,
- int (*Callback) (typename hash_table<Descriptor, Allocator,
- true>::value_type *slot,
- Argument argument)>
+ int (*Callback)
+ (typename hash_table<Descriptor, Allocator>::value_type *slot,
+ Argument argument)>
void
-hash_table<Descriptor, Allocator, true>::traverse (Argument argument)
+hash_table<Descriptor, Allocator>::traverse (Argument argument)
{
size_t size = m_size;
if (elements () * 8 < size && size > 32)
@@ -1662,7 +1126,7 @@ hash_table<Descriptor, Allocator, true>::traverse (Argument argument)
template<typename Descriptor, template<typename Type> class Allocator>
void
-hash_table<Descriptor, Allocator, true>::iterator::slide ()
+hash_table<Descriptor, Allocator>::iterator::slide ()
{
for ( ; m_slot < m_limit; ++m_slot )
{
@@ -1677,8 +1141,8 @@ hash_table<Descriptor, Allocator, true>::iterator::slide ()
/* Bump the iterator. */
template<typename Descriptor, template<typename Type> class Allocator>
-inline typename hash_table<Descriptor, Allocator, true>::iterator &
-hash_table<Descriptor, Allocator, true>::iterator::operator ++ ()
+inline typename hash_table<Descriptor, Allocator>::iterator &
+hash_table<Descriptor, Allocator>::iterator::operator ++ ()
{
++m_slot;
slide ();