From 1202f9248def0a7f685700191d29e97c601c7500 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Tue, 9 Oct 2007 11:39:22 +0000 Subject: Added an actual vector version of CrawlHashTable, and removed the code for making a hash table imitate a vector. Since there's now more than just one type of savable/restorable container, hash.cc and hash.h have been renamed to store.cc and store.h ("store" for storage). Destroying/unlinking/deleting an item now clears out the item's props field. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2389 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/store.h | 402 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 crawl-ref/source/store.h (limited to 'crawl-ref/source/store.h') diff --git a/crawl-ref/source/store.h b/crawl-ref/source/store.h new file mode 100644 index 0000000000..b65298b514 --- /dev/null +++ b/crawl-ref/source/store.h @@ -0,0 +1,402 @@ +/* + * File: store.cc + * Summary: Saveable hash-table and vector capable of storing + * multiple types of data. + * Written by: Matthew Cline + * + * Modified for Crawl Reference by $Author$ on $Date$ + * + * Change History (most recent first): + + * <1> 10/5/07 MPC Created + */ + +#ifndef STORE_H +#define STORE_H + +#include +#include +#include +#include + +struct tagHeader; +class CrawlHashTable; +class CrawlVector; +class item_def; +class coord_def; + +typedef unsigned char hash_size; +typedef unsigned char vec_size; +typedef unsigned char store_flags; + +#define VEC_MAX_SIZE 255 +#define HASH_MAX_SIZE 255 + +// NOTE: Changing the ordering of these enums will break savefile +// compatibility. +enum store_val_type +{ + SV_NONE = 0, + SV_BOOL, + SV_BYTE, + SV_SHORT, + SV_LONG, + SV_FLOAT, + SV_STR, + SV_COORD, + SV_ITEM, + SV_HASH, + SV_VEC, + NUM_STORE_VAL_TYPES +}; + +enum store_flag_type +{ + SFLAG_UNSET = (1 << 0), + SFLAG_CONST_VAL = (1 << 1), + SFLAG_CONST_TYPE = (1 << 2), + SFLAG_NO_ERASE = (1 << 3) +}; + + +// Can't just cast everything into a void pointer, since a float might +// not fit into a pointer on all systems. +typedef union StoreUnion StoreUnion; +union StoreUnion +{ + bool boolean; + char byte; + short _short; + long _long; + float _float; + void* ptr; +}; + + +class CrawlStoreValue +{ +public: + CrawlStoreValue(); + CrawlStoreValue(const CrawlStoreValue &other); + + ~CrawlStoreValue(); + + // Conversion constructors + CrawlStoreValue(const bool val); + CrawlStoreValue(const char &val); + CrawlStoreValue(const short &val); + CrawlStoreValue(const long &val); + CrawlStoreValue(const float &val); + CrawlStoreValue(const std::string &val); + CrawlStoreValue(const char* val); + CrawlStoreValue(const coord_def &val); + CrawlStoreValue(const item_def &val); + CrawlStoreValue(const CrawlHashTable &val); + CrawlStoreValue(const CrawlVector &val); + + // Only needed for doing some assertion checking. + CrawlStoreValue &operator = (const CrawlStoreValue &other); + +protected: + store_val_type type; + store_flags flags; + StoreUnion val; + +public: + store_flags get_flags() const; + store_flags set_flags(store_flags flags); + store_flags unset_flags(store_flags flags); + store_val_type get_type() const; + + CrawlHashTable &new_table(store_flags flags); + CrawlHashTable &new_table(store_val_type type, store_flags flags = 0); + + CrawlVector &new_vector(store_flags flags, + vec_size max_size = VEC_MAX_SIZE); + CrawlVector &new_vector(store_val_type type, store_flags flags = 0, + vec_size max_size = VEC_MAX_SIZE); + + bool &get_bool(); + char &get_byte(); + short &get_short(); + long &get_long(); + float &get_float(); + std::string &get_string(); + coord_def &get_coord(); + CrawlHashTable &get_table(); + CrawlVector &get_vector(); + item_def &get_item(); + + bool get_bool() const; + char get_byte() const; + short get_short() const; + long get_long() const; + float get_float() const; + std::string get_string() const; + coord_def get_coord() const; + + const CrawlHashTable& get_table() const; + const CrawlVector& get_vector() const; + const item_def& get_item() const; + + void set_bool(const bool val); + void set_byte(const char val); + void set_short(const short val); + void set_long(const long val); + void set_float(const float val); + void set_string(const std::string &val); + void set_coord(const coord_def &val); + void set_table(const CrawlHashTable &val); + void set_vector(const CrawlVector &val); + void set_item(const item_def &val); + +public: + // NOTE: All operators will assert if the alue is of the wrong + // type for the operation. If the value has no type yet, the + // operation will set it to the appropriate type. If the value + // has no type yet and the operation modifies the existing value + // rather than replacing it (i.e., ++) the value will be set to a + // default before the operation is done. + + // If the value is a hash table or vector, the container's values + // can be accessed with the [] operator with the approriate key + // type (strings for hashes, longs for vectors). + CrawlStoreValue &operator [] (const std::string &key); + CrawlStoreValue &operator [] (const vec_size &index); + + const CrawlStoreValue &operator [] (const std::string &key) const; + const CrawlStoreValue &operator [] (const vec_size &index) const; + + // Typecast operators + &operator bool(); + &operator char(); + &operator short(); + &operator long(); + &operator float(); + &operator std::string(); + &operator coord_def(); + &operator CrawlHashTable(); + &operator CrawlVector(); + &operator item_def(); + + operator bool() const; + operator char() const; + operator short() const; + operator long() const; + operator float() const; + operator std::string() const; + operator coord_def() const; + + // Assignment operators + CrawlStoreValue &operator = (const bool &val); + CrawlStoreValue &operator = (const char &val); + CrawlStoreValue &operator = (const short &val); + CrawlStoreValue &operator = (const long &val); + CrawlStoreValue &operator = (const float &val); + CrawlStoreValue &operator = (const std::string &val); + CrawlStoreValue &operator = (const char* val); + CrawlStoreValue &operator = (const coord_def &val); + CrawlStoreValue &operator = (const CrawlHashTable &val); + CrawlStoreValue &operator = (const CrawlVector &val); + CrawlStoreValue &operator = (const item_def &val); + + // Misc operators + std::string &operator += (const std::string &val); + + // Prefix + long operator ++ (); + long operator -- (); + + // Postfix + long operator ++ (int); + long operator -- (int); + +protected: + CrawlStoreValue(const store_flags flags, + const store_val_type type = SV_NONE); + + void write(tagHeader &th) const; + void read(tagHeader &th); + + void unset(bool force = false); + + friend class CrawlHashTable; + friend class CrawlVector; +}; + + +// A hash table can have a maximum of 255 key/value pairs. If you +// want more than that you can use nested hash tables. +// +// By default a hash table's value data types are heterogeneous. To +// make it homogeneous (which causes dynamic type checking) you have +// to give a type to the hash table constructor; once it's been +// created it's type (or lack of type) is immutable. +// +// An empty hash table will take up only 1 byte in the savefile. A +// non-empty hash table will have an overhead of 3 bytes for the hash +// table overall and 2 bytes per key/value pair, over and above the +// number of bytes needed to store the keys and values themselves. +class CrawlHashTable +{ +public: + CrawlHashTable(); + CrawlHashTable(store_flags flags); + CrawlHashTable(store_val_type type, store_flags flags = 0); + + ~CrawlHashTable(); + + typedef std::map hash_map_type; + typedef hash_map_type::iterator iterator; + typedef hash_map_type::const_iterator const_iterator; + +protected: + store_val_type type; + store_flags default_flags; + hash_map_type hash_map; + + friend class CrawlStoreValue; + +public: + void write(tagHeader &th) const; + void read(tagHeader &th); + + store_flags get_default_flags() const; + store_flags set_default_flags(store_flags flags); + store_flags unset_default_flags(store_flags flags); + store_val_type get_type() const; + bool exists(const std::string key) const; + void assert_validity() const; + + // NOTE: If get_value() or [] is given a key which doesn't exist + // in the table, an unset/empty CrawlStoreValue will be created + // with that key and returned. If it is not then given a value + // then the next call to assert_validity() will fail. If the + // hash table has a type (rather than being heterogeneous) + // then trying to assign a different type to the CrawlStoreValue + // will assert. + CrawlStoreValue& get_value(const std::string &key); + CrawlStoreValue& operator[] (const std::string &key); + + // NOTE: If the const versions of get_value() or [] are given a + // key which doesn't exist, they will assert. + const CrawlStoreValue& get_value(const std::string &key) const; + const CrawlStoreValue& operator[] (const std::string &key) const; + + // std::map style interface + hash_size size() const; + bool empty() const; + + void erase(const std::string key); + void clear(); + + iterator begin(); + iterator end(); + + const_iterator begin() const; + const_iterator end() const; +}; + +// A CrawlVector is the vector version of CrawlHashTable, except that +// a non-empty CrawlVector has one more byte of savefile overhead that +// a hash table, and that can specify a maximum size to make it act +// similarly to a FixedVec. +class CrawlVector +{ +public: + CrawlVector(); + CrawlVector(store_flags flags, vec_size max_size = VEC_MAX_SIZE); + CrawlVector(store_val_type type, store_flags flags = 0, + vec_size max_size = VEC_MAX_SIZE); + + ~CrawlVector(); + + typedef std::vector vector_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + +protected: + store_val_type type; + store_flags default_flags; + vec_size max_size; + vector_type vector; + + friend class CrawlStoreValue; + +public: + void write(tagHeader &th) const; + void read(tagHeader &th); + + store_flags get_default_flags() const; + store_flags set_default_flags(store_flags flags); + store_flags unset_default_flags(store_flags flags); + store_val_type get_type() const; + void assert_validity() const; + void set_max_size(vec_size size); + vec_size get_max_size() const; + + CrawlStoreValue& get_value(const vec_size &index); + CrawlStoreValue& operator[] (const vec_size &index); + + // NOTE: If the const versions of get_value() or [] are given a + // index which doesn't exist, they will assert. + const CrawlStoreValue& get_value(const vec_size &index) const; + const CrawlStoreValue& operator[] (const vec_size &index) const; + + // std::vector style interface + vec_size size() const; + bool empty() const; + + // NOTE: push_back() and insert() have val passed by value rather + // than by reference so that coversion constructors will work. + CrawlStoreValue& pop_back(); + void push_back(CrawlStoreValue val); + void insert(const vec_size index, CrawlStoreValue val); + + // resize() will assert if the maximum size has been set. + void resize(const vec_size size); + void erase(const vec_size index); + void clear(); + + iterator begin(); + iterator end(); + + const_iterator begin() const; + const_iterator end() const; +}; + +// A wrapper for non-heterogeneous hash tables, so that the values can +// be accessed without using get_foo(). T needs to have both normal +// and const type-cast operators defined by CrawlStoreValue for this +// template to work. +template +class CrawlTableWrapper +{ +public: + CrawlTableWrapper(); + CrawlTableWrapper(CrawlHashTable& table); + CrawlTableWrapper(CrawlHashTable* table); + +protected: + CrawlHashTable* table; + +public: + void wrap(CrawlHashTable& table); + void wrap(CrawlHashTable* table); + + CrawlHashTable* get_table(); + T& operator[] (const std::string &key); + + const CrawlHashTable* get_table() const; + const T operator[] (const std::string &key) const; +}; + +typedef CrawlTableWrapper CrawlBoolTable; +typedef CrawlTableWrapper CrawlByteTable; +typedef CrawlTableWrapper CrawlShortTable; +typedef CrawlTableWrapper CrawlLongTable; +typedef CrawlTableWrapper CrawlFloatTable; +typedef CrawlTableWrapper CrawlStringTable; +typedef CrawlTableWrapper CrawlCoordTable; + +#endif -- cgit v1.2.3-54-g00ecf