From: <laz...@us...> - 2004-03-07 21:16:54
|
Update of /cvsroot/rtk/rtk/rtk In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32596/rtk Modified Files: Dict.h Added Files: TDict.h Log Message: - Added custom key support for Dict - template based (T)Dict classes - Int / Str Dict added --- NEW FILE: TDict.h --- /** * * RTK * Fast and easy cross-platform GUI ToolKit. * * Copyright (C) 2001-200x RTK Development Team * * This library is free software; you can redistribute it and/or modify it * under the terms of the slightly modified (see the "EXCEPTION NOTICE" part * of RTK Library License) GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * and along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA . * * Also you should have received a copy of RTK Library License, if not please * write an e-mail to some of RTK authors (listed in file AUTHORS). * * Bug reports: bu...@rt... * Suggestions: rf...@rt... ***************************************************************************/ /** * $Source: /cvsroot/rtk/rtk/rtk/TDict.h,v $ ***** * Authors (chronological order): * Mikko Lahteenmaki, mikko§rtk.cx * Contributors (chronological order): * $fname $lname, $email ***** * T0D0 List: * - ***************************************************************************/ #ifndef _RTK_TDICT_H_ #define _RTK_TDICT_H_ 1 #include "Dict.h" namespace Rtk { /** * Custom key Dict. * Custom KEY classes needs atleast functions: * - bool Compare(KEY *) * - Copy ctor * - uint Hash() */ template <class KEY, class VALUE> class TDict : public Dict { public: static void *KeyCopyTempl(KEY *key) { return new KEY(*key); } static void KeyFreeTempl(KEY *key) { delete key; } static bool KeyCmpTempl(KEY *i1, KEY *i2) { return i1->Compare(i2); } static uint HashTempl(KEY *key) { return key->Hash(); } static void FreeDataTempl(VALUE *val) { delete val; } VALUE error_return; TDict(uint size = DICT_LOOKUP_DEFAULT) : Dict((KeyCopyFunc)KeyCopyTempl, (KeyFreeFunc)KeyFreeTempl, (KeyCmpFunc)KeyCmpTempl, (HashFunc)HashTempl, (FreeDataFunc)FreeDataTempl, size) { //error_return = VALUE(); } bool Insert(const KEY &key, const VALUE &data, bool replace=true) { VALUE *val = new VALUE(data); bool ret = Dict::Insert((void*)&key, (void*)val, replace); if(!ret) delete val; return ret; } const VALUE &Replace(const KEY &key, void *data, bool insert=true) { VALUE *val = new VALUE(data); VALUE *ret = Dict::Replace((void*)&key, val, insert); if(!ret) { delete val; return error_return; } return *ret; } bool Contains(const KEY &key) const { return (Dict::Lookup((void*)&key)!=0); } bool Delete(const KEY &key) { return Dict::Delete((void*)&key); } const VALUE &Lookup(const KEY &key) const { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(ret) return *ret; return error_return; } /** * Lookup key 'key', if not found, key is added to Dict. * This is used by non-const operator[] */ VALUE &LookupInsert(const KEY &key) { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(!ret) { ret = new VALUE(); if(!Dict::Insert((void*)&key, (void*)ret)) delete ret; } return *ret; } VALUE &operator [](const KEY &key) { return LookupInsert(key); } const VALUE &operator [](const KEY &key) const { return Lookup(key); } }; template <class VALUE> class TIntDict : public Dict { public: static void FreeDataTempl(VALUE *val) { delete val; } VALUE error_return; TIntDict(uint size = DICT_LOOKUP_DEFAULT) : Dict(IntDict::KeyCopy, IntDict::KeyFree, IntDict::KeyCmp, IntDict::Hash, (FreeDataFunc)FreeDataTempl, size) { //error_return = VALUE(); } bool Insert(int key, const VALUE &data, bool replace=true) { VALUE *val = new VALUE(data); bool ret = Dict::Insert((void*)&key, (void*)val, replace); if(!ret) delete val; return ret; } const VALUE &Replace(int key, void *data, bool insert=true) { VALUE *val = new VALUE(data); VALUE *ret = Dict::Replace((void*)&key, val, insert); if(!ret) { delete val; return error_return; } return *ret; } bool Contains(int key) const { return (Dict::Lookup((void*)&key)!=0); } bool Delete(int key) { return Dict::Delete((void*)&key); } const VALUE &Lookup(int key) const { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(ret) return *ret; return error_return; } /** * Lookup key 'key', if not found, key is added to Dict. * This is used by non-const operator[] */ VALUE &LookupInsert(int key) { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(!ret) { ret = new VALUE(); if(!Dict::Insert((void*)&key, (void*)ret)) delete ret; } return *ret; } VALUE &operator [](int key) { return LookupInsert(key); } const VALUE &operator [](int key) const { return Lookup(key); } }; template <class VALUE> class TStrDict : public Dict { public: static void FreeDataTempl(VALUE *val) { delete val; } VALUE error_return; TStrDict(uint size = DICT_LOOKUP_DEFAULT) : Dict(StrDict::KeyCopy, StrDict::KeyFree, StrDict::KeyCmp, StrDict::Hash, (FreeDataFunc)FreeDataTempl, size) { //error_return = VALUE(); } bool Insert(const String &key, const VALUE &data, bool replace=true) { VALUE *val = new VALUE(data); bool ret = Dict::Insert((void*)&key, (void*)val, replace); if(!ret) delete val; return ret; } const VALUE &Replace(const String &key, void *data, bool insert=true) { VALUE *val = new VALUE(data); VALUE *ret = Dict::Replace((void*)&key, val, insert); if(!ret) { delete val; return error_return; } return *ret; } bool Contains(const String &key) const { return (Dict::Lookup((void*)&key)!=0); } bool Delete(const String &key) { return Dict::Delete((void*)&key); } const VALUE &Lookup(const String &key) const { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(ret) return *ret; return error_return; } /** * Lookup key 'key', if not found, key is added to Dict. * This is used by non-const operator[] */ VALUE &LookupInsert(const String &key) { VALUE *ret = (VALUE*)Dict::Lookup((void*)&key); if(!ret) { ret = new VALUE(); if(!Dict::Insert((void*)&key, (void*)ret)) delete ret; } return *ret; } VALUE &operator [](const String &key) { return LookupInsert(key); } const VALUE &operator [](const String &key) const { return Lookup(key); } }; }; // Rtk namespace #endif /** * $Id: TDict.h,v 1.1 2004/03/07 20:52:59 laza2000 Exp $ ***************************************************************************/ Index: Dict.h =================================================================== RCS file: /cvsroot/rtk/rtk/rtk/Dict.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Dict.h 14 Feb 2004 20:36:17 -0000 1.5 --- Dict.h 7 Mar 2004 20:52:59 -0000 1.6 *************** *** 45,50 **** //--------------------------------------------------------------------------- ! #include <rtk/Export.h> // needed for RTK_API ! #include <rtk/String.h> //--------------------------------------------------------------------------- --- 45,52 ---- //--------------------------------------------------------------------------- ! #include "conf.h" ! #include "rtkdef.h" ! #include "Export.h" // needed for RTK_API ! #include "String.h" //--------------------------------------------------------------------------- *************** *** 53,56 **** --- 55,65 ---- { + #define DICT_LOOKUP_SMALL 17 + #define DICT_LOOKUP_MEDIUM 101 + #define DICT_LOOKUP_BIG 1007 + #define DICT_LOOKUP_HUGE 10017 + + #define DICT_LOOKUP_DEFAULT DICT_LOOKUP_MEDIUM + /** * Dict object consists of an list of _DictNode structures. In literature *************** *** 62,70 **** typedef struct _DictNode { ! RCHAR *key; void *data; struct _DictNode *next; } DictNode; /// Dict free data handler. /// Called whenever DictNode object is removed from list. --- 71,85 ---- typedef struct _DictNode { ! void *key; void *data; struct _DictNode *next; } DictNode; + typedef uint (*HashFunc)(void *key); + + typedef void *(*KeyCopyFunc)(void *key); + typedef void (*KeyFreeFunc)(void *key); + typedef bool (*KeyCmpFunc)(void *i1, void *i2); + /// Dict free data handler. /// Called whenever DictNode object is removed from list. *************** *** 77,81 **** /// @param data Data associated with key /// @param user_data User decided pointer, passed in Dict::Enumrate ! typedef void (*DictEnumFunc)(const RCHAR *key, void *data, void *user_data); /** --- 92,96 ---- /// @param data Data associated with key /// @param user_data User decided pointer, passed in Dict::Enumrate ! typedef void (*DictEnumFunc)(void *key, void *data, void *user_data); /** *************** *** 86,94 **** public: // --------- CONSTRUCTORS ---------------------------------- - /** - * Default constructor. - */ - Dict(): m_size(0), m_count(0), m_free_func(0) { } - /** * This constructor should be actually used by default - to initialize --- 101,104 ---- *************** *** 100,145 **** * NOTE: This must be prime number, e.g. 17, 101... */ ! Dict(unsigned int size); // --------- DESTRUCTORS ----------------------------------- ! ~Dict() { this->Clear(); } // --------- GET METHODS ----------------------------------- /** * Returns number of items in the Dictionary. */ ! inline int GetCount() const { return this->m_count; } // --------- SET METHODS ----------------------------------- - // --------- OTHER METHODS --------------------------------- /** ! * Hashes a string 'string' and produces key of unsigned int type. */ ! static unsigned int Hash(const RCHAR *string); /** ! * Inserts key 'key' into Dict objects hash table. Note that ! * this function will not allow duplicate keys. * @return Boolean wheter data is added or not. */ ! bool Insert(const RCHAR *key, void *data); /** ! * Replaces key 'key' into Dict objects hash table. Note that ! * this function will not allow duplicate keys. ! * @param insert If key is not found Dict, it will be inserted. (default false) ! * @return Data associated with 'key' before. */ ! void *Replace(const RCHAR *key, void *data, bool insert=false); /** ! * Looks up for given key 'key' and (if there is any) and returns associated data. ! * @return void* Pointer to associated data, or NULL if the key is not in the hash table. */ ! void* Lookup(const RCHAR *key) const; /** --- 110,166 ---- * NOTE: This must be prime number, e.g. 17, 101... */ ! Dict(KeyCopyFunc keycopy_f, KeyFreeFunc keyfree_f, KeyCmpFunc keycmp_f, HashFunc hash_f, FreeDataFunc free_f, uint size); // --------- DESTRUCTORS ----------------------------------- ! ~Dict(); // --------- GET METHODS ----------------------------------- /** + * Get free data function. + */ + FreeDataFunc GetFreeDataFunc() { return _free_func; } + + /** * Returns number of items in the Dictionary. */ ! RTK_INLINE int GetCount() const { return _count; } // --------- SET METHODS ----------------------------------- /** ! * Set function to free content of element. ! * Function is called whenever element is removed from list. */ ! void SetFreeDataFunc(FreeDataFunc func) { _free_func = func; } ! ! // --------- OTHER METHODS --------------------------------- /** ! * Inserts key 'key' with value 'data' into Dict. ! * If key already exists, it is replaced, unless 'replace' is false (defaults true) * @return Boolean wheter data is added or not. */ ! bool Insert(void *key, void *data, bool replace=true); /** ! * Replaces the value of key 'key' with value 'data'. ! * If key is not found, it is added, unless 'insert' is false (defaults true) ! * @return Data associated with 'key' before, or NULL if no data before */ ! void *Replace(void *key, void *data, bool insert=true); /** ! * Perform Lookup for given key 'key' ! * @return Pointer to associated data, or NULL if the key is not found. */ ! void *Lookup(void *key) const; ! ! /** Check whether Dict contains key or not. ! * @return True if key is found in Dict ! */ ! RTK_INLINE bool Contains(void *key) const { return (Lookup(key)!=0); } /** *************** *** 147,181 **** * @return void* Associated data, or NULL if not present. */ ! void* Delete(RCHAR* key); ! ! /** ! * Used in destructor. ! */ ! int FreeNode(RCHAR *key, void *data); ! ! const void* operator [](const RCHAR* key) const { return this->Lookup(key); } ! void* operator [](const RCHAR* key) { return this->Lookup(key); } /** ! * Completely deletes all DictNodes in Dict object. */ void Clear(); ! /** ! * It calls given function 'func' for every DictNode in Dict object, and ! * passes DictNode's associated data and the key to that function. */ void Enumerate(DictEnumFunc func, void *user_data = 0); - protected: - unsigned int m_size; - unsigned int m_count; - DictNode **m_table; - FreeDataFunc m_free_func; /// Free data function - private: }; // Dict class }; // Rtk namespace --- 168,238 ---- * @return void* Associated data, or NULL if not present. */ ! bool Delete(void* key); /** ! * Delete all nodes in Dict */ void Clear(); ! /** Enumrate all items in Dict. ! * It calls given function 'func' for every node in Dict, and ! * passes DictNode's associated value and the key to that function. */ void Enumerate(DictEnumFunc func, void *user_data = 0); private: + RTK_INLINE uint Hash(void *key) const { return (*_hash_func)(key) % (_size-1); } + + unsigned int _size; + unsigned int _count; + DictNode ** _table; + + FreeDataFunc _free_func; + HashFunc _hash_func; + + KeyCopyFunc _keycopy_func; + KeyFreeFunc _keyfree_func; + KeyCmpFunc _keycmp_func; }; // Dict class + class RTK_API StrDict : public Dict + { + public: + static void *KeyCopy(void *key); + static void KeyFree(void *key); + static bool KeyCmp(void *i1, void *i2); + static uint Hash(void *key); + + StrDict(uint size = DICT_LOOKUP_DEFAULT); + + RTK_INLINE bool Insert(const String &key, void *data, bool replace=true) { return Dict::Insert((void*)&key, data, replace); } + RTK_INLINE void *Replace(const String &key, void *data, bool insert=true) { return Dict::Replace((void*)&key, data, insert); } + RTK_INLINE void *Lookup(const String &key) const { return Dict::Lookup((void*)&key); } + RTK_INLINE bool Contains(const String &key) const { return (Lookup(key)!=0); } + RTK_INLINE bool Delete(const String &key) { return Dict::Delete((void*)&key); } + + void *operator [](const String &key) const { return Lookup(key); } + }; + + class RTK_API IntDict : public Dict + { + public: + static void *KeyCopy(void *key); + static void KeyFree(void *key); + static bool KeyCmp(void *i1, void *i2); + static uint Hash(void *key); + + IntDict(uint size = DICT_LOOKUP_DEFAULT); + + RTK_INLINE bool Insert(int key, void *data, bool replace=true) { return Dict::Insert((void*)&key, data, replace); } + RTK_INLINE void *Replace(int key, void *data, bool insert=true) { return Dict::Replace((void*)&key, data, insert); } + RTK_INLINE void *Lookup(int key) const { return Dict::Lookup((void*)&key); } + RTK_INLINE bool Contains(int key) const { return (Lookup(key)!=0); } + RTK_INLINE bool Delete(int key) { return Dict::Delete((void*)&key); } + + void *operator [](int key) const { return Lookup(key); } + }; + }; // Rtk namespace |