NEURON
list.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 list implemented as dynamic array
27  */
28 
29 #ifndef os_list_h
30 #define os_list_h
31 
32 #include <OS/enter-scope.h>
33 
34 extern void ListImpl_range_error(long index);
35 extern long ListImpl_best_new_count(long count, unsigned int size, unsigned int m = 1);
36 
37 #if 1 || defined(__STDC__) || defined(__ANSI_CPP__)
38 #define __ListItr(List) List##_Iterator
39 #define ListItr(List) __ListItr(List)
40 #define __ListUpdater(List) List##_Updater
41 #define ListUpdater(List) __ListUpdater(List)
42 #else
43 #define __ListItr(List) List/**/_Iterator
44 #define ListItr(List) __ListItr(List)
45 #define __ListUpdater(List) List/**/_Updater
46 #define ListUpdater(List) __ListUpdater(List)
47 #endif
48 
49 #define declareList(List,T) \
50 class List { \
51 public: \
52  List(long size = 0); \
53  ~List(); \
54 \
55  long count() const; \
56  T item(long index) const; \
57  T& item_ref(long index) const; \
58 \
59  void prepend(const T&); \
60  void append(const T&); \
61  void insert(long index, const T&); \
62  void remove(long index); \
63  void remove_all(); \
64 private: \
65  T* items_; \
66  long size_; \
67  long count_; \
68  long free_; \
69 }; \
70 \
71 inline long List::count() const { return count_; } \
72 \
73 inline T List::item(long index) const { \
74  if (index < 0 || index >= count_) { \
75  ListImpl_range_error(index); \
76  } \
77  long i = index < free_ ? index : index + size_ - count_; \
78  return items_[i]; \
79 } \
80 inline T& List::item_ref(long index) const { \
81  if (index < 0 || index >= count_) { \
82  ListImpl_range_error(index); \
83  } \
84  long i = index < free_ ? index : index + size_ - count_; \
85  return items_[i]; \
86 } \
87 \
88 inline void List::append(const T& item) { insert(count_, item); } \
89 inline void List::prepend(const T& item) { insert(0, item); } \
90 \
91 class ListItr(List) { \
92 public: \
93  ListItr(List)(const List&); \
94 \
95  bool more() const; \
96  T cur() const; \
97  T& cur_ref() const; \
98  void next(); \
99 private: \
100  const List* list_; \
101  long cur_; \
102 }; \
103 \
104 inline bool ListItr(List)::more() const { return cur_ < list_->count(); } \
105 inline T ListItr(List)::cur() const { return list_->item(cur_); } \
106 inline T& ListItr(List)::cur_ref() const { \
107  return list_->item_ref(cur_); \
108 } \
109 inline void ListItr(List)::next() { ++cur_; } \
110 \
111 class ListUpdater(List) { \
112 public: \
113  ListUpdater(List)(List&); \
114 \
115  bool more() const; \
116  T cur() const; \
117  T& cur_ref() const; \
118  void remove_cur(); \
119  void next(); \
120 private: \
121  List* list_; \
122  long cur_; \
123 }; \
124 \
125 inline bool ListUpdater(List)::more() const { \
126  return cur_ < list_->count(); \
127 } \
128 inline T ListUpdater(List)::cur() const { return list_->item(cur_); } \
129 inline T& ListUpdater(List)::cur_ref() const { \
130  return list_->item_ref(cur_); \
131 } \
132 inline void ListUpdater(List)::remove_cur() { list_->remove(cur_); } \
133 inline void ListUpdater(List)::next() { ++cur_; }
134 
135 /*
136  * Lists of pointers
137  *
138  * Don't ask me to explain the AnyPtr nonsense. C++ compilers
139  * have a hard time deciding between (const void*)& and const (void*&).
140  * Typedefs help, though still keep me guessing.
141  */
142 
143 typedef void* __AnyPtr;
144 
145 declareList(__AnyPtrList,__AnyPtr)
146 
147 #define declarePtrList(PtrList,T) \
148 class PtrList { \
149 public: \
150  PtrList(long size = 0); \
151 \
152  long count() const; \
153  T* item(long index) const; \
154 \
155  void prepend(T*); \
156  void append(T*); \
157  void insert(long index, T*); \
158  void remove(long index); \
159  void remove_all(); \
160 private: \
161  __AnyPtrList impl_; \
162 }; \
163 \
164 inline PtrList::PtrList(long size) : impl_(size) { } \
165 inline long PtrList::count() const { return impl_.count(); } \
166 inline T* PtrList::item(long index) const { return (T*)impl_.item(index); } \
167 inline void PtrList::append(T* item) { insert(impl_.count(), item); } \
168 inline void PtrList::prepend(T* item) { insert(0, item); } \
169 inline void PtrList::remove(long index) { impl_.remove(index); } \
170 inline void PtrList::remove_all() { impl_.remove_all(); } \
171 \
172 class ListItr(PtrList) { \
173 public: \
174  ListItr(PtrList)(const PtrList&); \
175 \
176  bool more() const; \
177  T* cur() const; \
178  void next(); \
179 private: \
180  const PtrList* list_; \
181  long cur_; \
182 }; \
183 \
184 inline bool ListItr(PtrList)::more() const { \
185  return cur_ < list_->count(); \
186 } \
187 inline T* ListItr(PtrList)::cur() const { return list_->item(cur_); } \
188 inline void ListItr(PtrList)::next() { ++cur_; } \
189 \
190 class ListUpdater(PtrList) { \
191 public: \
192  ListUpdater(PtrList)(PtrList&); \
193 \
194  bool more() const; \
195  T* cur() const; \
196  void remove_cur(); \
197  void next(); \
198 private: \
199  PtrList* list_; \
200  long cur_; \
201 }; \
202 \
203 inline bool ListUpdater(PtrList)::more() const { \
204  return cur_ < list_->count(); \
205 } \
206 inline T* ListUpdater(PtrList)::cur() const { return list_->item(cur_); } \
207 inline void ListUpdater(PtrList)::remove_cur() { list_->remove(cur_); } \
208 inline void ListUpdater(PtrList)::next() { ++cur_; }
209 
210 /*
211  * List implementation
212  */
213 
214 #define implementList(List,T) \
215 List::List(long size) { \
216  if (size > 0) { \
217  size_ = ListImpl_best_new_count(size, sizeof(T)); \
218  items_ = new T[size_]; \
219  } else { \
220  size_ = 0; \
221  items_ = 0; \
222  } \
223  count_ = 0; \
224  free_ = 0; \
225 } \
226 \
227 List::~List() { \
228  delete [] items_; \
229 } \
230 \
231 void List::insert(long index, const T& item) { \
232  if (count_ == size_) { \
233  long size = ListImpl_best_new_count(size_ + 1, sizeof(T), 2); \
234  T* items = new T[size]; \
235  if (items_ != 0) { \
236  long i; \
237  for (i = 0; i < free_; ++i) { \
238  items[i] = items_[i]; \
239  } \
240  for (i = 0; i < count_ - free_; ++i) { \
241  items[free_ + size - count_ + i] = \
242  items_[free_ + size_ - count_ + i]; \
243  } \
244  delete [] items_; \
245  } \
246  items_ = items; \
247  size_ = size; \
248  } \
249  if (index >= 0 && index <= count_) { \
250  if (index < free_) { \
251  for (long i = free_ - index - 1; i >= 0; --i) { \
252  items_[index + size_ - count_ + i] = items_[index + i]; \
253  } \
254  } else if (index > free_) { \
255  for (long i = 0; i < index - free_; ++i) { \
256  items_[free_ + i] = items_[free_ + size_ - count_ + i]; \
257  } \
258  } \
259  free_ = index + 1; \
260  count_ += 1; \
261  items_[index] = item; \
262  } \
263 } \
264 \
265 void List::remove(long index) { \
266  if (index >= 0 && index <= count_) { \
267  if (index < free_) { \
268  for (long i = free_ - index - 2; i >= 0; --i) { \
269  items_[size_ - count_ + index + 1 + i] = \
270  items_[index + 1 + i]; \
271  } \
272  } else if (index > free_) { \
273  for (long i = 0; i < index - free_; ++i) { \
274  items_[free_ + i] = items_[free_ + size_ - count_ + i]; \
275  } \
276  } \
277  free_ = index; \
278  count_ -= 1; \
279  } \
280 } \
281 \
282 void List::remove_all() { \
283  count_ = 0; \
284  free_ = 0; \
285 } \
286 \
287 ListItr(List)::ListItr(List)(const List& list) { \
288  list_ = &list; \
289  cur_ = 0; \
290 } \
291 \
292 ListUpdater(List)::ListUpdater(List)(List& list) { \
293  list_ = &list; \
294  cur_ = 0; \
295 }
296 
297 #define implementPtrList(PtrList,T) \
298 void PtrList::insert(long index, T* item) { \
299  const __AnyPtr p = item; \
300  impl_.insert(index, p); \
301 } \
302 ListItr(PtrList)::ListItr(PtrList)(const PtrList& list) { \
303  list_ = &list; \
304  cur_ = 0; \
305 } \
306 \
307 ListUpdater(PtrList)::ListUpdater(PtrList)(PtrList& list) { \
308  list_ = &list; \
309  cur_ = 0; \
310 }
311 
312 #endif
void ListImpl_range_error(long index)
Definition: listimpl.cpp:54
void * __AnyPtr
Definition: list.h:143
long ListImpl_best_new_count(long count, unsigned int size, unsigned int m=1)
Definition: listimpl.cpp:45
#define declareList(List, T)
Definition: list.h:49
short index
Definition: cabvars.h:11