Home | History | Annotate | Download | only in common
      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