#ifndef __ASSOC_H #define __ASSOC_H #ifndef __STRINGS_H #include #endif // @doc INTERNAL // @class THash_object | Classe per la definizione degli elementi di una tabella hash. // // @base public | TObject class THash_object : public TObject // @author:(INTERNAL) Guido { // @cfriend TAssoc_array friend class TAssoc_array; // @access:(INTERNAL) Private Member // @cmember:(INTERNAL) Chiave d'ordinamento TString _key; // @cmember:(INTERNAL) Oggetto da memorizzare TObject* _obj; // @access Public Member public: // @cmember Ritorna la chiave di ordinamento const TString& key() const { return _key; } // @cmember Ritorna l'oggetto TObject& obj() const { return *_obj; } TObject* remove_obj() { TObject* o = _obj; _obj = NULL; return o; } // @cmember Costruttore (inizializza la chiave ed opzionalmente l'oggetto) THash_object(const char* k, TObject* o = NULL) : _key(k), _obj(o) {} // @cmember Distruttore virtual ~THash_object(); }; // @doc EXTERNAL // @class TAssoc_array | Tabella hash di oggetti generici // // @base public |TObject class TAssoc_array : public TContainer // @author:(INTERNAL) Guido //@access:(INTERNAL) Private Member { // @cmember:(INTERNAL) Numero di oggetti contenuti nella tabella word _cnt; // @cmember:(INTERNAL) Numero di righe della tabella hash word _row; // @cmember:(INTERNAL) Numero di colonne della tabella hash word _col; // @cmember:(INTERNAL) Numero di righe della tabella hash per i metodi _item int _rowitem; // @cmember:(INTERNAL) Numero di colonne della tabella hash per i metodi _item int _colitem; // @cmember:(INTERNAL) Array contenente i dati veri e propri TArray _bucket; // @access Protected member protected: TArray& bucket(int index); // @cmember Cerca l'oggetto con chiave k THash_object* _lookup(const char* k, bool& isnew, bool insert = FALSE); // @cmember Copia tutto l'array associativo e ne duplica gli elementi TAssoc_array & copy(const TAssoc_array & a); // @access Public Member public: // @cmember Duplica l'array associativo copiandone gli elementi. virtual TObject* dup () const { return new TAssoc_array(*this);} // @cmember Ritorna un puntatore al primo oggetto virtual TObject* first_item( ); // @cmember Ritorna un puntatore all'ultimo oggetto virtual TObject* last_item( ); // @cmember Ritorna un puntatore all'oggetto successivo al quello corrente virtual TObject* succ_item( ); // @cmember Ritorna un puntatore all'oggetto che precede quello corrente virtual TObject* pred_item( ); // @cmember Ritorna un puntatore ad un THash_object casuale (anche NULL) THash_object* random_hash_object(); // @cmember Ritorna il numero di elementi presenti come long virtual long objects() const { return _cnt; } // @cmember Ritorna il numero di elementi presenti int items() const { return _cnt; } // @cmember Cancella tutti gli elementi virtual void destroy(); // @cmember Aggiunge un oggetto. Se era gia' presente guarda il parametro force bool add(const char* key, TObject* obj = NULL, bool force = false); // @cmember Aggiunge una copia dell'oggetto bool add(const char* key, const TObject& obj, bool force = false); // @cmember Elimina un oggetto bool remove(const char* key); // @cmember Controlla l'esistenza di una chiave bool is_key(const char* key) const ; // @cmember Ritorna l'oggetto con chiave key TObject* objptr(const char* key) const ; // @cmember Trova l'oggetto indicizzato TObject& find(const char* key) const ; // @cmember Ritorna l'indice del oggetto con chiave key (piu' intuitivo di ) TObject& operator[] (const char* key) const { return find(key); } // iterazione come TToken_string // si puo' adoperare get() e get_hashobj() intercambiabilmente ma // non sono indipendenti (entrambe avanzano gli stessi contatori) // @cmember Azzera il numero di riga e colonna corrente della tabella hash void restart() { _row = 0; _col = 0; } // @cmember Ritorna solo l'oggetto TObject* get(); // @cmember Ritorna l'oggetto e la relativa chiave THash_object* get_hashobj(); bool get_bool(const char* key) const; int get_int(const char* key) const; const TString& get_str(const char* key) const; // @cmember Mette chiavi e opzionalmente valori (come stringa) nel passato int get_keys(TString_array& kl, bool add_values = false); // @cmember Operatore di assegnamento tra array associativi TAssoc_array& operator= (const TAssoc_array & a) { return copy(a); } // @cmember Costruttore TAssoc_array() : _cnt(0), _row(0), _col(0) {} // @cmember Costruttore. Copia tutto l'array associativo e ne duplica gli elementi TAssoc_array(const TAssoc_array& a) : _cnt(0), _row(0), _col(0) { copy(a); } // @cmember Distruttore virtual ~TAssoc_array() { destroy(); } }; class TCache : public TObject { TArray _data; protected: virtual void discarding(const THash_object* obj); virtual TObject* key2obj(const char* key) pure; public: TObject* objptr(const TString& key); TObject* objptr(size_t nkey); bool empty() const { return _data.empty(); } void destroy(); // Not very useful, but who knows? TCache(size_t size = 0); // 883 assigned by default virtual ~TCache(); }; /* __ass = TAssoc_array da scandire __obj = variabile del cazzo che serve internamente al ciclo; va nominata e dimenticata __key = nome della variabile del record corrente dell'Assoc (primo campo) __str = valore del record corrente dell'Assoc (secondo campo) Es: TAssoc_array ass; TString str; FOR_EACH_ASSOC_STRING(ass, ho, k, str) { usa in qualche modo k e str presi da ass; } */ #define FOR_EACH_ASSOC_STRING(__ass, __obj, __key, __str) \ const char *__key, *__str; __ass.restart(); \ for (THash_object* __obj = __ass.get_hashobj(); \ __obj && ((__str = (const TString&)__obj->obj()) != NULL, __obj && (__key = __obj->key()) != NULL); \ __obj = __ass.get_hashobj()) #define FOR_EACH_ASSOC_OBJECT(__ass, __obj, __key, __itm) \ const char *__key; TObject* __itm; __ass.restart(); \ for (THash_object* __obj = __ass.get_hashobj(); \ __obj && (__itm = &__obj->obj()) != NULL, __obj && (__key = __obj->key()) != NULL; \ __obj = __ass.get_hashobj()) #endif