129 lines
2.9 KiB
C++
129 lines
2.9 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997, Microsoft Corp. All rights reserved.
|
|
//
|
|
// FILE
|
|
//
|
|
// hashmap.h
|
|
//
|
|
// SYNOPSIS
|
|
//
|
|
// This file describes the hash_map template class.
|
|
//
|
|
// MODIFICATION HISTORY
|
|
//
|
|
// 11/06/1997 Original version.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _HASHMAP_H_
|
|
#define _HASHMAP_H_
|
|
|
|
#include <hashtbl.h>
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CLASS
|
|
//
|
|
// hash_map<Key, Value, Hasher, KeyMatch>
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// Extends hash_table (q.v.) to implement a hash map.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <
|
|
class Key,
|
|
class Value,
|
|
class Hasher = hash_util::Hasher<Key>,
|
|
class KeyMatch = std::equal_to<Key>
|
|
>
|
|
class hash_map
|
|
: public hash_table<
|
|
Key,
|
|
Hasher,
|
|
std::pair<const Key, Value>,
|
|
ExtractFirst< std::pair<const Key, Value> >,
|
|
KeyMatch
|
|
>
|
|
{
|
|
public:
|
|
|
|
typedef table_type::const_iterator const_iterator;
|
|
typedef Value referent_type;
|
|
|
|
//////////
|
|
// The hash map can support a non-const iterator since you can change
|
|
// Value without effecting the hash value.
|
|
//////////
|
|
class iterator : public const_iterator
|
|
{
|
|
public:
|
|
iterator(SList* _first, SList* _end)
|
|
: const_iterator(_first, _end)
|
|
{
|
|
}
|
|
|
|
value_type& operator*() const
|
|
{
|
|
return node->value;
|
|
}
|
|
|
|
value_type* operator->() const
|
|
{
|
|
return &**this;
|
|
}
|
|
};
|
|
|
|
hash_map(size_t size = 16)
|
|
: table_type(size) { }
|
|
|
|
// non-const version of hash_table::begin
|
|
iterator begin()
|
|
{
|
|
return iterator(table, table + buckets);
|
|
}
|
|
|
|
// non-const version of hash_table::find
|
|
value_type* find(const key_type& key)
|
|
{
|
|
return const_cast<value_type*>(table_type::find(key));
|
|
}
|
|
|
|
// Duplicates implementation hidden in base class.
|
|
const value_type* find(const key_type& key) const
|
|
{
|
|
return const_cast<value_type*>(table_type::find(key));
|
|
}
|
|
|
|
// Allows the map to be indexed like an array.
|
|
referent_type& operator[](const key_type& key)
|
|
{
|
|
// Compute the hash value once.
|
|
size_t hv = hasher(key);
|
|
|
|
// See if the key exists.
|
|
const value_type* v = search_bucket(table[hv & mask], key);
|
|
|
|
if (!v)
|
|
{
|
|
reserve_space();
|
|
|
|
// The key wasn't found, so create a new node using
|
|
// a default referent.
|
|
|
|
Node* node = new Node(value_type(key, referent_type()));
|
|
|
|
add_entry();
|
|
|
|
table[hv & mask].push_front(node);
|
|
|
|
v = &node->value;
|
|
}
|
|
|
|
return const_cast<referent_type&>(v->second);
|
|
}
|
|
};
|
|
|
|
#endif // _HASHMAP_H_
|