// -*- mode: c++; c-basic-offset: 4 -*- /* * This file is part of the KDE libraries * Copyright (C) 2005, 2006 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef WTF_HashTraits_h #define WTF_HashTraits_h #include "HashFunctions.h" #include #include namespace WTF { using std::pair; using std::make_pair; template struct IsInteger { static const bool value = false; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template<> struct IsInteger { static const bool value = true; }; template struct HashTraits; template struct GenericHashTraitsBase; template struct GenericHashTraitsBase { typedef T TraitType; typedef HashTraits::SignedType> StorageTraits; static const bool emptyValueIsZero = true; static const bool needsDestruction = false; }; template struct GenericHashTraitsBase { typedef T TraitType; typedef HashTraits StorageTraits; static const bool emptyValueIsZero = false; static const bool needsDestruction = true; }; template struct GenericHashTraits : GenericHashTraitsBase::value, T> { static T emptyValue() { return T(); } static const bool needsRef = false; }; template struct HashTraits : GenericHashTraits { }; // signed integer traits may not be appropriate for all uses since they disallow 0 and -1 as keys template<> struct HashTraits : GenericHashTraits { static signed char deletedValue() { return -1; } }; template<> struct HashTraits : GenericHashTraits { static short deletedValue() { return -1; } }; template<> struct HashTraits : GenericHashTraits { static int deletedValue() { return -1; } }; template<> struct HashTraits : GenericHashTraits { static unsigned int deletedValue() { return static_cast(-1); } }; template<> struct HashTraits : GenericHashTraits { static long deletedValue() { return -1; } }; template<> struct HashTraits : GenericHashTraits { static unsigned long deletedValue() { return static_cast(-1); } }; template<> struct HashTraits : GenericHashTraits { static long long deletedValue() { return -1; } }; template<> struct HashTraits : GenericHashTraits { static unsigned long long deletedValue() { return static_cast(-1); } }; template struct FloatHashTraits { typedef T TraitType; typedef HashTraits StorageTraits; static T emptyValue() { return std::numeric_limits::infinity(); } static T deletedValue() { return -std::numeric_limits::infinity(); } static const bool emptyValueIsZero = false; static const bool needsDestruction = false; static const bool needsRef = false; }; template<> struct HashTraits : FloatHashTraits { }; template<> struct HashTraits : FloatHashTraits { }; template struct HashTraits : GenericHashTraits { typedef HashTraits::SignedType> StorageTraits; static const bool emptyValueIsZero = true; static const bool needsDestruction = false; static P* deletedValue() { return reinterpret_cast(-1); } }; template struct HashTraits > : GenericHashTraits > { typedef HashTraits::SignedType> StorageTraits; typedef typename StorageTraits::TraitType StorageType; static const bool emptyValueIsZero = true; static const bool needsRef = true; typedef union { P* m_p; StorageType m_s; } UnionType; static void ref(const StorageType& s) { if (const P* p = reinterpret_cast(&s)->m_p) const_cast(p)->ref(); } static void deref(const StorageType& s) { if (const P* p = reinterpret_cast(&s)->m_p) const_cast(p)->deref(); } }; // template to set deleted values template struct DeletedValueAssigner { static void assignDeletedValue(typename Traits::TraitType& location) { location = Traits::deletedValue(); } }; template inline void assignDeleted(T& location) { DeletedValueAssigner::assignDeletedValue(location); } // special traits for pairs, helpful for their use in HashMap implementation template struct PairHashTraits; template struct PairBaseHashTraits : GenericHashTraits > { typedef FirstTraitsArg FirstTraits; typedef SecondTraitsArg SecondTraits; typedef pair TraitType; typedef PairHashTraits StorageTraits; static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero; static TraitType emptyValue() { return make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); } }; template struct PairHashTraits : PairBaseHashTraits { typedef pair TraitType; static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction; static TraitType deletedValue() { return TraitType(FirstTraits::deletedValue(), SecondTraits::emptyValue()); } static void assignDeletedValue(TraitType& location) { assignDeleted(location.first); location.second = SecondTraits::emptyValue(); } }; template struct HashTraits > : public PairHashTraits, HashTraits > { }; template struct DeletedValueAssigner > { static void assignDeletedValue(pair& location) { PairHashTraits::assignDeletedValue(location); } }; template struct DeletedValueAssigner > > { static void assignDeletedValue(pair& location) { HashTraits >::assignDeletedValue(location); } }; // hash functions and traits that are equivalent (for code sharing) template struct HashKeyStorageTraits { typedef HashArg Hash; typedef TraitsArg Traits; }; template struct HashKeyStorageTraits, HashTraits > { typedef typename IntTypes::SignedType IntType; typedef IntHash Hash; typedef HashTraits Traits; }; template struct HashKeyStorageTraits >, HashTraits > > { typedef typename IntTypes::SignedType IntType; typedef IntHash Hash; typedef HashTraits Traits; }; } // namespace WTF using WTF::HashTraits; using WTF::PairHashTraits; #endif // WTF_HashTraits_h