1 | // -*- mode: c++; c-basic-offset: 4 -*-
|
---|
2 | /*
|
---|
3 | * This file is part of the KDE libraries
|
---|
4 | * Copyright (C) 2005, 2006 Apple Computer, Inc.
|
---|
5 | *
|
---|
6 | * This library is free software; you can redistribute it and/or
|
---|
7 | * modify it under the terms of the GNU Library General Public
|
---|
8 | * License as published by the Free Software Foundation; either
|
---|
9 | * version 2 of the License, or (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This library is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
14 | * Library General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU Library General Public License
|
---|
17 | * along with this library; see the file COPYING.LIB. If not, write to
|
---|
18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
---|
19 | * Boston, MA 02110-1301, USA.
|
---|
20 | *
|
---|
21 | */
|
---|
22 |
|
---|
23 | #ifndef KXMLCORE_HASH_TRAITS_H
|
---|
24 | #define KXMLCORE_HASH_TRAITS_H
|
---|
25 |
|
---|
26 | #include "HashFunctions.h"
|
---|
27 | #include <utility>
|
---|
28 |
|
---|
29 | namespace WTF {
|
---|
30 |
|
---|
31 | using std::pair;
|
---|
32 | using std::make_pair;
|
---|
33 |
|
---|
34 | template<typename T> struct IsInteger { static const bool value = false; };
|
---|
35 | template<> struct IsInteger<bool> { static const bool value = true; };
|
---|
36 | template<> struct IsInteger<char> { static const bool value = true; };
|
---|
37 | template<> struct IsInteger<signed char> { static const bool value = true; };
|
---|
38 | template<> struct IsInteger<unsigned char> { static const bool value = true; };
|
---|
39 | template<> struct IsInteger<short> { static const bool value = true; };
|
---|
40 | template<> struct IsInteger<unsigned short> { static const bool value = true; };
|
---|
41 | template<> struct IsInteger<int> { static const bool value = true; };
|
---|
42 | template<> struct IsInteger<unsigned int> { static const bool value = true; };
|
---|
43 | template<> struct IsInteger<long> { static const bool value = true; };
|
---|
44 | template<> struct IsInteger<unsigned long> { static const bool value = true; };
|
---|
45 | template<> struct IsInteger<long long> { static const bool value = true; };
|
---|
46 | template<> struct IsInteger<unsigned long long> { static const bool value = true; };
|
---|
47 |
|
---|
48 | template<typename T> struct HashTraits;
|
---|
49 |
|
---|
50 | template<bool isInteger, typename T> struct GenericHashTraitsBase;
|
---|
51 | template<typename T> struct GenericHashTraitsBase<true, T> {
|
---|
52 | typedef T TraitType;
|
---|
53 | typedef HashTraits<typename IntTypes<sizeof(T)>::SignedType> StorageTraits;
|
---|
54 | static const bool emptyValueIsZero = true;
|
---|
55 | static const bool needsDestruction = false;
|
---|
56 | };
|
---|
57 | template<typename T> struct GenericHashTraitsBase<false, T> {
|
---|
58 | typedef T TraitType;
|
---|
59 | typedef HashTraits<T> StorageTraits;
|
---|
60 | static const bool emptyValueIsZero = false;
|
---|
61 | static const bool needsDestruction = true;
|
---|
62 | };
|
---|
63 |
|
---|
64 | template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> {
|
---|
65 | static T emptyValue() { return T(); }
|
---|
66 | static const bool needsRef = false;
|
---|
67 | };
|
---|
68 |
|
---|
69 | template<typename T> struct HashTraits : GenericHashTraits<T> { };
|
---|
70 |
|
---|
71 | // signed integer traits may not be appropriate for all uses since they disallow 0 and -1 as keys
|
---|
72 | template<> struct HashTraits<signed char> : GenericHashTraits<int> {
|
---|
73 | static signed char deletedValue() { return -1; }
|
---|
74 | };
|
---|
75 | template<> struct HashTraits<short> : GenericHashTraits<int> {
|
---|
76 | static short deletedValue() { return -1; }
|
---|
77 | };
|
---|
78 | template<> struct HashTraits<int> : GenericHashTraits<int> {
|
---|
79 | static int deletedValue() { return -1; }
|
---|
80 | };
|
---|
81 | template<> struct HashTraits<long> : GenericHashTraits<long> {
|
---|
82 | static long deletedValue() { return -1; }
|
---|
83 | };
|
---|
84 | template<> struct HashTraits<long long> : GenericHashTraits<long long> {
|
---|
85 | static long deletedValue() { return -1; }
|
---|
86 | };
|
---|
87 |
|
---|
88 | template<typename P> struct HashTraits<P*> : GenericHashTraits<P*> {
|
---|
89 | typedef HashTraits<typename IntTypes<sizeof(P*)>::SignedType> StorageTraits;
|
---|
90 | static const bool emptyValueIsZero = true;
|
---|
91 | static const bool needsDestruction = false;
|
---|
92 | static P* deletedValue() { return reinterpret_cast<P*>(-1); }
|
---|
93 | };
|
---|
94 |
|
---|
95 | template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > {
|
---|
96 | typedef HashTraits<typename IntTypes<sizeof(P*)>::SignedType> StorageTraits;
|
---|
97 | static const bool emptyValueIsZero = true;
|
---|
98 | static const bool needsRef = true;
|
---|
99 | static void ref(const RefPtr<P>& p) { if (p) p->ref(); }
|
---|
100 | static void deref(const RefPtr<P>& p) { if (p) p->deref(); }
|
---|
101 | };
|
---|
102 |
|
---|
103 | // template to set deleted values
|
---|
104 |
|
---|
105 | template<typename Traits> struct DeletedValueAssigner {
|
---|
106 | static void assignDeletedValue(typename Traits::TraitType& location) { location = Traits::deletedValue(); }
|
---|
107 | };
|
---|
108 |
|
---|
109 | template<typename T, typename Traits> inline void assignDeleted(T& location)
|
---|
110 | {
|
---|
111 | DeletedValueAssigner<Traits>::assignDeletedValue(location);
|
---|
112 | }
|
---|
113 |
|
---|
114 | // special traits for pairs, helpful for their use in HashMap implementation
|
---|
115 |
|
---|
116 | template<typename FirstTraits, typename SecondTraits> struct PairHashTraits;
|
---|
117 |
|
---|
118 | template<typename FirstTraitsArg, typename SecondTraitsArg>
|
---|
119 | struct PairBaseHashTraits : GenericHashTraits<pair<typename FirstTraitsArg::TraitType, typename SecondTraitsArg::TraitType> > {
|
---|
120 | typedef FirstTraitsArg FirstTraits;
|
---|
121 | typedef SecondTraitsArg SecondTraits;
|
---|
122 | typedef pair<typename FirstTraits::TraitType, typename SecondTraits::TraitType> TraitType;
|
---|
123 |
|
---|
124 | typedef PairHashTraits<typename FirstTraits::StorageTraits, typename SecondTraits::StorageTraits> StorageTraits;
|
---|
125 |
|
---|
126 | static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
|
---|
127 |
|
---|
128 | static TraitType emptyValue()
|
---|
129 | {
|
---|
130 | return make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue());
|
---|
131 | }
|
---|
132 | };
|
---|
133 |
|
---|
134 | template<typename FirstTraits, typename SecondTraits>
|
---|
135 | struct PairHashTraits : PairBaseHashTraits<FirstTraits, SecondTraits> {
|
---|
136 | typedef pair<typename FirstTraits::TraitType, typename SecondTraits::TraitType> TraitType;
|
---|
137 |
|
---|
138 | static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
|
---|
139 |
|
---|
140 | static TraitType deletedValue()
|
---|
141 | {
|
---|
142 | return TraitType(FirstTraits::deletedValue(), SecondTraits::emptyValue());
|
---|
143 | }
|
---|
144 |
|
---|
145 | static void assignDeletedValue(TraitType& location)
|
---|
146 | {
|
---|
147 | assignDeleted<typename FirstTraits::TraitType, FirstTraits>(location.first);
|
---|
148 | location.second = SecondTraits::emptyValue();
|
---|
149 | }
|
---|
150 | };
|
---|
151 |
|
---|
152 | template<typename First, typename Second>
|
---|
153 | struct HashTraits<pair<First, Second> > : public PairHashTraits<HashTraits<First>, HashTraits<Second> > { };
|
---|
154 |
|
---|
155 | template<typename FirstTraits, typename SecondTraits>
|
---|
156 | struct DeletedValueAssigner<PairHashTraits<FirstTraits, SecondTraits> >
|
---|
157 | {
|
---|
158 | static void assignDeletedValue(pair<typename FirstTraits::TraitType, typename SecondTraits::TraitType>& location)
|
---|
159 | {
|
---|
160 | PairHashTraits<FirstTraits, SecondTraits>::assignDeletedValue(location);
|
---|
161 | }
|
---|
162 | };
|
---|
163 |
|
---|
164 | template<typename First, typename Second>
|
---|
165 | struct DeletedValueAssigner<HashTraits<pair<First, Second> > >
|
---|
166 | {
|
---|
167 | static void assignDeletedValue(pair<First, Second>& location)
|
---|
168 | {
|
---|
169 | HashTraits<pair<First, Second> >::assignDeletedValue(location);
|
---|
170 | }
|
---|
171 | };
|
---|
172 |
|
---|
173 | // hassh functions and traits that are equivalent (for code sharing)
|
---|
174 |
|
---|
175 | template<typename HashArg, typename TraitsArg> struct HashKeyStorageTraits {
|
---|
176 | typedef HashArg Hash;
|
---|
177 | typedef TraitsArg Traits;
|
---|
178 | };
|
---|
179 | template<typename P> struct HashKeyStorageTraits<PtrHash<P*>, HashTraits<P*> > {
|
---|
180 | typedef typename IntTypes<sizeof(P*)>::SignedType IntType;
|
---|
181 | typedef IntHash<IntType> Hash;
|
---|
182 | typedef HashTraits<IntType> Traits;
|
---|
183 | };
|
---|
184 | template<typename P> struct HashKeyStorageTraits<PtrHash<RefPtr<P> >, HashTraits<RefPtr<P> > > {
|
---|
185 | typedef typename IntTypes<sizeof(P*)>::SignedType IntType;
|
---|
186 | typedef IntHash<IntType> Hash;
|
---|
187 | typedef HashTraits<IntType> Traits;
|
---|
188 | };
|
---|
189 |
|
---|
190 | } // namespace WTF
|
---|
191 |
|
---|
192 | using WTF::HashTraits;
|
---|
193 | using WTF::PairHashTraits;
|
---|
194 |
|
---|
195 | #endif // KXMLCORE_HASH_TRAITS_H
|
---|