/home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/hash.hpp Source File

Ratpac-two: /home/docs/checkouts/readthedocs.org/user_builds/ratpac/checkouts/latest/src/external/stlplus/include/stlplus/hash.hpp Source File
Ratpac-two
hash.hpp
1 #ifndef HASH_HPP
2 #define HASH_HPP
3 /*----------------------------------------------------------------------------
4 
5  Author: Andy Rushton
6  Copyright: (c) Andy Rushton, 2004
7  License: BSD License, see ../docs/license.html
8 
9  A chained hash table using STL semantics
10 
11 ------------------------------------------------------------------------------*/
12 #include <map>
13 
14 #include "exceptions.hpp"
15 #include "os_fixes.hpp"
16 #include "persistent.hpp"
17 #include "textio.hpp"
18 
19 namespace stlplus {
21 // internals
22 
23 template <typename K, typename T, class H, class E>
24 class hash;
25 template <typename K, typename T>
27 
29 // iterator class
30 
31 template <typename K, typename T, class H, class E, typename V>
33  public:
34  friend class hash<K, T, H, E>;
35 
36  // local type definitions
37  // an iterator points to a value whilst a const_iterator points to a const value
38  typedef V value_type;
42  typedef V& reference;
43  typedef V* pointer;
44 
45  // constructor to create a null iterator - you must assign a valid value to this iterator before using it
46  // any attempt to dereference or use a null iterator is an error
47  // the only valid thing you can do is assign an iterator to it
48  hash_iterator(void);
49  ~hash_iterator(void);
50 
51  // tests
52  // a null iterator is one that has not been initialised with a value yet
53  // i.e. you just declared it but didn't assign to it
54  bool null(void) const;
55  // an end iterator is one that points to the end element of the list of nodes
56  // in STL conventions this is one past the last valid element and must not be dereferenced
57  bool end(void) const;
58  // a valid iterator is one that can be dereferenced
59  // i.e. non-null and non-end
60  bool valid(void) const;
61 
62  // get the hash container that created this iterator
63  // a null iterator doesn't have an owner so returns a null pointer
64  const hash<K, T, H, E>* owner(void) const;
65 
66  // Type conversion methods allow const_iterator and iterator to be converted
67  // convert an iterator/const_iterator to a const_iterator
68  const_iterator constify(void) const;
69  // convert an iterator/const_iterator to an iterator
70  iterator deconstify(void) const;
71 
72  // increment operators used to step through the set of all values in a hash
73  // it is only legal to increment a valid iterator
74  // there's no decrement - I've only implemented this as a unidirectional iterator
75  // pre-increment
76  this_iterator& operator++(void) throw();
77  // post-increment
78  this_iterator operator++(int) throw();
79 
80  // tests useful for putting iterators into other STL structures and for testing whether iteration has completed
81  bool operator==(const this_iterator& r) const;
82  bool operator!=(const this_iterator& r) const;
83  bool operator<(const this_iterator& r) const;
84 
85  // access the value - a const_iterator gives you a const value, an iterator a non-const value
86  // it is illegal to dereference an invalid (i.e. null or end) iterator
87  reference operator*(void) const throw();
88  pointer operator->(void) const throw();
89 
90  // Note: hash iterators are not persistent for a good reason: they are
91  // invalidated by rehashing and so it is not a good idea to build data
92  // structures containing hash iterators in the first place
93 
94  private:
95  friend class hash_element<K, T>;
96 
97  const hash<K, T, H, E>* m_owner;
98  unsigned m_bin;
99  hash_element<K, T>* m_element;
100 
101  void check_owner(const hash<K, T, H, E>* owner) const throw();
102  void check_non_null(void) const;
103  void check_non_end(void) const;
104  void check_valid(void) const throw();
105  void check(const hash<K, T, H, E>* owner) const throw();
106 
107  // constructor used by hash to create a non-null iterator
108  // you cannot create a valid iterator except by calling a hash method that returns one
109  hash_iterator(const hash<K, T, H, E>* owner, unsigned bin, hash_element<K, T>* element);
110 };
111 
113 // Hash class
114 // K = key type
115 // T = value type
116 // H = hash function object with the profile 'unsigned H(const K&)'
117 // E = equal function object with the profile 'bool E(const K&, const K&)' defaults to equal_to which in turn calls '=='
118 
119 template <typename K, typename T, class H, class E = std::equal_to<K> >
120 class hash {
121  public:
122  typedef unsigned size_type;
123  typedef K key_type;
124  typedef T data_type;
125  typedef T mapped_type;
126  typedef std::pair<const K, T> value_type;
129 
130  // construct a hash table with specified number of bins
131  // the default 0 bins means leave it to the table to decide
132  // specifying 0 bins also enables auto-rehashing, otherwise auto-rehashing defaults off
133  hash(unsigned bins = 0);
134  ~hash(void);
135 
136  // copy and equality copy the data elements but not the size of the copied table
137  hash(const hash&);
138  hash& operator=(const hash&);
139 
140  // test for an empty table and for the size of a table - efficient because the size is stored separately from the
141  // table contents
142  bool empty(void) const;
143  unsigned size(void) const;
144 
145  // test for equality - two hashes are equal if they contain equal values
146  bool operator==(const hash&) const;
147  bool operator!=(const hash&) const;
148 
149  // switch auto-rehash on
150  void auto_rehash(void);
151  // switch auto-rehash off
152  void manual_rehash(void);
153  // force a rehash now
154  // default of 0 means implement built-in size calculation for rehashing (recommended - it doubles the number of bins)
155  void rehash(unsigned bins = 0);
156  // test the loading ratio, which is the size divided by the number of bins
157  // use this if you are doing your own rehashing
158  // the recommendation is to double the bins when the loading exceeds 0.5 which is what auto-rehashing does
159  float loading(void) const;
160 
161  // test for the presence of a key
162  bool present(const K& key) const;
163  // provide map equivalent key count function (0 or 1, as not a multimap)
164  size_type count(const K& key) const;
165 
166  // insert a new key/data pair - replaces any previous value for this key
167  iterator insert(const K& key, const T& data);
168  // insert a copy of the pair into the table (std::map compatible)
169  std::pair<iterator, bool> insert(const value_type& value);
170  // insert a new key and return the iterator so that the data can be filled in
171  iterator insert(const K& key);
172 
173  // remove a key/data pair from the hash table
174  bool erase(const K& key);
175  // remove all elements from the hash table
176  void erase(void);
177  // provide the std::map equivalent clear function
178  void clear(void);
179 
180  // find a key and return an iterator to it
181  // The iterator is like a pointer to a pair<const K,T>
182  // end() is returned if the find fails
183  const_iterator find(const K& key) const;
184  iterator find(const K& key);
185  // returns the data corresponding to the key
186  // the const version is used by the compiler on const hashes and cannot change the hash, so find failure causes an
187  // exception the non-const version is used by the compiler on non-const hashes and is like map - it creates a new
188  // key/data pair if find fails
189  const T& operator[](const K& key) const;
190  T& operator[](const K& key);
191 
192  // iterators allow the hash table to be traversed
193  // iterators remain valid unless an item is removed or unless a rehash happens
194  const_iterator begin(void) const;
195  iterator begin(void);
196  const_iterator end(void) const;
197  iterator end(void);
198 
199  // diagnostic report shows the number of items in each bin so can be used to diagnose effectiveness of hash functions
200  void debug_report(otext&, unsigned indent = 0) const;
201  // the same diagnostic function that returns a string, rather than use an otext stream
202  std::string debug_report(unsigned indent = 0) const;
203 
204  // persistence methods
205  void dump(dump_context&) const throw();
206  void restore(restore_context&) throw();
207 
208  // internals
209  private:
210  friend class hash_element<K, T>;
211  friend class hash_iterator<K, T, H, E, std::pair<const K, T> >;
212  friend class hash_iterator<K, T, H, E, const std::pair<const K, T> >;
213 
214  unsigned m_rehash;
215  unsigned m_bins;
216  unsigned m_size;
217  hash_element<K, T>** m_values;
218 };
219 
221 
222 template <typename K, typename T, class H, class E>
223 otext& print(otext& str, const hash<K, T, H, E>& table, unsigned indent = 0);
224 
225 template <typename K, typename T, class H, class E>
226 otext& operator<<(otext& str, const hash<K, T, H, E>& table);
227 
229 
230 template <typename K, typename T, class H, class E>
231 void dump_hash(dump_context& str, const hash<K, T, H, E>& data) throw();
232 
233 template <typename K, typename T, class H, class E>
234 void restore_hash(restore_context& str, hash<K, T, H, E>& data) throw();
235 
237 } // namespace stlplus
238 
239 #include "hash.tpp"
240 #endif
Definition: persistent.hpp:64
Definition: textio.hpp:37
Definition: persistent.hpp:126
Definition: hash.hpp:26
Definition: hash.hpp:32
Definition: hash.hpp:120