Mercurial > hg > CbC > CbC_gcc
comparison gcc/typed-splay-tree.h @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* A typesafe wrapper around libiberty's splay-tree.h. | 1 /* A typesafe wrapper around libiberty's splay-tree.h. |
2 Copyright (C) 2015-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2015-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #ifndef GCC_TYPED_SPLAY_TREE_H | 20 #ifndef GCC_TYPED_SPLAY_TREE_H |
21 #define GCC_TYPED_SPLAY_TREE_H | 21 #define GCC_TYPED_SPLAY_TREE_H |
22 | 22 |
23 #include "splay-tree.h" | |
24 | |
25 /* Typesafe wrapper around libiberty's splay-tree.h. */ | 23 /* Typesafe wrapper around libiberty's splay-tree.h. */ |
26 template <typename KEY_TYPE, typename VALUE_TYPE> | 24 template <typename KEY_TYPE, typename VALUE_TYPE> |
27 class typed_splay_tree | 25 class typed_splay_tree |
28 { | 26 { |
29 public: | 27 public: |
42 | 40 |
43 value_type lookup (key_type k); | 41 value_type lookup (key_type k); |
44 value_type predecessor (key_type k); | 42 value_type predecessor (key_type k); |
45 value_type successor (key_type k); | 43 value_type successor (key_type k); |
46 void insert (key_type k, value_type v); | 44 void insert (key_type k, value_type v); |
45 void remove (key_type k); | |
47 value_type max (); | 46 value_type max (); |
48 value_type min (); | 47 value_type min (); |
49 int foreach (foreach_fn, void *); | 48 int foreach (foreach_fn, void *); |
50 | 49 |
51 private: | 50 private: |
52 /* Helper type for typed_splay_tree::foreach. */ | 51 /* Copy and assignment ops are not supported. */ |
53 struct closure | 52 typed_splay_tree (const typed_splay_tree &); |
54 { | 53 typed_splay_tree & operator = (const typed_splay_tree &); |
55 closure (foreach_fn outer_cb, void *outer_user_data) | 54 |
56 : m_outer_cb (outer_cb), m_outer_user_data (outer_user_data) {} | 55 typedef key_type splay_tree_key; |
57 | 56 typedef value_type splay_tree_value; |
58 foreach_fn m_outer_cb; | 57 |
59 void *m_outer_user_data; | 58 /* The nodes in the splay tree. */ |
59 struct splay_tree_node_s { | |
60 /* The key. */ | |
61 splay_tree_key key; | |
62 | |
63 /* The value. */ | |
64 splay_tree_value value; | |
65 | |
66 /* The left and right children, respectively. */ | |
67 splay_tree_node_s *left, *right; | |
68 | |
69 /* Used as temporary value for tree traversals. */ | |
70 splay_tree_node_s *back; | |
60 }; | 71 }; |
61 | 72 typedef splay_tree_node_s *splay_tree_node; |
62 static int inner_foreach_fn (splay_tree_node node, void *user_data); | 73 |
74 inline void KDEL (splay_tree_key); | |
75 inline void VDEL (splay_tree_value); | |
76 void splay_tree_delete_helper (splay_tree_node); | |
77 static inline void rotate_left (splay_tree_node *, | |
78 splay_tree_node, splay_tree_node); | |
79 static inline void rotate_right (splay_tree_node *, | |
80 splay_tree_node, splay_tree_node); | |
81 void splay_tree_splay (splay_tree_key); | |
82 static int splay_tree_foreach_helper (splay_tree_node, | |
83 foreach_fn, void*); | |
84 splay_tree_node splay_tree_insert (splay_tree_key, splay_tree_value); | |
85 void splay_tree_remove (splay_tree_key key); | |
86 splay_tree_node splay_tree_lookup (splay_tree_key key); | |
87 splay_tree_node splay_tree_predecessor (splay_tree_key); | |
88 splay_tree_node splay_tree_successor (splay_tree_key); | |
89 splay_tree_node splay_tree_max (); | |
90 splay_tree_node splay_tree_min (); | |
63 | 91 |
64 static value_type node_to_value (splay_tree_node node); | 92 static value_type node_to_value (splay_tree_node node); |
65 | 93 |
66 private: | 94 /* The root of the tree. */ |
67 ::splay_tree m_inner; | 95 splay_tree_node root; |
96 | |
97 /* The comparision function. */ | |
98 compare_fn comp; | |
99 | |
100 /* The deallocate-key function. NULL if no cleanup is necessary. */ | |
101 delete_key_fn delete_key; | |
102 | |
103 /* The deallocate-value function. NULL if no cleanup is necessary. */ | |
104 delete_value_fn delete_value; | |
68 }; | 105 }; |
69 | 106 |
70 /* Constructor for typed_splay_tree <K, V>. */ | 107 /* Constructor for typed_splay_tree <K, V>. */ |
71 | 108 |
72 template <typename KEY_TYPE, typename VALUE_TYPE> | 109 template <typename KEY_TYPE, typename VALUE_TYPE> |
73 inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>:: | 110 inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>:: |
74 typed_splay_tree (compare_fn compare_fn, | 111 typed_splay_tree (compare_fn compare_fn, |
75 delete_key_fn delete_key_fn, | 112 delete_key_fn delete_key_fn, |
76 delete_value_fn delete_value_fn) | 113 delete_value_fn delete_value_fn) |
77 { | 114 { |
78 m_inner = splay_tree_new ((splay_tree_compare_fn)compare_fn, | 115 root = NULL; |
79 (splay_tree_delete_key_fn)delete_key_fn, | 116 comp = compare_fn; |
80 (splay_tree_delete_value_fn)delete_value_fn); | 117 delete_key = delete_key_fn; |
118 delete_value = delete_value_fn; | |
81 } | 119 } |
82 | 120 |
83 /* Destructor for typed_splay_tree <K, V>. */ | 121 /* Destructor for typed_splay_tree <K, V>. */ |
84 | 122 |
85 template <typename KEY_TYPE, typename VALUE_TYPE> | 123 template <typename KEY_TYPE, typename VALUE_TYPE> |
86 inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>:: | 124 inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>:: |
87 ~typed_splay_tree () | 125 ~typed_splay_tree () |
88 { | 126 { |
89 splay_tree_delete (m_inner); | 127 splay_tree_delete_helper (root); |
90 } | 128 } |
91 | 129 |
92 /* Lookup KEY, returning a value if present, and NULL | 130 /* Lookup KEY, returning a value if present, and NULL |
93 otherwise. */ | 131 otherwise. */ |
94 | 132 |
95 template <typename KEY_TYPE, typename VALUE_TYPE> | 133 template <typename KEY_TYPE, typename VALUE_TYPE> |
96 inline VALUE_TYPE | 134 inline VALUE_TYPE |
97 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::lookup (key_type key) | 135 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::lookup (key_type key) |
98 { | 136 { |
99 splay_tree_node node = splay_tree_lookup (m_inner, (splay_tree_key)key); | 137 splay_tree_node node = splay_tree_lookup (key); |
100 return node_to_value (node); | 138 return node_to_value (node); |
101 } | 139 } |
102 | 140 |
103 /* Return the immediate predecessor of KEY, or NULL if there is no | 141 /* Return the immediate predecessor of KEY, or NULL if there is no |
104 predecessor. KEY need not be present in the tree. */ | 142 predecessor. KEY need not be present in the tree. */ |
105 | 143 |
106 template <typename KEY_TYPE, typename VALUE_TYPE> | 144 template <typename KEY_TYPE, typename VALUE_TYPE> |
107 inline VALUE_TYPE | 145 inline VALUE_TYPE |
108 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::predecessor (key_type key) | 146 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::predecessor (key_type key) |
109 { | 147 { |
110 splay_tree_node node = splay_tree_predecessor (m_inner, (splay_tree_key)key); | 148 splay_tree_node node = splay_tree_predecessor (key); |
111 return node_to_value (node); | 149 return node_to_value (node); |
112 } | 150 } |
113 | 151 |
114 /* Return the immediate successor of KEY, or NULL if there is no | 152 /* Return the immediate successor of KEY, or NULL if there is no |
115 successor. KEY need not be present in the tree. */ | 153 successor. KEY need not be present in the tree. */ |
116 | 154 |
117 template <typename KEY_TYPE, typename VALUE_TYPE> | 155 template <typename KEY_TYPE, typename VALUE_TYPE> |
118 inline VALUE_TYPE | 156 inline VALUE_TYPE |
119 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::successor (key_type k) | 157 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::successor (key_type key) |
120 { | 158 { |
121 splay_tree_node node = splay_tree_successor (m_inner, (splay_tree_key)k); | 159 splay_tree_node node = splay_tree_successor (key); |
122 return node_to_value (node); | 160 return node_to_value (node); |
123 } | 161 } |
124 | 162 |
125 /* Insert a new node (associating KEY with VALUE). If a | 163 /* Insert a new node (associating KEY with VALUE). If a |
126 previous node with the indicated KEY exists, its data is replaced | 164 previous node with the indicated KEY exists, its data is replaced |
129 template <typename KEY_TYPE, typename VALUE_TYPE> | 167 template <typename KEY_TYPE, typename VALUE_TYPE> |
130 inline void | 168 inline void |
131 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::insert (key_type key, | 169 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::insert (key_type key, |
132 value_type value) | 170 value_type value) |
133 { | 171 { |
134 splay_tree_insert (m_inner, | 172 splay_tree_insert (key, value); |
135 (splay_tree_key)key, | 173 } |
136 (splay_tree_value)value); | 174 |
175 /* Remove a node (associating KEY with VALUE). */ | |
176 | |
177 template <typename KEY_TYPE, typename VALUE_TYPE> | |
178 inline void | |
179 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::remove (key_type key) | |
180 { | |
181 splay_tree_remove (key); | |
137 } | 182 } |
138 | 183 |
139 /* Get the value with maximal key. */ | 184 /* Get the value with maximal key. */ |
140 | 185 |
141 template <typename KEY_TYPE, typename VALUE_TYPE> | 186 template <typename KEY_TYPE, typename VALUE_TYPE> |
142 inline VALUE_TYPE | 187 inline VALUE_TYPE |
143 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::max () | 188 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::max () |
144 { | 189 { |
145 return node_to_value (splay_tree_max (m_inner)); | 190 return node_to_value (splay_tree_max ()); |
146 } | 191 } |
147 | 192 |
148 /* Get the value with minimal key. */ | 193 /* Get the value with minimal key. */ |
149 | 194 |
150 template <typename KEY_TYPE, typename VALUE_TYPE> | 195 template <typename KEY_TYPE, typename VALUE_TYPE> |
151 inline VALUE_TYPE | 196 inline VALUE_TYPE |
152 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::min () | 197 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::min () |
153 { | 198 { |
154 return node_to_value (splay_tree_min (m_inner)); | 199 return node_to_value (splay_tree_min ()); |
155 } | 200 } |
156 | 201 |
157 /* Call OUTER_CB, passing it the OUTER_USER_DATA, for every node, | 202 /* Call OUTER_CB, passing it the OUTER_USER_DATA, for every node, |
158 following an in-order traversal. If OUTER_CB ever returns a non-zero | 203 following an in-order traversal. If OUTER_CB ever returns a non-zero |
159 value, the iteration ceases immediately, and the value is returned. | 204 value, the iteration ceases immediately, and the value is returned. |
160 Otherwise, this function returns 0. */ | 205 Otherwise, this function returns 0. */ |
161 | 206 |
162 template <typename KEY_TYPE, typename VALUE_TYPE> | 207 template <typename KEY_TYPE, typename VALUE_TYPE> |
163 inline int | 208 inline int |
164 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::foreach (foreach_fn outer_cb, | 209 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::foreach (foreach_fn foreach_fn, |
165 void *outer_user_data) | 210 void *user_data) |
166 { | 211 { |
167 closure c (outer_cb, outer_user_data); | 212 return splay_tree_foreach_helper (root, foreach_fn, user_data); |
168 | |
169 return splay_tree_foreach (m_inner, inner_foreach_fn, &c); | |
170 } | |
171 | |
172 /* Helper function for typed_splay_tree::foreach. */ | |
173 | |
174 template <typename KEY_TYPE, typename VALUE_TYPE> | |
175 int | |
176 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::inner_foreach_fn (splay_tree_node node, | |
177 void *user_data) | |
178 { | |
179 closure *c = (closure *)user_data; | |
180 | |
181 return c->m_outer_cb ((KEY_TYPE)node->key, (VALUE_TYPE)node->value, | |
182 c->m_outer_user_data); | |
183 } | 213 } |
184 | 214 |
185 /* Internal function for converting from splay_tree_node to | 215 /* Internal function for converting from splay_tree_node to |
186 VALUE_TYPE. */ | 216 VALUE_TYPE. */ |
187 template <typename KEY_TYPE, typename VALUE_TYPE> | 217 template <typename KEY_TYPE, typename VALUE_TYPE> |
188 inline VALUE_TYPE | 218 inline VALUE_TYPE |
189 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::node_to_value (splay_tree_node node) | 219 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::node_to_value (splay_tree_node node) |
190 { | 220 { |
191 if (node) | 221 if (node) |
192 return (value_type)node->value; | 222 return node->value; |
193 else | 223 else |
194 return 0; | 224 return 0; |
195 } | 225 } |
196 | 226 |
227 template <typename KEY_TYPE, typename VALUE_TYPE> | |
228 inline void | |
229 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::KDEL(splay_tree_key x) | |
230 { | |
231 if (delete_key) | |
232 (*delete_key)(x); | |
233 } | |
234 | |
235 template <typename KEY_TYPE, typename VALUE_TYPE> | |
236 inline void | |
237 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::VDEL(splay_tree_value x) | |
238 { | |
239 if (delete_value) | |
240 (*delete_value)(x); | |
241 } | |
242 | |
243 /* Deallocate NODE (a member of SP), and all its sub-trees. */ | |
244 | |
245 template <typename KEY_TYPE, typename VALUE_TYPE> | |
246 void | |
247 typed_splay_tree<KEY_TYPE, | |
248 VALUE_TYPE>::splay_tree_delete_helper (splay_tree_node node) | |
249 { | |
250 splay_tree_node pending = NULL; | |
251 splay_tree_node active = NULL; | |
252 | |
253 if (!node) | |
254 return; | |
255 | |
256 KDEL (node->key); | |
257 VDEL (node->value); | |
258 | |
259 /* We use the "back" field to hold the "next" pointer. */ | |
260 node->back = pending; | |
261 pending = node; | |
262 | |
263 /* Now, keep processing the pending list until there aren't any | |
264 more. This is a little more complicated than just recursing, but | |
265 it doesn't toast the stack for large trees. */ | |
266 | |
267 while (pending) | |
268 { | |
269 active = pending; | |
270 pending = NULL; | |
271 while (active) | |
272 { | |
273 splay_tree_node temp; | |
274 | |
275 /* active points to a node which has its key and value | |
276 deallocated, we just need to process left and right. */ | |
277 | |
278 if (active->left) | |
279 { | |
280 KDEL (active->left->key); | |
281 VDEL (active->left->value); | |
282 active->left->back = pending; | |
283 pending = active->left; | |
284 } | |
285 if (active->right) | |
286 { | |
287 KDEL (active->right->key); | |
288 VDEL (active->right->value); | |
289 active->right->back = pending; | |
290 pending = active->right; | |
291 } | |
292 | |
293 temp = active; | |
294 active = temp->back; | |
295 delete temp; | |
296 } | |
297 } | |
298 } | |
299 | |
300 /* Rotate the edge joining the left child N with its parent P. PP is the | |
301 grandparents' pointer to P. */ | |
302 | |
303 template <typename KEY_TYPE, typename VALUE_TYPE> | |
304 inline void | |
305 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::rotate_left (splay_tree_node *pp, | |
306 splay_tree_node p, | |
307 splay_tree_node n) | |
308 { | |
309 splay_tree_node tmp; | |
310 tmp = n->right; | |
311 n->right = p; | |
312 p->left = tmp; | |
313 *pp = n; | |
314 } | |
315 | |
316 /* Rotate the edge joining the right child N with its parent P. PP is the | |
317 grandparents' pointer to P. */ | |
318 | |
319 template <typename KEY_TYPE, typename VALUE_TYPE> | |
320 inline void | |
321 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::rotate_right (splay_tree_node *pp, | |
322 splay_tree_node p, | |
323 splay_tree_node n) | |
324 { | |
325 splay_tree_node tmp; | |
326 tmp = n->left; | |
327 n->left = p; | |
328 p->right = tmp; | |
329 *pp = n; | |
330 } | |
331 | |
332 /* Bottom up splay of key. */ | |
333 | |
334 template <typename KEY_TYPE, typename VALUE_TYPE> | |
335 void | |
336 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_splay (splay_tree_key key) | |
337 { | |
338 if (root == NULL) | |
339 return; | |
340 | |
341 do { | |
342 int cmp1, cmp2; | |
343 splay_tree_node n, c; | |
344 | |
345 n = root; | |
346 cmp1 = (*comp) (key, n->key); | |
347 | |
348 /* Found. */ | |
349 if (cmp1 == 0) | |
350 return; | |
351 | |
352 /* Left or right? If no child, then we're done. */ | |
353 if (cmp1 < 0) | |
354 c = n->left; | |
355 else | |
356 c = n->right; | |
357 if (!c) | |
358 return; | |
359 | |
360 /* Next one left or right? If found or no child, we're done | |
361 after one rotation. */ | |
362 cmp2 = (*comp) (key, c->key); | |
363 if (cmp2 == 0 | |
364 || (cmp2 < 0 && !c->left) | |
365 || (cmp2 > 0 && !c->right)) | |
366 { | |
367 if (cmp1 < 0) | |
368 rotate_left (&root, n, c); | |
369 else | |
370 rotate_right (&root, n, c); | |
371 return; | |
372 } | |
373 | |
374 /* Now we have the four cases of double-rotation. */ | |
375 if (cmp1 < 0 && cmp2 < 0) | |
376 { | |
377 rotate_left (&n->left, c, c->left); | |
378 rotate_left (&root, n, n->left); | |
379 } | |
380 else if (cmp1 > 0 && cmp2 > 0) | |
381 { | |
382 rotate_right (&n->right, c, c->right); | |
383 rotate_right (&root, n, n->right); | |
384 } | |
385 else if (cmp1 < 0 && cmp2 > 0) | |
386 { | |
387 rotate_right (&n->left, c, c->right); | |
388 rotate_left (&root, n, n->left); | |
389 } | |
390 else if (cmp1 > 0 && cmp2 < 0) | |
391 { | |
392 rotate_left (&n->right, c, c->left); | |
393 rotate_right (&root, n, n->right); | |
394 } | |
395 } while (1); | |
396 } | |
397 | |
398 /* Call FN, passing it the DATA, for every node below NODE, all of | |
399 which are from SP, following an in-order traversal. If FN every | |
400 returns a non-zero value, the iteration ceases immediately, and the | |
401 value is returned. Otherwise, this function returns 0. */ | |
402 | |
403 template <typename KEY_TYPE, typename VALUE_TYPE> | |
404 int | |
405 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_foreach_helper ( | |
406 splay_tree_node node, | |
407 foreach_fn fn, void *data) | |
408 { | |
409 int val; | |
410 splay_tree_node stack; | |
411 | |
412 /* A non-recursive implementation is used to avoid filling the stack | |
413 for large trees. Splay trees are worst case O(n) in the depth of | |
414 the tree. */ | |
415 | |
416 stack = NULL; | |
417 val = 0; | |
418 | |
419 for (;;) | |
420 { | |
421 while (node != NULL) | |
422 { | |
423 node->back = stack; | |
424 stack = node; | |
425 node = node->left; | |
426 } | |
427 | |
428 if (stack == NULL) | |
429 break; | |
430 | |
431 node = stack; | |
432 stack = stack->back; | |
433 | |
434 val = (*fn) (node->key, node->value, data); | |
435 if (val) | |
436 break; | |
437 | |
438 node = node->right; | |
439 } | |
440 | |
441 return val; | |
442 } | |
443 | |
444 /* Insert a new node (associating KEY with DATA) into SP. If a | |
445 previous node with the indicated KEY exists, its data is replaced | |
446 with the new value. Returns the new node. */ | |
447 | |
448 template <typename KEY_TYPE, typename VALUE_TYPE> | |
449 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
450 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_insert ( | |
451 splay_tree_key key, | |
452 splay_tree_value value) | |
453 { | |
454 int comparison = 0; | |
455 | |
456 splay_tree_splay (key); | |
457 | |
458 if (root) | |
459 comparison = (*comp)(root->key, key); | |
460 | |
461 if (root && comparison == 0) | |
462 { | |
463 /* If the root of the tree already has the indicated KEY, just | |
464 replace the value with VALUE. */ | |
465 VDEL(root->value); | |
466 root->value = value; | |
467 } | |
468 else | |
469 { | |
470 /* Create a new node, and insert it at the root. */ | |
471 splay_tree_node node; | |
472 | |
473 node = new splay_tree_node_s; | |
474 node->key = key; | |
475 node->value = value; | |
476 | |
477 if (!root) | |
478 node->left = node->right = 0; | |
479 else if (comparison < 0) | |
480 { | |
481 node->left = root; | |
482 node->right = node->left->right; | |
483 node->left->right = 0; | |
484 } | |
485 else | |
486 { | |
487 node->right = root; | |
488 node->left = node->right->left; | |
489 node->right->left = 0; | |
490 } | |
491 | |
492 root = node; | |
493 } | |
494 | |
495 return root; | |
496 } | |
497 | |
498 /* Remove KEY from SP. It is not an error if it did not exist. */ | |
499 | |
500 template <typename KEY_TYPE, typename VALUE_TYPE> | |
501 void | |
502 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_remove (splay_tree_key key) | |
503 { | |
504 splay_tree_splay (key); | |
505 | |
506 if (root && (*comp) (root->key, key) == 0) | |
507 { | |
508 splay_tree_node left, right; | |
509 | |
510 left = root->left; | |
511 right = root->right; | |
512 | |
513 /* Delete the root node itself. */ | |
514 VDEL (root->value); | |
515 delete root; | |
516 | |
517 /* One of the children is now the root. Doesn't matter much | |
518 which, so long as we preserve the properties of the tree. */ | |
519 if (left) | |
520 { | |
521 root = left; | |
522 | |
523 /* If there was a right child as well, hang it off the | |
524 right-most leaf of the left child. */ | |
525 if (right) | |
526 { | |
527 while (left->right) | |
528 left = left->right; | |
529 left->right = right; | |
530 } | |
531 } | |
532 else | |
533 root = right; | |
534 } | |
535 } | |
536 | |
537 /* Lookup KEY in SP, returning VALUE if present, and NULL | |
538 otherwise. */ | |
539 | |
540 template <typename KEY_TYPE, typename VALUE_TYPE> | |
541 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
542 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_lookup (splay_tree_key key) | |
543 { | |
544 splay_tree_splay (key); | |
545 | |
546 if (root && (*comp)(root->key, key) == 0) | |
547 return root; | |
548 else | |
549 return 0; | |
550 } | |
551 | |
552 /* Return the node in SP with the greatest key. */ | |
553 | |
554 template <typename KEY_TYPE, typename VALUE_TYPE> | |
555 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
556 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_max () | |
557 { | |
558 splay_tree_node n = root; | |
559 | |
560 if (!n) | |
561 return NULL; | |
562 | |
563 while (n->right) | |
564 n = n->right; | |
565 | |
566 return n; | |
567 } | |
568 | |
569 /* Return the node in SP with the smallest key. */ | |
570 | |
571 template <typename KEY_TYPE, typename VALUE_TYPE> | |
572 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
573 typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_min () | |
574 { | |
575 splay_tree_node n = root; | |
576 | |
577 if (!n) | |
578 return NULL; | |
579 | |
580 while (n->left) | |
581 n = n->left; | |
582 | |
583 return n; | |
584 } | |
585 | |
586 /* Return the immediate predecessor KEY, or NULL if there is no | |
587 predecessor. KEY need not be present in the tree. */ | |
588 | |
589 template <typename KEY_TYPE, typename VALUE_TYPE> | |
590 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
591 typed_splay_tree<KEY_TYPE, | |
592 VALUE_TYPE>::splay_tree_predecessor (splay_tree_key key) | |
593 { | |
594 int comparison; | |
595 splay_tree_node node; | |
596 | |
597 /* If the tree is empty, there is certainly no predecessor. */ | |
598 if (!root) | |
599 return NULL; | |
600 | |
601 /* Splay the tree around KEY. That will leave either the KEY | |
602 itself, its predecessor, or its successor at the root. */ | |
603 splay_tree_splay (key); | |
604 comparison = (*comp)(root->key, key); | |
605 | |
606 /* If the predecessor is at the root, just return it. */ | |
607 if (comparison < 0) | |
608 return root; | |
609 | |
610 /* Otherwise, find the rightmost element of the left subtree. */ | |
611 node = root->left; | |
612 if (node) | |
613 while (node->right) | |
614 node = node->right; | |
615 | |
616 return node; | |
617 } | |
618 | |
619 /* Return the immediate successor KEY, or NULL if there is no | |
620 successor. KEY need not be present in the tree. */ | |
621 | |
622 template <typename KEY_TYPE, typename VALUE_TYPE> | |
623 typename typed_splay_tree<KEY_TYPE, VALUE_TYPE>::splay_tree_node | |
624 typed_splay_tree<KEY_TYPE, | |
625 VALUE_TYPE>::splay_tree_successor (splay_tree_key key) | |
626 { | |
627 int comparison; | |
628 splay_tree_node node; | |
629 | |
630 /* If the tree is empty, there is certainly no successor. */ | |
631 if (!root) | |
632 return NULL; | |
633 | |
634 /* Splay the tree around KEY. That will leave either the KEY | |
635 itself, its predecessor, or its successor at the root. */ | |
636 splay_tree_splay (key); | |
637 comparison = (*comp)(root->key, key); | |
638 | |
639 /* If the successor is at the root, just return it. */ | |
640 if (comparison > 0) | |
641 return root; | |
642 | |
643 /* Otherwise, find the leftmost element of the right subtree. */ | |
644 node = root->right; | |
645 if (node) | |
646 while (node->left) | |
647 node = node->left; | |
648 | |
649 return node; | |
650 } | |
651 | |
197 #endif /* GCC_TYPED_SPLAY_TREE_H */ | 652 #endif /* GCC_TYPED_SPLAY_TREE_H */ |