| 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 void* get(const UnicodeString& key) const; | 
|---|
| 89 |  | 
|---|
| 90 | inline int32_t geti(const UnicodeString& key) const; | 
|---|
| 91 |  | 
|---|
| 92 | inline void* remove(const UnicodeString& key); | 
|---|
| 93 |  | 
|---|
| 94 | inline int32_t removei(const UnicodeString& key); | 
|---|
| 95 |  | 
|---|
| 96 | inline void removeAll(void); | 
|---|
| 97 |  | 
|---|
| 98 | inline const UHashElement* find(const UnicodeString& key) const; | 
|---|
| 99 |  | 
|---|
| 100 | /** | 
|---|
| 101 | * @param pos - must be UHASH_FIRST on first call, and untouched afterwards. | 
|---|
| 102 | * @see uhash_nextElement | 
|---|
| 103 | */ | 
|---|
| 104 | inline const UHashElement* nextElement(int32_t& pos) const; | 
|---|
| 105 |  | 
|---|
| 106 | inline UKeyComparator* setKeyComparator(UKeyComparator*keyComp); | 
|---|
| 107 |  | 
|---|
| 108 | inline UValueComparator* setValueComparator(UValueComparator* valueComp); | 
|---|
| 109 |  | 
|---|
| 110 | inline UBool equals(const Hashtable& that) const; | 
|---|
| 111 | private: | 
|---|
| 112 | Hashtable(const Hashtable &other); // forbid copying of this class | 
|---|
| 113 | Hashtable &operator=(const Hashtable &other); // forbid copying of this class | 
|---|
| 114 | }; | 
|---|
| 115 |  | 
|---|
| 116 | /********************************************************************* | 
|---|
| 117 | * Implementation | 
|---|
| 118 | ********************************************************************/ | 
|---|
| 119 |  | 
|---|
| 120 | inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, | 
|---|
| 121 | UValueComparator *valueComp, UErrorCode& status) { | 
|---|
| 122 | if (U_FAILURE(status)) { | 
|---|
| 123 | return; | 
|---|
| 124 | } | 
|---|
| 125 | uhash_init(&hashObj, keyHash, keyComp, valueComp, &status); | 
|---|
| 126 | if (U_SUCCESS(status)) { | 
|---|
| 127 | hash = &hashObj; | 
|---|
| 128 | uhash_setKeyDeleter(hash, uprv_deleteUObject); | 
|---|
| 129 | } | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | inline void Hashtable::initSize(UHashFunction *keyHash, UKeyComparator *keyComp, | 
|---|
| 133 | UValueComparator *valueComp, int32_t size, UErrorCode& status) { | 
|---|
| 134 | if (U_FAILURE(status)) { | 
|---|
| 135 | return; | 
|---|
| 136 | } | 
|---|
| 137 | uhash_initSize(&hashObj, keyHash, keyComp, valueComp, size, &status); | 
|---|
| 138 | if (U_SUCCESS(status)) { | 
|---|
| 139 | hash = &hashObj; | 
|---|
| 140 | uhash_setKeyDeleter(hash, uprv_deleteUObject); | 
|---|
| 141 | } | 
|---|
| 142 | } | 
|---|
| 143 |  | 
|---|
| 144 | inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, | 
|---|
| 145 | UErrorCode& status) : hash(0) { | 
|---|
| 146 | init( uhash_hashUnicodeString, keyComp, valueComp, status); | 
|---|
| 147 | } | 
|---|
| 148 |  | 
|---|
| 149 | inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status) | 
|---|
| 150 | : hash(0) | 
|---|
| 151 | { | 
|---|
| 152 | init(ignoreKeyCase ? uhash_hashCaselessUnicodeString | 
|---|
| 153 | : uhash_hashUnicodeString, | 
|---|
| 154 | ignoreKeyCase ? uhash_compareCaselessUnicodeString | 
|---|
| 155 | : uhash_compareUnicodeString, | 
|---|
| 156 | NULL, | 
|---|
| 157 | status); | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status) | 
|---|
| 161 | : hash(0) | 
|---|
| 162 | { | 
|---|
| 163 | initSize(ignoreKeyCase ? uhash_hashCaselessUnicodeString | 
|---|
| 164 | : uhash_hashUnicodeString, | 
|---|
| 165 | ignoreKeyCase ? uhash_compareCaselessUnicodeString | 
|---|
| 166 | : uhash_compareUnicodeString, | 
|---|
| 167 | NULL, size, | 
|---|
| 168 | status); | 
|---|
| 169 | } | 
|---|
| 170 |  | 
|---|
| 171 | inline Hashtable::Hashtable(UErrorCode& status) | 
|---|
| 172 | : hash(0) | 
|---|
| 173 | { | 
|---|
| 174 | init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status); | 
|---|
| 175 | } | 
|---|
| 176 |  | 
|---|
| 177 | inline Hashtable::Hashtable() | 
|---|
| 178 | : hash(0) | 
|---|
| 179 | { | 
|---|
| 180 | UErrorCode status = U_ZERO_ERROR; | 
|---|
| 181 | init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status); | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | inline Hashtable::~Hashtable() { | 
|---|
| 185 | if (hash != NULL) { | 
|---|
| 186 | uhash_close(hash); | 
|---|
| 187 | } | 
|---|
| 188 | } | 
|---|
| 189 |  | 
|---|
| 190 | inline UObjectDeleter *Hashtable::setValueDeleter(UObjectDeleter *fn) { | 
|---|
| 191 | return uhash_setValueDeleter(hash, fn); | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 | inline int32_t Hashtable::count() const { | 
|---|
| 195 | return uhash_count(hash); | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | inline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) { | 
|---|
| 199 | return uhash_put(hash, new UnicodeString(key), value, &status); | 
|---|
| 200 | } | 
|---|
| 201 |  | 
|---|
| 202 | inline int32_t Hashtable::puti(const UnicodeString& key, int32_t value, UErrorCode& status) { | 
|---|
| 203 | return uhash_puti(hash, new UnicodeString(key), value, &status); | 
|---|
| 204 | } | 
|---|
| 205 |  | 
|---|
| 206 | inline void* Hashtable::get(const UnicodeString& key) const { | 
|---|
| 207 | return uhash_get(hash, &key); | 
|---|
| 208 | } | 
|---|
| 209 |  | 
|---|
| 210 | inline int32_t Hashtable::geti(const UnicodeString& key) const { | 
|---|
| 211 | return uhash_geti(hash, &key); | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | inline void* Hashtable::remove(const UnicodeString& key) { | 
|---|
| 215 | return uhash_remove(hash, &key); | 
|---|
| 216 | } | 
|---|
| 217 |  | 
|---|
| 218 | inline int32_t Hashtable::removei(const UnicodeString& key) { | 
|---|
| 219 | return uhash_removei(hash, &key); | 
|---|
| 220 | } | 
|---|
| 221 |  | 
|---|
| 222 | inline const UHashElement* Hashtable::find(const UnicodeString& key) const { | 
|---|
| 223 | return uhash_find(hash, &key); | 
|---|
| 224 | } | 
|---|
| 225 |  | 
|---|
| 226 | inline const UHashElement* Hashtable::nextElement(int32_t& pos) const { | 
|---|
| 227 | return uhash_nextElement(hash, &pos); | 
|---|
| 228 | } | 
|---|
| 229 |  | 
|---|
| 230 | inline void Hashtable::removeAll(void) { | 
|---|
| 231 | uhash_removeAll(hash); | 
|---|
| 232 | } | 
|---|
| 233 |  | 
|---|
| 234 | inline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){ | 
|---|
| 235 | return uhash_setKeyComparator(hash, keyComp); | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|
| 238 | inline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){ | 
|---|
| 239 | return uhash_setValueComparator(hash, valueComp); | 
|---|
| 240 | } | 
|---|
| 241 |  | 
|---|
| 242 | inline UBool Hashtable::equals(const Hashtable& that)const{ | 
|---|
| 243 | return uhash_equals(hash, that.hash); | 
|---|
| 244 | } | 
|---|
| 245 | U_NAMESPACE_END | 
|---|
| 246 |  | 
|---|
| 247 | #endif | 
|---|
| 248 |  | 
|---|
| 249 |  | 
|---|