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