NEURON
table2.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  * Object association table with 2 keys.
27  */
28 
29 #ifndef os_table2_h
30 #define os_table2_h
31 
32 #include <OS/enter-scope.h>
33 
34 #if defined(__STDC__) || defined(__ANSI_CPP__)
35 #define __Table2Entry(Table2) Table2##_Entry
36 #define Table2Entry(Table2) __Table2Entry(Table2)
37 #define __Table2Iterator(Table2) Table2##_Iterator
38 #define Table2Iterator(Table2) __Table2Iterator(Table2)
39 #else
40 #define __Table2Entry(Table2) Table2/**/_Entry
41 #define Table2Entry(Table2) __Table2Entry(Table2)
42 #define __Table2Iterator(Table2) Table2/**/_Iterator
43 #define Table2Iterator(Table2) __Table2Iterator(Table2)
44 #endif
45 
46 #define declareTable2(Table2,Key1,Key2,Value) \
47 struct Table2Entry(Table2); \
48 \
49 class Table2 { \
50 public: \
51  Table2(int); \
52  ~Table2(); \
53 \
54  void insert(Key1, Key2, Value); \
55  bool find(Value&, Key1, Key2); \
56  void remove(Key1, Key2); \
57 private: \
58  friend class Table2Iterator(Table2); \
59 \
60  int size_; \
61  Table2Entry(Table2)** first_; \
62  Table2Entry(Table2)** last_; \
63 \
64  Table2Entry(Table2)*& probe(Key1, Key2); \
65 }; \
66 \
67 struct Table2Entry(Table2) { \
68 private: \
69 friend class Table2; \
70 friend class Table2Iterator(Table2); \
71 \
72  Key1 key1_; \
73  Key2 key2_; \
74  Value value_; \
75  Table2Entry(Table2)* chain_; \
76 }; \
77 \
78 class Table2Iterator(Table2) { \
79 public: \
80  Table2Iterator(Table2)(Table2&); \
81 \
82  Key1& cur_key1(); \
83  Key2& cur_key2(); \
84  Value& cur_value(); \
85  bool more(); \
86  bool next(); \
87 private: \
88  Table2Entry(Table2)* cur_; \
89  Table2Entry(Table2)** entry_; \
90  Table2Entry(Table2)** last_; \
91 }; \
92 \
93 inline Key1& Table2Iterator(Table2)::cur_key1() { return cur_->key1_; } \
94 inline Key2& Table2Iterator(Table2)::cur_key2() { return cur_->key2_; } \
95 inline Value& Table2Iterator(Table2)::cur_value() { return cur_->value_; } \
96 inline bool Table2Iterator(Table2)::more() { return entry_ <= last_; }
97 
98 /*
99  * Predefined hash functions
100  */
101 
102 #ifndef os_table_h
103 inline unsigned long key_to_hash(long k) { return (unsigned long)k; }
104 inline unsigned long key_to_hash(const void* k) { return (unsigned long)k; }
105 #endif
106 
107 /*
108  * Table2 implementation
109  */
110 
111 #define implementTable2(Table2,Key1,Key2,Value) \
112 Table2::Table2(int n) { \
113  for (size_ = 32; size_ < n; size_ <<= 1); \
114  first_ = new Table2Entry(Table2)*[size_]; \
115  --size_; \
116  last_ = &first_[size_]; \
117  for (Table2Entry(Table2)** e = first_; e <= last_; e++) { \
118  *e = nil; \
119  } \
120 } \
121 \
122 Table2::~Table2() { \
123  delete [] first_; \
124 } \
125 \
126 inline Table2Entry(Table2)*& Table2::probe(Key1 k1, Key2 k2) { \
127  return first_[(key_to_hash(k1) ^ key_to_hash(k2)) & size_]; \
128 } \
129 \
130 void Table2::insert(Key1 k1, Key2 k2, Value v) { \
131  Table2Entry(Table2)* e = new Table2Entry(Table2); \
132  e->key1_ = k1; \
133  e->key2_ = k2; \
134  e->value_ = v; \
135  Table2Entry(Table2)** a = &probe(k1, k2); \
136  e->chain_ = *a; \
137  *a = e; \
138 } \
139 \
140 bool Table2::find(Value& v, Key1 k1, Key2 k2) { \
141  for ( \
142  Table2Entry(Table2)* e = probe(k1, k2); \
143  e != nil; \
144  e = e->chain_ \
145  ) { \
146  if (e->key1_ == k1 && e->key2_ == k2) { \
147  v = e->value_; \
148  return true; \
149  } \
150  } \
151  return false; \
152 } \
153 \
154 void Table2::remove(Key1 k1, Key2 k2) { \
155  Table2Entry(Table2)** a = &probe(k1, k2); \
156  Table2Entry(Table2)* e = *a; \
157  if (e != nil) { \
158  if (e->key1_ == k1 && e->key2_ == k2) { \
159  *a = e->chain_; \
160  delete e; \
161  } else { \
162  Table2Entry(Table2)* prev; \
163  do { \
164  prev = e; \
165  e = e->chain_; \
166  } while (e != nil && (e->key1_ != k1 || e->key2_ != k2)); \
167  if (e != nil) { \
168  prev->chain_ = e->chain_; \
169  delete e; \
170  } \
171  } \
172  } \
173 } \
174 \
175 Table2Iterator(Table2)::Table2Iterator(Table2)(Table2& t) { \
176  last_ = t.last_; \
177  for (entry_ = t.first_; entry_ <= last_; entry_++) { \
178  cur_ = *entry_; \
179  if (cur_ != nil) { \
180  break; \
181  } \
182  } \
183 } \
184 \
185 bool Table2Iterator(Table2)::next() { \
186  cur_ = cur_->chain_; \
187  if (cur_ != nil) { \
188  return true; \
189  } \
190  for (++entry_; entry_ <= last_; entry_++) { \
191  cur_ = *entry_; \
192  if (cur_ != nil) { \
193  return true; \
194  } \
195  } \
196  return false; \
197 }
198 
199 #endif
unsigned long key_to_hash(long k)
Definition: table2.h:103
static philox4x32_key_t k
Definition: nrnran123.cpp:11