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