btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / glteapot / util.h
blobf8a4f36cf0c88485725f2fdc3f0a3df6f2491167
1 /*
2 Copyright 1999, Be Incorporated. All Rights Reserved.
3 This file may be used under the terms of the Be Sample Code License.
4 */
6 #ifndef UTIL_H
7 #define UTIL_H
9 #include <memory.h>
10 #include <stdlib.h>
11 #include "error.h"
13 template <class contents>
14 struct LispNode {
15 contents* car;
16 LispNode* cdr;
18 /* Create a node with no next */
19 inline LispNode(contents* value)
20 : car(value), cdr(0) { }
22 /* Create a node with specified next */
23 inline LispNode(contents* value, LispNode* next)
24 : car (value), cdr(next) { }
26 /* Create a node and insert it in a list right after `prev' */
27 inline LispNode(LispNode* prev, contents* value)
28 : car(value), cdr(prev->cdr) { prev->cdr = this; }
32 template <class contents>
33 struct LispList {
34 LispNode<contents> *first;
36 /* -------- List creation --------------- */
37 /* Create an empty list */
38 inline LispList()
40 first = 0;
44 /* Create a list pointing to the specified node */
45 inline LispList(LispNode<contents>* _first)
47 first = _first;
51 /* ?? */
52 inline LispList(LispList &init)
54 first = init.first;
58 /* ---------- List queries ------------- */
59 inline int is_empty()
61 return first == 0;
65 /* Determines if a thing is on the list */
66 inline int is_present(contents* element)
68 for (LispNode<contents>* node = first; node; node = node->cdr)
69 if (node->car == element)
70 return 1;
71 return 0;
75 /* Returns the length of the list */
76 inline int count()
78 int n = 0;
79 for (LispNode<contents>* node = first; node; node = node->cdr)
80 n++;
81 return n;
85 /* ----------- Adding "nodes" to the list ------------ */
86 /* Add a specified node to the head of the list. */
87 inline void add_head(LispNode<contents>* new_element)
89 new_element->cdr = first;
90 first = new_element;
94 /* Add a specified node anywhere on the list */
95 inline void add(LispNode<contents>* new_element)
97 add_head (new_element);
101 inline void add_tail(LispNode<contents>* new_element)
103 LispNode<contents>** pred = &first;
104 while(*pred)
105 pred = &(*pred)->cdr;
106 *pred = new_element;
107 new_element->cdr = 0;
111 /* ----------- Adding "contents" to the list ------------ */
112 /* ----- (Which in my opinion is far more useful) ------ */
114 /* Create new node pointing to thing, & add to head of list. */
115 inline void add_head_new(contents* new_element)
117 first = new LispNode<contents>(new_element, first);
121 inline void add_head(contents* new_element)
123 add_head_new(new_element);
127 /* Create new node pointing to thing, & add to end of list. */
128 inline void add_tail_new(contents* new_element)
130 LispNode< contents >** pred = &first;
131 while (*pred)
132 pred = &(*pred)->cdr;
134 *pred = new LispNode< contents >(new_element);
138 inline void add_tail(contents* new_element)
140 add_tail_new(new_element);
144 /* Create new node pointing to thing, & add anywhere on list */
145 inline void add_new(contents* new_element)
147 add_head_new(new_element);
151 inline void add(contents* new_element)
153 add_new(new_element);
157 /* Create and add a new node for a specified element,
158 but only if it's not already on the list. */
159 inline void add_new_once(contents* new_element)
161 if (!is_present(new_element))
162 add_head_new(new_element);
166 inline void add_tail_once(contents *new_element)
168 if (!is_present(new_element))
169 add_tail_new(new_element);
173 /* ------- Removing things from the list ------------ */
175 /* Remove and return the first node on the list j.h. */
176 inline LispNode<contents>* rem_head ()
178 LispNode<contents>* n = first;
180 if (n) {
181 first = first->cdr;
184 return n;
188 /* Remove and return any node on the list. */
189 inline LispNode<contents>* remove ()
191 return( rem_head() );
195 /* Remove a specified node from the list. */
196 inline void remove (LispNode<contents>* node)
198 for (LispNode<contents> **pp = &first; *pp; pp = &(*pp)->cdr)
199 if (*pp == node) {
200 *pp = (*pp)->cdr;
201 return;
206 /* Remove & delete all nodes pointing to a particular element. */
207 inline void rem_del (contents* element)
209 LispNode<contents>** pp = &first;
210 while (*pp) {
211 if ((*pp)->car == element) {
212 LispNode<contents> *o = *pp;
213 *pp = o->cdr;
214 delete o;
215 } else
216 pp = &(*pp)->cdr;
221 /* Remove and delete all nodes on the list. */
222 inline void rem_del_all()
224 while (first) {
225 LispNode<contents>* old = first;
226 first = first->cdr;
227 delete old;
232 /* -------- Simple list storage (by j.h.) ------------ */
234 /* When you just want to hold a bunch of stuff on a list and then pull them
235 off later. Note that these calls do NOT check for to see if a thing is
236 already on the list. Use is_present() before adding.
238 /* Put something anywhere on the list */
239 inline void put( contents* c )
241 add_tail( c );
245 /* Put something at beginning of list */
246 inline void put_head( contents* c )
248 add_head( c );
252 /* Put something at end of the list */
253 inline void put_tail( contents* c )
255 add_tail( c );
258 #if 0 /* leaks memory */
259 /* Take a specific thing off the list */
260 inline contents *get(contents *element)
262 contents *c = 0;
263 for (LispNode<contents> *node = first; node; node = node->cdr)
265 if (node->car == element)
267 c = node->car;
268 remove(node);
269 break;
272 return c;
274 #endif
276 /* Take the first thing off the list */
277 inline contents* get_head()
279 contents *c = 0;
280 if(first) {
281 c = first->car;
282 delete rem_head();
284 return c;
288 /* Take something off the list */
289 inline contents* get()
291 return(get_head());
295 /* XXX inline contents *get_tail() { } */
297 /* -------- Stack simulation (by j.h.) ------------ */
298 /* Put a thing onto the head of the list */
299 inline void push(contents* c)
301 put_head(c);
305 /* Remove a thing from the head of the list */
306 inline contents* pop()
308 return(get_head());
311 /* Pop everything off the stack. Empty the stack/list. */
312 inline void pop_all()
314 rem_del_all();
318 /* ----------- list/list manipulations ------------ */
320 /* Add all elements present on another list to this list also. */
321 inline void add_new(LispList other)
323 for (LispNode<contents>* n = other.first; n; n = n->cdr)
324 add_new(n->car);
328 inline void add_new_once(LispList other)
330 for (LispNode<contents>* n = other.first; n; n = n->cdr)
331 add_new_once(n->car);
335 /* Remove and delete all nodes whose contents are also present
336 in a different list (set disjunction). */
337 inline void rem_del(LispList other)
339 for (LispNode<contents>* n = other.first; n; n = n->cdr)
340 rem_del(n->car);
344 template <class thetype>
345 struct DoubleLinkedNode
347 thetype* next;
348 thetype* prev;
350 DoubleLinkedNode()
352 next = prev = NULL;
356 void insert_after(thetype* n)
358 if (next != NULL)
359 next->prev = n;
361 n->next = next;
362 n->prev = (thetype*)this;
363 next = n;
367 void insert_before(thetype* n)
369 prev->next = n;
370 n->next = (thetype*)this;
371 n->prev = prev;
372 prev = n;
376 void remove()
378 assert(prev != NULL);
379 prev->next = next;
381 if (next != NULL)
382 next->prev = prev;
387 template <class thetype>
388 struct DoubleLinkedList : public DoubleLinkedNode<thetype>
390 DoubleLinkedList() : DoubleLinkedNode<thetype>() {};
392 void insert(thetype* n)
394 insert_after(n);
398 void add(thetype* n)
400 insert_after(n);
405 template <class T>
406 struct BufferArray {
407 T * items;
408 int num_items;
409 int num_slots;
410 int slot_inc;
412 void resize(int i)
414 items = (T*)realloc(items,sizeof(T)*i);
415 num_slots = i;
419 T & operator [](int index)
421 assert(index < num_items);
422 return items[index];
426 T & get(int index)
428 assert(index < num_items);
429 return items[index];
433 void add(T &item)
435 if (num_items == num_slots)
436 resize(num_slots+slot_inc);
438 memcpy(items+num_items,&item,sizeof(item));
439 num_items++;
443 BufferArray(int start_slots, int _slot_inc)
445 num_slots = start_slots;
446 slot_inc = _slot_inc;
447 assert(slot_inc > 0);
448 num_items = 0;
449 items = (T*)malloc(sizeof(T)*num_slots);
453 ~BufferArray()
455 free(items);
459 #endif // UTIL_H