NEURON
table.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
3  * Copyright (c) 1991 Silicon Graphics, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that (i) the above copyright notices and this permission notice appear in
8  * all copies of the software and related documentation, and (ii) the names of
9  * Stanford and Silicon Graphics may not be used in any advertising or
10  * publicity relating to the software without the specific, prior written
11  * permission of Stanford and Silicon Graphics.
12  *
13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22  * OF THIS SOFTWARE.
23  */
24 
25 /*
26  * Generic object association table.
27  */
28 
29 #ifndef os_table_h
30 #define os_table_h
31 
32 #include <OS/enter-scope.h>
33 
34 #if 1 || defined(__STDC__) || defined(__ANSI_CPP__)
35 #define __TableEntry(Table) Table##_Entry
36 #define TableEntry(Table) __TableEntry(Table)
37 #define __TableIterator(Table) Table##_Iterator
38 #define TableIterator(Table) __TableIterator(Table)
39 #else
40 #define __TableEntry(Table) Table/**/_Entry
41 #define TableEntry(Table) __TableEntry(Table)
42 #define __TableIterator(Table) Table/**/_Iterator
43 #define TableIterator(Table) __TableIterator(Table)
44 #endif
45 
46 #define declareTable(Table,Key,Value) \
47 struct TableEntry(Table); \
48 \
49 class Table { \
50 public: \
51  Table(int); \
52  ~Table(); \
53 \
54  void insert(Key, Value); \
55  bool find(Value&, Key); \
56  bool find_and_remove(Value&, Key); \
57  void remove(Key); \
58 private: \
59  friend class TableIterator(Table); \
60 \
61  int size_; \
62  TableEntry(Table)** first_; \
63  TableEntry(Table)** last_; \
64 \
65  TableEntry(Table)*& probe(Key); \
66 }; \
67 \
68 struct TableEntry(Table) { \
69 private: \
70  friend class Table; \
71  friend class TableIterator(Table); \
72 \
73  Key key_; \
74  Value value_; \
75  TableEntry(Table)* chain_; \
76 }; \
77 \
78 class TableIterator(Table) { \
79 public: \
80  TableIterator(Table)(Table&); \
81 \
82  Key& cur_key(); \
83  Value& cur_value(); \
84  bool more(); \
85  bool next(); \
86 private: \
87  TableEntry(Table)* cur_; \
88  TableEntry(Table)** entry_; \
89  TableEntry(Table)** last_; \
90 }; \
91 \
92 inline Key& TableIterator(Table)::cur_key() { return cur_->key_; } \
93 inline Value& TableIterator(Table)::cur_value() { return cur_->value_; } \
94 inline bool TableIterator(Table)::more() { return entry_ <= last_; }
95 
96 /*
97  * Predefined hash functions
98  */
99 
100 #ifndef os_table2_h
101 inline unsigned long key_to_hash(long k) { return (unsigned long)k; }
102 #if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ > __SIZEOF_LONG__
103 inline unsigned long key_to_hash(const void* k) { return (unsigned long)((unsigned long long)k); }
104 #else
105 inline unsigned long key_to_hash(const void* k) { return (unsigned long)k; }
106 #endif
107 #endif
108 
109 /*
110  * Table implementation
111  */
112 
113 #define implementTable(Table,Key,Value) \
114 Table::Table(int n) { \
115  for (size_ = 32; size_ < n; size_ <<= 1); \
116  first_ = new TableEntry(Table)*[size_]; \
117  --size_; \
118  last_ = &first_[size_]; \
119  for (TableEntry(Table)** e = first_; e <= last_; e++) { \
120  *e = nil; \
121  } \
122 } \
123 \
124 Table::~Table() { \
125  for (TableEntry(Table)** e = first_; e <= last_; e++) { \
126  TableEntry(Table)* t = *e; \
127  for (TableEntry(Table)* i = t; i; i = t) { \
128  t = i->chain_; \
129  delete i; \
130  } \
131  } \
132  delete [] first_; \
133 } \
134 \
135 inline TableEntry(Table)*& Table::probe(Key i) { \
136  return first_[key_to_hash(i) & size_]; \
137 } \
138 \
139 void Table::insert(Key k, Value v) { \
140  TableEntry(Table)* e = new TableEntry(Table); \
141  e->key_ = k; \
142  e->value_ = v; \
143  TableEntry(Table)** a = &probe(k); \
144  e->chain_ = *a; \
145  *a = e; \
146 } \
147 \
148 bool Table::find(Value& v, Key k) { \
149  for (TableEntry(Table)* e = probe(k); e != nil; e = e->chain_) { \
150  if (e->key_ == k) { \
151  v = e->value_; \
152  return true; \
153  } \
154  } \
155  return false; \
156 } \
157 \
158 bool Table::find_and_remove(Value& v, Key k) { \
159  TableEntry(Table)** a = &probe(k); \
160  TableEntry(Table)* e = *a; \
161  if (e != nil) { \
162  if (e->key_ == k) { \
163  v = e->value_; \
164  *a = e->chain_; \
165  delete e; \
166  return true; \
167  } else { \
168  TableEntry(Table)* prev; \
169  do { \
170  prev = e; \
171  e = e->chain_; \
172  } while (e != nil && e->key_ != k); \
173  if (e != nil) { \
174  v = e->value_; \
175  prev->chain_ = e->chain_; \
176  delete e; \
177  return true; \
178  } \
179  } \
180  } \
181  return false; \
182 } \
183 \
184 void Table::remove(Key k) { \
185  TableEntry(Table)** a = &probe(k); \
186  TableEntry(Table)* e = *a; \
187  if (e != nil) { \
188  if (e->key_ == k) { \
189  *a = e->chain_; \
190  delete e; \
191  } else { \
192  TableEntry(Table)* prev; \
193  do { \
194  prev = e; \
195  e = e->chain_; \
196  } while (e != nil && e->key_ != k); \
197  if (e != nil) { \
198  prev->chain_ = e->chain_; \
199  delete e; \
200  } \
201  } \
202  } \
203 } \
204 \
205 TableIterator(Table)::TableIterator(Table)(Table& t) { \
206  last_ = t.last_; \
207  for (entry_ = t.first_; entry_ <= last_; entry_++) { \
208  cur_ = *entry_; \
209  if (cur_ != nil) { \
210  break; \
211  } \
212  } \
213 } \
214 \
215 bool TableIterator(Table)::next() { \
216  cur_ = cur_->chain_; \
217  if (cur_ != nil) { \
218  return true; \
219  } \
220  for (++entry_; entry_ <= last_; entry_++) { \
221  cur_ = *entry_; \
222  if (cur_ != nil) { \
223  return true; \
224  } \
225  } \
226  return false; \
227 }
228 
229 #endif
static philox4x32_key_t k
Definition: nrnran123.cpp:11
long
Definition: netcvode.cpp:4792
unsigned long key_to_hash(long k)
Definition: table.h:101