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 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 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 Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status); 61 62 /** 63 * Construct a hashtable 64 * @param status Error code 65 */ 66 Hashtable(UErrorCode& status); 67 68 /** 69 * Construct a hashtable, _disregarding any error_. Use this constructor 70 * with caution. 71 */ 72 Hashtable(); 73 74 /** 75 * Non-virtual destructor; make this virtual if Hashtable is subclassed 76 * in the future. 77 */ 78 ~Hashtable(); 79 80 UObjectDeleter *setValueDeleter(UObjectDeleter *fn); 81 82 int32_t count() const; 83 84 void* put(const UnicodeString& key, void* value, UErrorCode& status); 85 86 int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status); 87 88 void* get(const UnicodeString& key) const; 89 90 int32_t geti(const UnicodeString& key) const; 91 92 void* remove(const UnicodeString& key); 93 94 int32_t removei(const UnicodeString& key); 95 96 void removeAll(void); 97 98 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 const UHashElement* nextElement(int32_t& pos) const; 105 106 UKeyComparator* setKeyComparator(UKeyComparator*keyComp); 107 108 UValueComparator* setValueComparator(UValueComparator* valueComp); 109 110 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