annotate gcc/typed-splay-tree.h @ 145:1830386684a0

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