home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
- * Copyright (c) 1991 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Stanford and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Stanford and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- *
- * 12.8.92 Christoph Streit: remove_all function added
- * modified for own purposes
- *
- * Generic object association table.
- */
-
- #ifndef Table_H
- #define Table_H
-
- #include "Hash.h"
- #include "rcString.h"
-
- #if defined(__STDC__) || defined(__ANSI_CPP__) || defined(__DECCXX)
- #define __TableEntry(Table) Table##_Entry
- #define TableEntry(Table) __TableEntry(Table)
- #define __TableIterator(Table) Table##_Iterator
- #define TableIterator(Table) __TableIterator(Table)
- #else
- #define __TableEntry(Table) Table/**/_Entry
- #define TableEntry(Table) __TableEntry(Table)
- #define __TableIterator(Table) Table/**/_Iterator
- #define TableIterator(Table) __TableIterator(Table)
- #endif
-
-
- #define declareTable(Table,Key,Value) \
- class TableEntry(Table); \
- \
- class Table { \
- public: \
- Table(int); \
- ~Table(); \
- \
- int insert(const Key&, const Value&); \
- int find(const Key&); \
- int find_and_replace(const Key&, const Value&); \
- int find_and_remove(const Key&, Value&); \
- int lookup(const Key&, Value&); \
- void remove(const Key&); \
- void remove_all(); \
- private: \
- friend class TableIterator(Table); \
- \
- int size_; \
- TableEntry(Table)** first_; \
- TableEntry(Table)** last_; \
- \
- TableEntry(Table)*&probe(const Key&); \
- }; \
- \
- class TableEntry(Table) { \
- private: \
- friend class Table; \
- friend class TableIterator(Table); \
- \
- Key key_; \
- Value value_; \
- TableEntry(Table)* chain_; \
- }; \
- \
- class TableIterator(Table) { \
- public: \
- TableIterator(Table)(const Table&); \
- \
- Key& cur_key(); \
- Value& cur_value(); \
- int more(); \
- int next(); \
- private: \
- TableEntry(Table)* cur_; \
- TableEntry(Table)** entry_; \
- TableEntry(Table)** last_; \
- }; \
- \
- inline Key& TableIterator(Table)::cur_key() { return cur_->key_; } \
- inline Value& TableIterator(Table)::cur_value() { return cur_->value_; } \
- inline int TableIterator(Table)::more() { return entry_ <= last_; }
-
- /*
- * Predefined hash functions
- */
-
- inline unsigned long key_to_hash(long k) { return (unsigned long)k; }
- //inline unsigned long key_to_hash(const void* k) { return (unsigned long)k; }
- //inline unsigned long key_to_hash(const char* k)
- //{ return (unsigned long)hash(k); }
- inline unsigned long key_to_hash(const rcString& k)
- { return (unsigned long)hash((const char*) k); }
-
- /*
- * Table implementation
- */
-
- #define implementTable(Table,Key,Value) \
- Table::Table(int n) { \
- for (size_ = 32; size_ < n; size_ <<= 1); \
- first_ = new TableEntry(Table)*[size_]; \
- --size_; \
- last_ = &first_[size_]; \
- for (register TableEntry(Table)** e = first_; e <= last_; e++) { \
- *e = NULL; \
- } \
- } \
- \
- Table::~Table() { \
- delete first_; \
- } \
- \
- inline TableEntry(Table)*& Table::probe(const Key &i) { \
- return first_[key_to_hash(i) & size_]; \
- } \
- \
- int Table::insert(const Key& k, const Value &v) { \
- if (find(k)) return 0; \
- \
- register TableEntry(Table)* e = new TableEntry(Table); \
- e->key_ = k; \
- e->value_ = v; \
- register TableEntry(Table)** a = &probe(k); \
- e->chain_ = *a; \
- *a = e; \
- return 1;\
- } \
- \
- int Table::lookup(const Key &k, Value &v) { \
- for (register TableEntry(Table)* e = probe(k); e != NULL; e = e->chain_) { \
- if (e->key_ == k) { \
- v = e->value_; \
- return 1; \
- } \
- } \
- return 0; \
- } \
- \
- int Table::find(const Key &k) { \
- for (register TableEntry(Table)* e = probe(k); e != NULL; e = e->chain_) { \
- if (e->key_ == k) { \
- return 1; \
- } \
- } \
- return 0; \
- } \
- \
- int Table::find_and_replace(const Key& k, const Value& v) { \
- for (register TableEntry(Table)* e = probe(k); e != NULL; e = e->chain_) { \
- if (e->key_ == k) { \
- e->value_ = v; \
- return 1; \
- } \
- } \
- return 0; \
- } \
- \
- int Table::find_and_remove(const Key& k, Value& v) { \
- TableEntry(Table)** a = &probe(k); \
- register TableEntry(Table)* e = *a; \
- if (e != NULL) { \
- if (e->key_ == k) { \
- v = e->value_; \
- *a = e->chain_; \
- delete e; \
- return 1; \
- } else { \
- register TableEntry(Table)* prev; \
- do { \
- prev = e; \
- e = e->chain_; \
- } while (e != NULL && e->key_ != k); \
- if (e != NULL) { \
- v = e->value_; \
- prev->chain_ = e->chain_; \
- delete e; \
- return 1; \
- } \
- } \
- } \
- return 0; \
- } \
- \
- void Table::remove(const Key &k) { \
- TableEntry(Table)** a = &probe(k); \
- register TableEntry(Table)* e = *a; \
- if (e != NULL) { \
- if (e->key_ == k) { \
- *a = e->chain_; \
- delete e; \
- } else { \
- register TableEntry(Table)* prev; \
- do { \
- prev = e; \
- e = e->chain_; \
- } while (e != NULL && e->key_ != k); \
- if (e != NULL) { \
- prev->chain_ = e->chain_; \
- delete e; \
- } \
- } \
- } \
- } \
- \
- void Table::remove_all() \
- { \
- TableIterator(Table) ti(*this); \
- while (ti.more()) \
- { \
- remove(ti.cur_key()); \
- ti.next(); \
- } \
- } \
- \
- TableIterator(Table)::TableIterator(Table)(const Table& t) { \
- last_ = t.last_; \
- for (entry_ = t.first_; entry_ <= last_; entry_++) { \
- cur_ = *entry_; \
- if (cur_ != NULL) { \
- break; \
- } \
- } \
- } \
- \
- int TableIterator(Table)::next() { \
- cur_ = cur_->chain_; \
- if (cur_ != NULL) { \
- return 1; \
- } \
- for (++entry_; entry_ <= last_; entry_++) { \
- cur_ = *entry_; \
- if (cur_ != NULL) { \
- return 1; \
- } \
- } \
- return 0; \
- }
-
- #endif // Table_H
-
-
-
-
-