-// -*- mode: c++; c-basic-offset: 4 -*-
/*
- * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
// This specialization is a direct copy of HashMap, with overloaded functions
// to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
- // FIXME: Is there a better way to do this that doesn't just copy HashMap?
+ // FIXME: Find a better way that doesn't require an entire copy of the HashMap template.
+ template<typename RawKeyType, typename ValueType, typename ValueTraits, typename HashFunctions>
+ struct RefPtrHashMapRawKeyTranslator {
+ typedef typename ValueType::first_type KeyType;
+ typedef typename ValueType::second_type MappedType;
+ typedef typename ValueTraits::FirstTraits KeyTraits;
+ typedef typename ValueTraits::SecondTraits MappedTraits;
+
+ static unsigned hash(RawKeyType key) { return HashFunctions::hash(key); }
+ static bool equal(const KeyType& a, RawKeyType b) { return HashFunctions::equal(a, b); }
+ static void translate(ValueType& location, RawKeyType key, const MappedType& mapped)
+ {
+ location.first = key;
+ location.second = mapped;
+ }
+ };
+
template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
- class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
+ class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> : public FastAllocBase {
private:
typedef KeyTraitsArg KeyTraits;
typedef MappedTraitsArg MappedTraits;
- typedef PairBaseHashTraits<KeyTraits, MappedTraits> ValueTraits;
+ typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits;
public:
typedef typename KeyTraits::TraitType KeyType;
private:
typedef HashArg HashFunctions;
- typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Hash StorageHashFunctions;
-
- typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Traits KeyStorageTraits;
- typedef typename MappedTraits::StorageTraits MappedStorageTraits;
- typedef PairHashTraits<KeyStorageTraits, MappedStorageTraits> ValueStorageTraits;
+ typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>,
+ HashFunctions, ValueTraits, KeyTraits> HashTableType;
- typedef typename KeyStorageTraits::TraitType KeyStorageType;
- typedef typename MappedStorageTraits::TraitType MappedStorageType;
- typedef typename ValueStorageTraits::TraitType ValueStorageType;
-
- typedef HashTable<KeyStorageType, ValueStorageType, PairFirstExtractor<ValueStorageType>,
- StorageHashFunctions, ValueStorageTraits, KeyStorageTraits> HashTableType;
+ typedef RefPtrHashMapRawKeyTranslator<RawKeyType, ValueType, ValueTraits, HashFunctions>
+ RawKeyTranslator;
public:
typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
- HashMap();
- HashMap(const HashMap&);
- HashMap& operator=(const HashMap&);
- ~HashMap();
-
void swap(HashMap&);
int size() const;
bool contains(RawKeyType) const;
MappedType get(const KeyType&) const;
MappedType get(RawKeyType) const;
+ MappedType inlineGet(RawKeyType) const;
// replaces value but not key if key is already present
// return value is a pair of the iterator to the key location,
private:
pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
pair<iterator, bool> inlineAdd(RawKeyType, const MappedType&);
- void refAll();
- void derefAll();
HashTableType m_impl;
};
- template<typename T, typename U, typename V, typename W, typename X>
- inline void HashMap<RefPtr<T>, U, V, W, X>::refAll()
- {
- HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
- }
-
- template<typename T, typename U, typename V, typename W, typename X>
- inline void HashMap<RefPtr<T>, U, V, W, X>::derefAll()
- {
- HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
- }
-
- template<typename T, typename U, typename V, typename W, typename X>
- inline HashMap<RefPtr<T>, U, V, W, X>::HashMap()
- {
- }
-
- template<typename T, typename U, typename V, typename W, typename X>
- inline HashMap<RefPtr<T>, U, V, W, X>::HashMap(const HashMap& other)
- : m_impl(other.m_impl)
- {
- refAll();
- }
-
- template<typename T, typename U, typename V, typename W, typename X>
- inline HashMap<RefPtr<T>, U, V, W, X>& HashMap<RefPtr<T>, U, V, W, X>::operator=(const HashMap& other)
- {
- HashMap tmp(other);
- swap(tmp);
- return *this;
- }
-
template<typename T, typename U, typename V, typename W, typename X>
inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other)
{
m_impl.swap(other.m_impl);
}
- template<typename T, typename U, typename V, typename W, typename X>
- inline HashMap<RefPtr<T>, U, V, W, X>::~HashMap()
- {
- derefAll();
- }
-
template<typename T, typename U, typename V, typename W, typename X>
inline int HashMap<RefPtr<T>, U, V, W, X>::size() const
{
template<typename T, typename U, typename V, typename W, typename X>
inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key)
{
- return m_impl.find(*(const KeyStorageType*)&key);
+ return m_impl.find(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key)
{
- return m_impl.find(*(const KeyStorageType*)&key);
+ return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const
{
- return m_impl.find(*(const KeyStorageType*)&key);
+ return m_impl.find(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const
{
- return m_impl.find(*(const KeyStorageType*)&key);
+ return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const
{
- return m_impl.contains(*(const KeyStorageType*)&key);
+ return m_impl.contains(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const
{
- return m_impl.contains(*(const KeyStorageType*)&key);
+ return m_impl.template contains<RawKeyType, RawKeyTranslator>(key);
}
template<typename T, typename U, typename V, typename W, typename X>
inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
{
- const bool canReplaceDeletedKey = !KeyTraits::needsDestruction || KeyStorageTraits::needsDestruction;
- typedef HashMapTranslator<canReplaceDeletedKey, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> TranslatorType;
+ typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType;
return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
}
inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(RawKeyType key, const MappedType& mapped)
{
- return inlineAdd(*(const KeyType*)&key, mapped);
+ return m_impl.template add<RawKeyType, MappedType, RawKeyTranslator>(key, mapped);
}
template<typename T, typename U, typename V, typename W, typename X>
HashMap<RefPtr<T>, U, V, W, X>::set(const KeyType& key, const MappedType& mapped)
{
pair<iterator, bool> result = inlineAdd(key, mapped);
- if (!result.second)
+ if (!result.second) {
// add call above didn't change anything, so set the mapped value
result.first->second = mapped;
+ }
return result;
}
HashMap<RefPtr<T>, U, V, W, X>::set(RawKeyType key, const MappedType& mapped)
{
pair<iterator, bool> result = inlineAdd(key, mapped);
- if (!result.second)
+ if (!result.second) {
// add call above didn't change anything, so set the mapped value
result.first->second = mapped;
+ }
return result;
}
typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const
{
- if (m_impl.isEmpty())
- return MappedTraits::emptyValue();
- ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
+ ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
if (!entry)
return MappedTraits::emptyValue();
- return ((ValueType *)entry)->second;
+ return entry->second;
}
template<typename T, typename U, typename V, typename W, typename MappedTraits>
typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
- HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
+ inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const
{
- if (m_impl.isEmpty())
- return MappedTraits::emptyValue();
- ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
+ ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<RawKeyType, RawKeyTranslator>(key);
if (!entry)
return MappedTraits::emptyValue();
- return ((ValueType *)entry)->second;
+ return entry->second;
+ }
+
+ template<typename T, typename U, typename V, typename W, typename MappedTraits>
+ typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
+ HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
+ {
+ return inlineGet(key);
}
template<typename T, typename U, typename V, typename W, typename X>
{
if (it.m_impl == m_impl.end())
return;
- m_impl.checkTableConsistency();
- RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
+ m_impl.internalCheckTableConsistency();
m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
}
template<typename T, typename U, typename V, typename W, typename X>
inline void HashMap<RefPtr<T>, U, V, W, X>::clear()
{
- derefAll();
m_impl.clear();
}