1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html |
3 | /* |
4 | ****************************************************************************** |
5 | * Copyright (C) 1997-2014, International Business Machines |
6 | * Corporation and others. All Rights Reserved. |
7 | ****************************************************************************** |
8 | * Date Name Description |
9 | * 03/28/00 aliu Creation. |
10 | ****************************************************************************** |
11 | */ |
12 | |
13 | #ifndef HASH_H |
14 | #define HASH_H |
15 | |
16 | #include "unicode/unistr.h" |
17 | #include "unicode/uobject.h" |
18 | #include "cmemory.h" |
19 | #include "uhash.h" |
20 | |
21 | U_NAMESPACE_BEGIN |
22 | |
23 | /** |
24 | * Hashtable is a thin C++ wrapper around UHashtable, a general-purpose void* |
25 | * hashtable implemented in C. Hashtable is designed to be idiomatic and |
26 | * easy-to-use in C++. |
27 | * |
28 | * Hashtable is an INTERNAL CLASS. |
29 | */ |
30 | class U_COMMON_API Hashtable : public UMemory { |
31 | UHashtable* hash; |
32 | UHashtable hashObj; |
33 | |
34 | inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status); |
35 | |
36 | inline void initSize(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, int32_t size, UErrorCode& status); |
37 | |
38 | public: |
39 | /** |
40 | * Construct a hashtable |
41 | * @param ignoreKeyCase If true, keys are case insensitive. |
42 | * @param status Error code |
43 | */ |
44 | inline Hashtable(UBool ignoreKeyCase, UErrorCode& status); |
45 | |
46 | /** |
47 | * Construct a hashtable |
48 | * @param ignoreKeyCase If true, keys are case insensitive. |
49 | * @param size initial size allocation |
50 | * @param status Error code |
51 | */ |
52 | inline Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status); |
53 | |
54 | /** |
55 | * Construct a hashtable |
56 | * @param keyComp Comparator for comparing the keys |
57 | * @param valueComp Comparator for comparing the values |
58 | * @param status Error code |
59 | */ |
60 | inline Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status); |
61 | |
62 | /** |
63 | * Construct a hashtable |
64 | * @param status Error code |
65 | */ |
66 | inline Hashtable(UErrorCode& status); |
67 | |
68 | /** |
69 | * Construct a hashtable, _disregarding any error_. Use this constructor |
70 | * with caution. |
71 | */ |
72 | inline Hashtable(); |
73 | |
74 | /** |
75 | * Non-virtual destructor; make this virtual if Hashtable is subclassed |
76 | * in the future. |
77 | */ |
78 | inline ~Hashtable(); |
79 | |
80 | inline UObjectDeleter *setValueDeleter(UObjectDeleter *fn); |
81 | |
82 | inline int32_t count() const; |
83 | |
84 | inline void* put(const UnicodeString& key, void* value, UErrorCode& status); |
85 | |
86 | inline int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status); |
87 | |
88 | inline int32_t putiAllowZero(const UnicodeString& key, int32_t value, UErrorCode& status); |
89 | |
90 | inline void* get(const UnicodeString& key) const; |
91 | |
92 | inline int32_t geti(const UnicodeString& key) const; |
93 | |
94 | inline int32_t getiAndFound(const UnicodeString& key, UBool &found) const; |
95 | |
96 | inline void* remove(const UnicodeString& key); |
97 | |
98 | inline int32_t removei(const UnicodeString& key); |
99 | |
100 | inline void removeAll(); |
101 | |
102 | inline UBool containsKey(const UnicodeString& key) const; |
103 | |
104 | inline const UHashElement* find(const UnicodeString& key) const; |
105 | |
106 | /** |
107 | * @param pos - must be UHASH_FIRST on first call, and untouched afterwards. |
108 | * @see uhash_nextElement |
109 | */ |
110 | inline const UHashElement* nextElement(int32_t& pos) const; |
111 | |
112 | inline UKeyComparator* setKeyComparator(UKeyComparator*keyComp); |
113 | |
114 | inline UValueComparator* setValueComparator(UValueComparator* valueComp); |
115 | |
116 | inline UBool equals(const Hashtable& that) const; |
117 | private: |
118 | Hashtable(const Hashtable &other) = delete; // forbid copying of this class |
119 | Hashtable &operator=(const Hashtable &other) = delete; // forbid copying of this class |
120 | }; |
121 | |
122 | /********************************************************************* |
123 | * Implementation |
124 | ********************************************************************/ |
125 | |
126 | inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, |
127 | UValueComparator *valueComp, UErrorCode& status) { |
128 | if (U_FAILURE(status)) { |
129 | return; |
130 | } |
131 | uhash_init(&hashObj, keyHash, keyComp, valueComp, &status); |
132 | if (U_SUCCESS(status)) { |
133 | hash = &hashObj; |
134 | uhash_setKeyDeleter(hash, uprv_deleteUObject); |
135 | } |
136 | } |
137 | |
138 | inline void Hashtable::initSize(UHashFunction *keyHash, UKeyComparator *keyComp, |
139 | UValueComparator *valueComp, int32_t size, UErrorCode& status) { |
140 | if (U_FAILURE(status)) { |
141 | return; |
142 | } |
143 | uhash_initSize(&hashObj, keyHash, keyComp, valueComp, size, &status); |
144 | if (U_SUCCESS(status)) { |
145 | hash = &hashObj; |
146 | uhash_setKeyDeleter(hash, uprv_deleteUObject); |
147 | } |
148 | } |
149 | |
150 | inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, |
151 | UErrorCode& status) : hash(0) { |
152 | init( uhash_hashUnicodeString, keyComp, valueComp, status); |
153 | } |
154 | |
155 | inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status) |
156 | : hash(0) |
157 | { |
158 | init(ignoreKeyCase ? uhash_hashCaselessUnicodeString |
159 | : uhash_hashUnicodeString, |
160 | ignoreKeyCase ? uhash_compareCaselessUnicodeString |
161 | : uhash_compareUnicodeString, |
162 | nullptr, |
163 | status); |
164 | } |
165 | |
166 | inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status) |
167 | : hash(0) |
168 | { |
169 | initSize(ignoreKeyCase ? uhash_hashCaselessUnicodeString |
170 | : uhash_hashUnicodeString, |
171 | ignoreKeyCase ? uhash_compareCaselessUnicodeString |
172 | : uhash_compareUnicodeString, |
173 | nullptr, size, |
174 | status); |
175 | } |
176 | |
177 | inline Hashtable::Hashtable(UErrorCode& status) |
178 | : hash(0) |
179 | { |
180 | init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status); |
181 | } |
182 | |
183 | inline Hashtable::Hashtable() |
184 | : hash(0) |
185 | { |
186 | UErrorCode status = U_ZERO_ERROR; |
187 | init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status); |
188 | } |
189 | |
190 | inline Hashtable::~Hashtable() { |
191 | if (hash != nullptr) { |
192 | uhash_close(hash); |
193 | } |
194 | } |
195 | |
196 | inline UObjectDeleter *Hashtable::setValueDeleter(UObjectDeleter *fn) { |
197 | return uhash_setValueDeleter(hash, fn); |
198 | } |
199 | |
200 | inline int32_t Hashtable::count() const { |
201 | return uhash_count(hash); |
202 | } |
203 | |
204 | inline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) { |
205 | return uhash_put(hash, new UnicodeString(key), value, &status); |
206 | } |
207 | |
208 | inline int32_t Hashtable::puti(const UnicodeString& key, int32_t value, UErrorCode& status) { |
209 | return uhash_puti(hash, new UnicodeString(key), value, &status); |
210 | } |
211 | |
212 | inline int32_t Hashtable::putiAllowZero(const UnicodeString& key, int32_t value, |
213 | UErrorCode& status) { |
214 | return uhash_putiAllowZero(hash, new UnicodeString(key), value, &status); |
215 | } |
216 | |
217 | inline void* Hashtable::get(const UnicodeString& key) const { |
218 | return uhash_get(hash, &key); |
219 | } |
220 | |
221 | inline int32_t Hashtable::geti(const UnicodeString& key) const { |
222 | return uhash_geti(hash, &key); |
223 | } |
224 | |
225 | inline int32_t Hashtable::getiAndFound(const UnicodeString& key, UBool &found) const { |
226 | return uhash_getiAndFound(hash, &key, &found); |
227 | } |
228 | |
229 | inline void* Hashtable::remove(const UnicodeString& key) { |
230 | return uhash_remove(hash, &key); |
231 | } |
232 | |
233 | inline int32_t Hashtable::removei(const UnicodeString& key) { |
234 | return uhash_removei(hash, &key); |
235 | } |
236 | |
237 | inline UBool Hashtable::containsKey(const UnicodeString& key) const { |
238 | return uhash_containsKey(hash, &key); |
239 | } |
240 | |
241 | inline const UHashElement* Hashtable::find(const UnicodeString& key) const { |
242 | return uhash_find(hash, &key); |
243 | } |
244 | |
245 | inline const UHashElement* Hashtable::nextElement(int32_t& pos) const { |
246 | return uhash_nextElement(hash, &pos); |
247 | } |
248 | |
249 | inline void Hashtable::removeAll() { |
250 | uhash_removeAll(hash); |
251 | } |
252 | |
253 | inline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){ |
254 | return uhash_setKeyComparator(hash, keyComp); |
255 | } |
256 | |
257 | inline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){ |
258 | return uhash_setValueComparator(hash, valueComp); |
259 | } |
260 | |
261 | inline UBool Hashtable::equals(const Hashtable& that)const{ |
262 | return uhash_equals(hash, that.hash); |
263 | } |
264 | U_NAMESPACE_END |
265 | |
266 | #endif |
267 | |
268 | |