Apply the new ground_level method.
[crawl.git] / crawl-ref / source / store.h
blob9f4ba3c6237a273159898e3cb1c8b977580a0b0a
1 /*
2 * File: store.h
3 * Summary: Saveable hash-table and vector capable of storing
4 * multiple types of data.
5 * Written by: Matthew Cline
6 */
8 #ifndef STORE_H
9 #define STORE_H
11 #include <limits.h>
12 #include <map>
13 #include <string>
14 #include <vector>
16 class reader;
17 class writer;
18 class CrawlHashTable;
19 class CrawlVector;
20 struct item_def;
21 struct coord_def;
22 struct level_pos;
23 class level_id;
24 class dlua_chunk;
25 class monster;
27 typedef uint8_t hash_size;
28 typedef uint8_t vec_size;
29 typedef uint8_t store_flags;
31 #define VEC_MAX_SIZE 255
32 #define HASH_MAX_SIZE 255
34 // NOTE: Changing the ordering of these enums will break savefile
35 // compatibility.
36 enum store_val_type
38 SV_NONE = 0,
39 SV_BOOL,
40 SV_BYTE,
41 SV_SHORT,
42 SV_INT,
43 SV_FLOAT,
44 SV_STR,
45 SV_COORD,
46 SV_ITEM,
47 SV_HASH,
48 SV_VEC,
49 SV_LEV_ID,
50 SV_LEV_POS,
51 SV_MONST,
52 SV_LUA,
53 SV_INT64,
54 NUM_STORE_VAL_TYPES
57 enum store_flag_type
59 SFLAG_UNSET = (1 << 0),
60 SFLAG_CONST_VAL = (1 << 1),
61 SFLAG_CONST_TYPE = (1 << 2),
62 SFLAG_NO_ERASE = (1 << 3),
66 // Can't just cast everything into a void pointer, since a float might
67 // not fit into a pointer on all systems.
68 typedef union StoreUnion StoreUnion;
69 union StoreUnion
71 bool boolean;
72 char byte;
73 short _short;
74 int _int;
75 float _float;
76 int64_t _int64;
77 void* ptr;
81 class CrawlStoreValue
83 public:
84 CrawlStoreValue();
85 CrawlStoreValue(const CrawlStoreValue &other);
87 ~CrawlStoreValue();
89 // Conversion constructors
90 CrawlStoreValue(const bool val);
91 CrawlStoreValue(const char &val);
92 CrawlStoreValue(const short &val);
93 CrawlStoreValue(const int &val);
94 CrawlStoreValue(const int64_t &val);
95 CrawlStoreValue(const float &val);
96 CrawlStoreValue(const std::string &val);
97 CrawlStoreValue(const char* val);
98 CrawlStoreValue(const coord_def &val);
99 CrawlStoreValue(const item_def &val);
100 CrawlStoreValue(const CrawlHashTable &val);
101 CrawlStoreValue(const CrawlVector &val);
102 CrawlStoreValue(const level_id &val);
103 CrawlStoreValue(const level_pos &val);
104 CrawlStoreValue(const monster& val);
105 CrawlStoreValue(const dlua_chunk &val);
107 CrawlStoreValue &operator = (const CrawlStoreValue &other);
109 protected:
110 store_val_type type;
111 store_flags flags;
112 StoreUnion val;
114 public:
115 store_flags get_flags() const;
116 store_flags set_flags(store_flags flags);
117 store_flags unset_flags(store_flags flags);
118 store_val_type get_type() const;
120 CrawlHashTable &new_table();
122 CrawlVector &new_vector(store_flags flags,
123 vec_size max_size = VEC_MAX_SIZE);
124 CrawlVector &new_vector(store_val_type type, store_flags flags = 0,
125 vec_size max_size = VEC_MAX_SIZE);
127 bool &get_bool();
128 char &get_byte();
129 short &get_short();
130 int &get_int();
131 int64_t &get_int64();
132 float &get_float();
133 std::string &get_string();
134 coord_def &get_coord();
135 CrawlHashTable &get_table();
136 CrawlVector &get_vector();
137 item_def &get_item();
138 level_id &get_level_id();
139 level_pos &get_level_pos();
140 monster &get_monster();
141 dlua_chunk &get_lua();
143 bool get_bool() const;
144 char get_byte() const;
145 short get_short() const;
146 int get_int() const;
147 int64_t get_int64() const;
148 float get_float() const;
149 std::string get_string() const;
150 coord_def get_coord() const;
151 level_id get_level_id() const;
152 level_pos get_level_pos() const;
154 const CrawlHashTable& get_table() const;
155 const CrawlVector& get_vector() const;
156 const item_def& get_item() const;
157 const monster& get_monster() const;
158 const dlua_chunk& get_lua() const;
160 public:
161 // NOTE: All operators will assert if the value is of the wrong
162 // type for the operation. If the value has no type yet, the
163 // operation will set it to the appropriate type. If the value
164 // has no type yet and the operation modifies the existing value
165 // rather than replacing it (e.g., ++) the value will be set to a
166 // default before the operation is done.
168 // If the value is a hash table or vector, the container's values
169 // can be accessed with the [] operator with the approriate key
170 // type (strings for hashes, longs for vectors).
171 CrawlStoreValue &operator [] (const std::string &key);
172 CrawlStoreValue &operator [] (const vec_size &index);
174 const CrawlStoreValue &operator [] (const std::string &key) const;
175 const CrawlStoreValue &operator [] (const vec_size &index) const;
177 // Typecast operators
178 operator bool&();
179 operator char&();
180 operator short&();
181 operator int&();
182 operator int64_t&();
183 operator float&();
184 operator std::string&();
185 operator coord_def&();
186 operator CrawlHashTable&();
187 operator CrawlVector&();
188 operator item_def&();
189 operator level_id&();
190 operator level_pos&();
191 operator monster& ();
192 operator dlua_chunk&();
194 operator bool() const;
195 operator char() const;
196 operator short() const;
197 operator int() const;
198 operator int64_t() const;
199 operator float() const;
200 operator std::string() const;
201 operator coord_def() const;
202 operator level_id() const;
203 operator level_pos() const;
205 // Assignment operators
206 CrawlStoreValue &operator = (const bool &val);
207 CrawlStoreValue &operator = (const char &val);
208 CrawlStoreValue &operator = (const short &val);
209 CrawlStoreValue &operator = (const int &val);
210 CrawlStoreValue &operator = (const int64_t &val);
211 CrawlStoreValue &operator = (const float &val);
212 CrawlStoreValue &operator = (const std::string &val);
213 CrawlStoreValue &operator = (const char* val);
214 CrawlStoreValue &operator = (const coord_def &val);
215 CrawlStoreValue &operator = (const CrawlHashTable &val);
216 CrawlStoreValue &operator = (const CrawlVector &val);
217 CrawlStoreValue &operator = (const item_def &val);
218 CrawlStoreValue &operator = (const level_id &val);
219 CrawlStoreValue &operator = (const level_pos &val);
220 CrawlStoreValue &operator = (const monster& val);
221 CrawlStoreValue &operator = (const dlua_chunk &val);
223 // Misc operators
224 std::string &operator += (const std::string &val);
226 // Prefix
227 int operator ++ ();
228 int operator -- ();
230 // Postfix
231 int operator ++ (int);
232 int operator -- (int);
234 protected:
235 CrawlStoreValue(const store_flags flags,
236 const store_val_type type = SV_NONE);
238 void write(writer &) const;
239 void read(reader &);
241 void unset(bool force = false);
243 friend class CrawlHashTable;
244 friend class CrawlVector;
248 // A hash table can have a maximum of 255 key/value pairs. If you
249 // want more than that you can use nested hash tables.
251 // By default a hash table's value data types are heterogeneous. To
252 // make it homogeneous (which causes dynamic type checking) you have
253 // to give a type to the hash table constructor; once it's been
254 // created its type (or lack of type) is immutable.
256 // An empty hash table will take up only 1 byte in the savefile. A
257 // non-empty hash table will have an overhead of 3 bytes for the hash
258 // table overall and 2 bytes per key/value pair, over and above the
259 // number of bytes needed to store the keys and values themselves.
260 class CrawlHashTable
262 public:
263 CrawlHashTable();
264 CrawlHashTable(const CrawlHashTable& other);
266 ~CrawlHashTable();
268 typedef std::map<std::string, CrawlStoreValue> hash_map_type;
269 typedef hash_map_type::iterator iterator;
270 typedef hash_map_type::const_iterator const_iterator;
272 protected:
273 // NOTE: Not using std::auto_ptr because making hash_map an auto_ptr
274 // causes compile weirdness in externs.h
275 hash_map_type *hash_map;
277 void init_hash_map();
279 friend class CrawlStoreValue;
281 public:
282 CrawlHashTable &operator = (const CrawlHashTable &other);
284 void write(writer &) const;
285 void read(reader &);
287 bool exists(const std::string &key) const;
288 void assert_validity() const;
290 // NOTE: If the const versions of get_value() or [] are given a
291 // key which doesn't exist, they will assert.
292 const CrawlStoreValue& get_value(const std::string &key) const;
293 const CrawlStoreValue& operator[] (const std::string &key) const;
295 // NOTE: If get_value() or [] is given a key which doesn't exist
296 // in the table, an unset/empty CrawlStoreValue will be created
297 // with that key and returned. If it is not then given a value
298 // then the next call to assert_validity() will fail. If the
299 // hash table has a type (rather than being heterogeneous)
300 // then trying to assign a different type to the CrawlStoreValue
301 // will assert.
302 CrawlStoreValue& get_value(const std::string &key);
303 CrawlStoreValue& operator[] (const std::string &key);
305 // std::map style interface
306 hash_size size() const;
307 bool empty() const;
309 void erase(const std::string key);
310 void clear();
312 const_iterator begin() const;
313 const_iterator end() const;
315 iterator begin();
316 iterator end();
319 // A CrawlVector is the vector version of CrawlHashTable, except that
320 // a non-empty CrawlVector has one more byte of savefile overhead that
321 // a hash table, and that can specify a maximum size to make it act
322 // similarly to a FixedVec.
323 class CrawlVector
325 public:
326 CrawlVector();
327 CrawlVector(store_flags flags, vec_size max_size = VEC_MAX_SIZE);
328 CrawlVector(store_val_type type, store_flags flags = 0,
329 vec_size max_size = VEC_MAX_SIZE);
331 ~CrawlVector();
333 typedef std::vector<CrawlStoreValue> vector_type;
334 typedef vector_type::iterator iterator;
335 typedef vector_type::const_iterator const_iterator;
337 protected:
338 store_val_type type;
339 store_flags default_flags;
340 vec_size max_size;
341 vector_type vector;
343 friend class CrawlStoreValue;
345 public:
346 void write(writer &) const;
347 void read(reader &);
349 store_flags get_default_flags() const;
350 store_flags set_default_flags(store_flags flags);
351 store_flags unset_default_flags(store_flags flags);
352 store_val_type get_type() const;
353 void assert_validity() const;
354 void set_max_size(vec_size size);
355 vec_size get_max_size() const;
357 // NOTE: If the const versions of get_value() or [] are given an
358 // index which doesn't exist, they will assert.
359 const CrawlStoreValue& get_value(const vec_size &index) const;
360 const CrawlStoreValue& operator[] (const vec_size &index) const;
362 CrawlStoreValue& get_value(const vec_size &index);
363 CrawlStoreValue& operator[] (const vec_size &index);
365 // std::vector style interface
366 vec_size size() const;
367 bool empty() const;
369 // NOTE: push_back() and insert() have val passed by value rather
370 // than by reference so that conversion constructors will work.
371 CrawlStoreValue& pop_back();
372 void push_back(CrawlStoreValue val);
373 void insert(const vec_size index, CrawlStoreValue val);
375 // resize() will assert if the maximum size has been set.
376 void resize(const vec_size size);
377 void erase(const vec_size index);
378 void clear();
380 const_iterator begin() const;
381 const_iterator end() const;
383 iterator begin();
384 iterator end();
386 #endif