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 */