--- parser3/src/include/pa_hash.h 2003/01/23 15:38:05 1.58.2.3 +++ parser3/src/include/pa_hash.h 2003/01/31 12:34:30 1.58.2.10 @@ -1,7 +1,7 @@ /** @file Parser: hash class decl. - Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ @@ -17,7 +17,7 @@ #ifndef PA_HASH_H #define PA_HASH_H -static const char* IDENT_HASH_H="$Date: 2003/01/23 15:38:05 $"; +static const char* IDENT_HASH_H="$Date: 2003/01/31 12:34:30 $"; #include "pa_pool.h" #include "pa_types.h" @@ -33,8 +33,8 @@ static const char* IDENT_HASH_H="$Date: template class Hash: public PA_Object { public: - typename K key_type; - typename V value_type; + typedef K key_type; + typedef V value_type; Hash() { allocated=allocates[allocates_index=0]; @@ -57,27 +57,12 @@ public: delete refs; } - /// useful generic hash function - static uint generic_code(uint aresult, const char *start, uint allocated) { - uint result=aresult, g; - const char *end=start+allocated; - - while (start>24); - result=result^g; - } - } - return result; - } - /// put a [value] under the [key] @returns existed or not - bool put(const K key, V value) { + bool put(K key, V value) { if(is_full()) expand(); - uint code=key.hash_code(); + uint code=hash_code(key); uint index=code%allocated; Pair **ref=&refs[index]; for(Pair *pair=*ref; pair; pair=pair->link) @@ -96,8 +81,8 @@ public: } /// remove the [key] @returns existed or not - bool remove(const K key) { - uint code=key.hash_code(); + bool remove(K key) { + uint code=hash_code(key); uint index=code%allocated; for(Pair **ref=&refs[index]; *ref; ref=&(*ref)->link) if((*ref)->code==code && (*ref)->key==key) { @@ -113,8 +98,8 @@ public: } /// get associated [value] by the [key] - V get(const K key) const { - uint code=key.hash_code(); + V get(K key) const { + uint code=hash_code(key); uint index=code%allocated; for(Pair *pair=refs[index]; pair; pair=pair->link) if(pair->code==code && pair->key==key) @@ -124,8 +109,8 @@ public: } /// put a [value] under the [key] if that [key] existed @returns existed or not - bool put_replace(const K key, V value) { - uint code=key.hash_code(); + bool put_replace(K key, V value) { + uint code=hash_code(key); uint index=code%allocated; for(Pair *pair=refs[index]; pair; pair=pair->link) if(pair->code==code && pair->key==key) { @@ -139,11 +124,11 @@ public: } /// put a [value] under the [key] if that [key] NOT existed @returns existed or not - bool put_dont_replace(const K key, V value) { + bool put_dont_replace(K key, V value) { if(is_full()) expand(); - uint code=key.hash_code(); + uint code=hash_code(key); uint index=code%allocated; Pair **ref=&refs[index]; for(Pair *pair=*ref; pair; pair=pair->link) @@ -179,23 +164,15 @@ public: callback(pair->key, pair->value, info); } - /// iterate over all pairs, passing references - template void for_each(void callback(K, V&, I), I info) const { - Pair **ref=refs; - for(int index=0; indexlink) - callback(pair->key, pair->value, info); - } - /// iterate over all pairs until condition becomes true, return that element - template V *first_that(bool callback(K, V, I), I info) const { + template V first_that(bool callback(K, V, I), I info) const { Pair **ref=refs; for(int index=0; indexlink) if(callback(pair->key, pair->value, info)) return &pair->value; - return 0; + return 0;//V(0) } /// remove all elements @@ -233,14 +210,13 @@ private: /// pair storage class Pair: public PA_Allocated { - //friend class Hash; - + public: uint code; - const K key; + K key; V value; Pair *link; - Pair(uint acode, const K akey, V avalue, Pair *alink) : + Pair(uint acode, K akey, V avalue, Pair *alink) : code(acode), key(akey), value(avalue), @@ -306,14 +282,29 @@ uint Hash::allocates[]={ template int Hash::allocates_count=sizeof(allocates)/sizeof(uint); +/// useful generic hash function +inline uint generic_hash_code(uint aresult, const char* start, uint allocated) { + uint result=aresult, g; + const char* end=start+allocated; + + while (start>24); + result=result^g; + } + } + return result; +} + /// Auto-object used to temporarily substituting/removing hash values template class Temp_hash_value { Hash& fhash; - const K fname; + K fname; V saved_value; public: - Temp_hash_value(Hash& ahash, const K aname, V avalue) : + Temp_hash_value(Hash& ahash, K aname, V avalue) : fhash(ahash), fname(aname), saved_value(ahash.get(aname)) {