2 Copyright 1999, Be Incorporated. All Rights Reserved.
3 This file may be used under the terms of the Be Sample Code License.
13 template <class contents
>
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
>
34 LispNode
<contents
> *first
;
36 /* -------- List creation --------------- */
37 /* Create an empty list */
44 /* Create a list pointing to the specified node */
45 inline LispList(LispNode
<contents
>* _first
)
52 inline LispList(LispList
&init
)
58 /* ---------- List queries ------------- */
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
)
75 /* Returns the length of the list */
79 for (LispNode
<contents
>* node
= first
; node
; node
= node
->cdr
)
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
;
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
;
105 pred
= &(*pred
)->cdr
;
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
;
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
;
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
)
206 /* Remove & delete all nodes pointing to a particular element. */
207 inline void rem_del (contents
* element
)
209 LispNode
<contents
>** pp
= &first
;
211 if ((*pp
)->car
== element
) {
212 LispNode
<contents
> *o
= *pp
;
221 /* Remove and delete all nodes on the list. */
222 inline void rem_del_all()
225 LispNode
<contents
>* old
= first
;
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
)
245 /* Put something at beginning of list */
246 inline void put_head( contents
* c
)
252 /* Put something at end of the list */
253 inline void put_tail( contents
* c
)
258 #if 0 /* leaks memory */
259 /* Take a specific thing off the list */
260 inline contents
*get(contents
*element
)
263 for (LispNode
<contents
> *node
= first
; node
; node
= node
->cdr
)
265 if (node
->car
== element
)
276 /* Take the first thing off the list */
277 inline contents
* get_head()
288 /* Take something off the list */
289 inline contents
* get()
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
)
305 /* Remove a thing from the head of the list */
306 inline contents
* pop()
311 /* Pop everything off the stack. Empty the stack/list. */
312 inline void pop_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
)
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
)
344 template <class thetype
>
345 struct DoubleLinkedNode
356 void insert_after(thetype
* n
)
362 n
->prev
= (thetype
*)this;
367 void insert_before(thetype
* n
)
370 n
->next
= (thetype
*)this;
378 assert(prev
!= NULL
);
387 template <class thetype
>
388 struct DoubleLinkedList
: public DoubleLinkedNode
<thetype
>
390 DoubleLinkedList() : DoubleLinkedNode
<thetype
>() {};
392 void insert(thetype
* n
)
414 items
= (T
*)realloc(items
,sizeof(T
)*i
);
419 T
& operator [](int index
)
421 assert(index
< num_items
);
428 assert(index
< num_items
);
435 if (num_items
== num_slots
)
436 resize(num_slots
+slot_inc
);
438 memcpy(items
+num_items
,&item
,sizeof(item
));
443 BufferArray(int start_slots
, int _slot_inc
)
445 num_slots
= start_slots
;
446 slot_inc
= _slot_inc
;
447 assert(slot_inc
> 0);
449 items
= (T
*)malloc(sizeof(T
)*num_slots
);