Annotation of /home/cljanss/src/SC/src/lib/util/container/eavlmmap.h for ./mpqc.vmon.0018
1 //
2 // eavlmmap.h --- definition for embedded avl multimap class
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27
28 #ifndef _util_container_eavlmmap_h
29 #define _util_container_eavlmmap_h
30
31 #ifdef HAVE_CONFIG_H
32 # include <scconfig.h>
33 #endif
34 #include <iostream>
35 #include <util/misc/exenv.h>
36 #include <util/container/compare.h>
37 #include <unistd.h> // for size_t on solaris
38 #include <stdlib.h>
39
40 #ifdef __GNUC__
41 // gcc typename seems to be broken in some cases
42 # define eavl_typename
43 #else
44 1 0 0 0 0 0 0 0 0 0 # define eavl_typename typename
45 #endif
46
47 template <class K, class T>
48 class EAVLMMapNode {
49 public:
50 K key;
51 T* lt;
52 T* rt;
53 T* up;
54 int balance;
55 public:
56 1 0 0 0 0 0 0 0 0 0 EAVLMMapNode(const K& k): key(k) {}
57 };
58
59 template <class K, class T>
60 class EAVLMMap {
61 private:
62 size_t length_;
63 T *root_;
64 T *start_;
65 EAVLMMapNode<K,T> T::* node_;
66 public:
67 #if defined(__GNUC__) && defined(__alpha__)
68 T*& rlink(const T* n) const { T*& r = (n->*node_).rt; return r; }
69 T*& llink(const T* n) const { T*& r = (n->*node_).lt; return r; }
70 T*& uplink(const T* n) const { T*& r = (n->*node_).up; return r; }
71 int& balance(const T* n) const { int& r = (n->*node_).balance; return r; }
72 K& key(T* n) const { K& r = (n->*node_).key; return r; }
73 const K& key(const T* n) const { K& r = (n->*node_).key; return r; }
74 #else
75 490 0 115 211 90 19 1 4 0 0 T*& rlink(T* n) const { return (n->*node_).rt; }
76 T* rlink(const T* n) const { return (n->*node_).rt; }
77 535 0 162 158 121 34 5 2 4 0 T*& llink(T* n) const { return (n->*node_).lt; }
78 1 0 0 1 0 0 0 0 0 0 T* llink(const T* n) const { return (n->*node_).lt; }
79 140 0 36 13 45 6 2 0 2 0 T*& uplink(T* n) const { return (n->*node_).up; }
80 0 0 1 0 1 0 0 0 0 0 T* uplink(const T* n) const { return (n->*node_).up; }
81 279 0 113 49 59 19 5 1 1 0 int& balance(T* n) const { return (n->*node_).balance; }
82 int balance(const T* n) const { return (n->*node_).balance; }
83 143 0 23 73 24 5 1 4 0 0 K& key(T* n) const { return (n->*node_).key; }
84 const K& key(const T* n) const { return (n->*node_).key; }
85 #endif
86 int compare(T*n,T*m) const { return ::compare(key(n), key(m)); }
87 int compare(T*n,const K&m) const { return ::compare(key(n), m); }
88 private:
89 void adjust_balance_insert(T* A, T* child);
90 void adjust_balance_remove(T* A, T* child);
91 void clear(T*);
92 public:
93 class iterator {
94 private:
95 EAVLMMap<K,T> *map_;
96 T *node;
97 public:
98 iterator(EAVLMMap<K,T> *m, T *n):map_(m),node(n){}
99 iterator(const eavl_typename EAVLMMap<K,T>::iterator &i) { map_=i.map_; node=i.node; }
100 void operator++() { map_->next(node); }
101 void operator++(int) { operator++(); }
102 int operator == (const eavl_typename EAVLMMap<K,T>::iterator &i) const
103 { return map_ == i.map_ && node == i.node; }
104 int operator != (const eavl_typename EAVLMMap<K,T>::iterator &i) const
105 { return !operator == (i); }
106 void operator = (const eavl_typename EAVLMMap<K,T>::iterator &i)
107 { map_ = i.map_; node = i.node; }
108 const K &key() const { return map_->key(node); }
109 T & operator *() { return *node; }
110 T * operator->() { return node; }
111 };
112 public:
113 EAVLMMap();
114 EAVLMMap(EAVLMMapNode<K,T> T::* node);
115 3 0 2 1 2 0 0 1 0 0 ~EAVLMMap() { clear(root_); }
116 void initialize(EAVLMMapNode<K,T> T::* node);
117 void clear_without_delete() { initialize(node_); }
118 void clear() { clear(root_); initialize(node_); }
119 void insert(T*);
120 void remove(T*);
121 T* find(const K&) const;
122
123 int height(T* node);
124 int height() { return height(root_); }
125 void check();
126 void check_node(T*) const;
127
128 5 0 1 3 2 0 0 0 0 0 T* start() const { return start_; }
129 void next(const T*&) const;
130 void next(T*&) const;
131
132 iterator begin() { return iterator(this,start()); }
133 iterator end() { return iterator(this,0); }
134
135 void print();
136 int length() const { return length_; }
137 int depth(T*);
138 };
139
140 template <class K, class T>
141 T*
142 EAVLMMap<K,T>::find(const K& key) const
143 400 0 148 12 45 0 0 0 0 0 {
144 7 0 2 0 0 0 0 0 0 0 T* n = root_;
145
146 1064 0 141 487 125 12 0 5 8 0 while (n) {
147 int cmp = compare(n, key);
148 184 0 12 126 2 6 0 0 0 0 if (cmp < 0) n = rlink(n);
149 105 0 9 56 2 2 0 2 0 0 else if (cmp > 0) n = llink(n);
150 95 0 19 73 4 8 1 1 1 0 else return n;
151 }
152
153 145 0 23 117 10 3 0 2 0 0 return 0;
154 }
155
156 template <class K, class T>
157 void
158 EAVLMMap<K,T>::remove(T* node)
159 12 0 8 1 1 1 0 0 0 0 {
160 0 0 0 2 0 0 0 0 0 0 if (!node) return;
161
162 1 0 1 1 1 0 0 0 0 0 length_--;
163
164 28 0 3 14 1 0 0 1 0 0 if (node == start_) {
165 3 0 0 2 1 1 0 0 0 0 next(start_);
166 }
167
168 T *rebalance_point;
169 T *q;
170
171 if (llink(node) == 0) {
172 q = rlink(node);
173 rebalance_point = uplink(node);
174
175 if (q) uplink(q) = rebalance_point;
176
177 0 0 0 1 0 0 0 0 0 0 if (rebalance_point) {
178 if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;
179 else llink(rebalance_point) = q;
180 }
181 0 0 0 1 1 1 0 0 0 0 else root_ = q;
182 }
183 else if (rlink(node) == 0) {
184 q = llink(node);
185 rebalance_point = uplink(node);
186
187 if (q) uplink(q) = rebalance_point;
188
189 if (rebalance_point) {
190 if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;
191 else llink(rebalance_point) = q;
192 }
193 else root_ = q;
194 }
195 else {
196 T *r = node;
197 1 0 1 1 0 0 0 0 0 0 next(r);
198
199 1 0 0 0 0 0 0 0 0 0 if (r == 0 || llink(r) != 0) {
200 ExEnv::err() << "EAVLMMap::remove: inconsistency" << std::endl;
201 1 0 0 0 0 0 0 0 0 0 abort();
202 }
203
204 if (r == rlink(node)) {
205 llink(r) = llink(node);
206 if (llink(r)) uplink(llink(r)) = r;
207 balance(r) = balance(node);
208 1 0 0 0 0 0 0 0 0 0 rebalance_point = r;
209 q = rlink(r);
210 }
211 else {
212 q = rlink(r);
213
214 rebalance_point = uplink(r);
215
216 if (llink(rebalance_point) == r) llink(rebalance_point) = q;
217 else rlink(rebalance_point) = q;
218
219 if (q) uplink(q) = rebalance_point;
220
221 balance(r) = balance(node);
222 rlink(r) = rlink(node);
223 llink(r) = llink(node);
224 if (rlink(r)) uplink(rlink(r)) = r;
225 if (llink(r)) uplink(llink(r)) = r;
226 }
227 2 0 0 0 0 0 0 1 0 0 if (r) {
228 T* up = uplink(node);
229 uplink(r) = up;
230 if (up) {
231 if (rlink(up) == node) rlink(up) = r;
232 else llink(up) = r;
233 }
234 1 0 0 1 0 0 0 0 0 0 if (up == 0) root_ = r;
235 }
236 }
237
238 // adjust balance won't work if both children are null,
239 // so handle this special case here
240 4 0 6 1 2 1 0 0 0 0 if (rebalance_point &&
241 llink(rebalance_point) == 0 && rlink(rebalance_point) == 0) {
242 balance(rebalance_point) = 0;
243 q = rebalance_point;
244 rebalance_point = uplink(rebalance_point);
245 }
246 15 0 4 1 3 1 0 1 0 0 adjust_balance_remove(rebalance_point, q);
247 }
248
249 template <class K, class T>
250 void
251 EAVLMMap<K,T>::print()
252 {
253 for (T*n=start(); n; next(n)) {
254 int d = depth(n) + 1;
255 for (int i=0; i<d; i++) ExEnv::out() << " ";
256 if (balance(n) == 1) ExEnv::out() << " (+)" << std::endl;
257 else if (balance(n) == -1) ExEnv::out() << " (-)" << std::endl;
258 else if (balance(n) == 0) ExEnv::out() << " (.)" << std::endl;
259 else ExEnv::out() << " (" << balance(n) << ")" << std::endl;
260 }
261 }
262
263 template <class K, class T>
264 int
265 EAVLMMap<K,T>::depth(T*node)
266 {
267 int d = 0;
268 while (node) {
269 node = uplink(node);
270 d++;
271 }
272 return d;
273 }
274 1 0 0 0 0 0 0 0 0 0
275 template <class K, class T>
276 void
277 EAVLMMap<K,T>::check_node(T*n) const
278 {
279 if (uplink(n) && uplink(n) == n) abort();
280 if (llink(n) && llink(n) == n) abort();
281 if (rlink(n) && rlink(n) == n) abort();
282 if (rlink(n) && rlink(n) == llink(n)) abort();
283 if (uplink(n) && uplink(n) == llink(n)) abort();
284 if (uplink(n) && uplink(n) == rlink(n)) abort();
285 if (uplink(n) && !(llink(uplink(n)) == n
286 || rlink(uplink(n)) == n)) abort();
287 }
288
289 template <class K, class T>
290 void
291 EAVLMMap<K,T>::clear(T*n)
292 18 0 2 8 3 0 0 0 0 0 {
293 0 0 0 1 0 0 0 0 0 0 if (!n) return;
294 110 0 28 86 27 7 0 0 0 0 clear(llink(n));
295 27 0 6 15 5 0 0 0 0 0 clear(rlink(n));
296 21 0 4 9 1 1 0 0 0 0 delete n;
297 }
298
299 template <class K, class T>
300 int
301 EAVLMMap<K,T>::height(T* node)
302 {
303 if (!node) return 0;
304 int rh = height(rlink(node)) + 1;
305 int lh = height(llink(node)) + 1;
306 return rh>lh?rh:lh;
307 }
308
309 template <class K, class T>
310 void
311 EAVLMMap<K,T>::check()
312 {
313 T* node;
314 T* prev=0;
315 size_t computed_length = 0;
316 for (node = start(); node; next(node)) {
317 check_node(node);
318 if (prev && compare(prev,node) > 0) {
319 ExEnv::err() << "nodes out of order" << std::endl;
320 abort();
321 }
322 prev = node;
323 computed_length++;
324 }
325 for (node = start(); node; next(node)) {
326 if (balance(node) != height(rlink(node)) - height(llink(node))) {
327 ExEnv::err() << "balance inconsistency" << std::endl;
328 abort();
329 }
330 if (balance(node) < -1 || balance(node) > 1) {
331 ExEnv::err() << "balance out of range" << std::endl;
332 abort();
333 }
334 }
335 if (length_ != computed_length) {
336 ExEnv::err() << "length error" << std::endl;
337 abort();
338 }
339 }
340
341 template <class K, class T>
342 void
343 EAVLMMap<K,T>::next(const T*& node) const
344 {
345 const T* r;
346 if (r = rlink(node)) {
347 node = r;
348 while (r = llink(node)) node = r;
349 return;
350 }
351 while (r = uplink(node)) {
352 if (node == llink(r)) {
353 node = r;
354 return;
355 }
356 node = r;
357 }
358 node = 0;
359 }
360
361 template <class K, class T>
362 void
363 EAVLMMap<K,T>::next(T*& node) const
364 208 0 64 32 28 6 0 2 0 0 {
365 T* r;
366 if (r = rlink(node)) {
367 5 0 1 2 5 2 0 2 0 0 node = r;
368 while (r = llink(node)) node = r;
369 return;
370 }
371 while (r = uplink(node)) {
372 if (node == llink(r)) {
373 3 0 3 0 3 0 0 0 0 0 node = r;
374 9 0 11 1 6 0 0 0 0 0 return;
375 }
376 node = r;
377 }
378 56 0 19 11 9 5 0 0 0 0 node = 0;
379 }
380
381 template <class K, class T>
382 void
383 EAVLMMap<K,T>::insert(T* n)
384 117 0 23 2 19 1 0 2 0 0 {
385 5 0 0 0 0 0 0 0 0 0 if (!n) {
386 return;
387 }
388
389 59 0 9 17 8 0 0 1 0 0 length_++;
390
391 rlink(n) = 0;
392 llink(n) = 0;
393 balance(n) = 0;
394
395 11 0 1 4 2 1 0 0 0 0 if (!root_) {
396 uplink(n) = 0;
397 0 0 1 0 0 0 0 0 0 0 root_ = n;
398 1 0 0 0 0 0 0 0 0 0 start_ = n;
399 19 0 1 1 0 0 0 0 0 0 return;
400 }
401
402 // find an insertion point
403 T* p = root_;
404 T* prev_p = 0;
405 int cmp;
406 31 0 4 2 1 0 0 0 0 0 int have_start = 1;
407 while (p) {
408 85 0 21 30 18 3 1 0 0 0 if (p == n) {
409 abort();
410 }
411 31 0 15 7 7 0 0 0 0 0 prev_p = p;
412 cmp = compare(n,p);
413 70 0 19 43 16 2 0 0 0 0 if (cmp < 0) p = llink(p);
414 else {
415 p = rlink(p);
416 28 0 9 12 5 1 0 0 0 0 have_start = 0;
417 }
418 }
419
420 // insert the node
421 uplink(n) = prev_p;
422 0 0 1 0 0 0 0 0 0 0 if (prev_p) {
423 3 0 1 2 2 0 0 0 0 0 if (cmp < 0) llink(prev_p) = n;
424 else rlink(prev_p) = n;
425 }
426
427 // maybe update the first node in the map
428 5 0 8 5 3 1 0 0 0 0 if (have_start) start_ = n;
429
430 // adjust the balance factors
431 15 0 7 10 5 3 2 0 0 0 if (prev_p) {
432 60 0 25 11 8 6 2 1 0 0 adjust_balance_insert(prev_p, n);
433 }
434 }
435
436 template <class K, class T>
437 void
438 EAVLMMap<K,T>::adjust_balance_insert(T* A, T* child)
439 95 0 37 9 18 9 3 0 0 0 {
440 4 0 4 1 1 1 0 0 0 0 if (!A) return;
441 int adjustment;
442 if (llink(A) == child) adjustment = -1;
443 else adjustment = 1;
444 int bal = balance(A) + adjustment;
445 0 0 2 0 0 0 0 0 0 0 if (bal == 0) {
446 balance(A) = 0;
447 }
448 39 0 19 3 7 4 1 0 0 0 else if (bal == -1 || bal == 1) {
449 balance(A) = bal;
450 34 0 13 8 16 5 1 0 0 0 adjust_balance_insert(uplink(A), A);
451 }
452 15 0 5 2 7 0 1 0 0 0 else if (bal == 2) {
453 T* B = rlink(A);
454 if (balance(B) == 1) {
455 balance(B) = 0;
456 balance(A) = 0;
457 rlink(A) = llink(B);
458 llink(B) = A;
459 uplink(B) = uplink(A);
460 uplink(A) = B;
461 if (rlink(A)) uplink(rlink(A)) = A;
462 if (llink(B)) uplink(llink(B)) = B;
463 if (uplink(B) == 0) root_ = B;
464 else {
465 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
466 else llink(uplink(B)) = B;
467 }
468 }
469 else {
470 T* X = llink(B);
471 rlink(A) = llink(X);
472 llink(B) = rlink(X);
473 llink(X) = A;
474 rlink(X) = B;
475 if (balance(X) == 1) {
476 balance(A) = -1;
477 balance(B) = 0;
478 }
479 else if (balance(X) == -1) {
480 balance(A) = 0;
481 balance(B) = 1;
482 }
483 else {
484 balance(A) = 0;
485 balance(B) = 0;
486 }
487 balance(X) = 0;
488 uplink(X) = uplink(A);
489 uplink(A) = X;
490 uplink(B) = X;
491 if (rlink(A)) uplink(rlink(A)) = A;
492 if (llink(B)) uplink(llink(B)) = B;
493 0 0 0 0 1 0 0 0 0 0 if (uplink(X) == 0) root_ = X;
494 else {
495 if (rlink(uplink(X)) == A) rlink(uplink(X)) = X;
496 else llink(uplink(X)) = X;
497 }
498 }
499 }
500 25 0 19 4 10 2 0 0 0 0 else if (bal == -2) {
501 T* B = llink(A);
502 if (balance(B) == -1) {
503 balance(B) = 0;
504 balance(A) = 0;
505 llink(A) = rlink(B);
506 rlink(B) = A;
507 uplink(B) = uplink(A);
508 uplink(A) = B;
509 if (llink(A)) uplink(llink(A)) = A;
510 if (rlink(B)) uplink(rlink(B)) = B;
511 13 0 9 1 4 2 1 0 0 0 if (uplink(B) == 0) root_ = B;
512 else {
513 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
514 else rlink(uplink(B)) = B;
515 }
516 }
517 else {
518 T* X = rlink(B);
519 llink(A) = rlink(X);
520 rlink(B) = llink(X);
521 rlink(X) = A;
522 llink(X) = B;
523 if (balance(X) == -1) {
524 balance(A) = 1;
525 balance(B) = 0;
526 }
527 else if (balance(X) == 1) {
528 balance(A) = 0;
529 balance(B) = -1;
530 }
531 else {
532 balance(A) = 0;
533 balance(B) = 0;
534 }
535 balance(X) = 0;
536 uplink(X) = uplink(A);
537 uplink(A) = X;
538 uplink(B) = X;
539 if (llink(A)) uplink(llink(A)) = A;
540 if (rlink(B)) uplink(rlink(B)) = B;
541 0 0 0 0 1 0 0 0 0 0 if (uplink(X) == 0) root_ = X;
542 else {
543 if (llink(uplink(X)) == A) llink(uplink(X)) = X;
544 110 0 29 3 25 5 2 1 0 0 else rlink(uplink(X)) = X;
545 }
546 }
547 }
548 }
549
550 template <class K, class T>
551 void
552 EAVLMMap<K,T>::adjust_balance_remove(T* A, T* child)
553 20 0 4 8 4 1 0 1 0 0 {
554 0 0 0 0 1 0 0 0 0 0 if (!A) return;
555 int adjustment;
556 if (llink(A) == child) adjustment = 1;
557 else adjustment = -1;
558 int bal = balance(A) + adjustment;
559 if (bal == 0) {
560 balance(A) = 0;
561 4 0 1 1 0 0 0 0 0 0 adjust_balance_remove(uplink(A), A);
562 }
563 8 0 4 3 1 0 0 0 0 0 else if (bal == -1 || bal == 1) {
564 balance(A) = bal;
565 }
566 1 0 1 0 0 0 0 0 0 0 else if (bal == 2) {
567 T* B = rlink(A);
568 if (balance(B) == 0) {
569 balance(B) = -1;
570 balance(A) = 1;
571 rlink(A) = llink(B);
572 llink(B) = A;
573 uplink(B) = uplink(A);
574 uplink(A) = B;
575 if (rlink(A)) uplink(rlink(A)) = A;
576 if (llink(B)) uplink(llink(B)) = B;
577 if (uplink(B) == 0) root_ = B;
578 else {
579 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
580 else llink(uplink(B)) = B;
581 }
582 }
583 else if (balance(B) == 1) {
584 balance(B) = 0;
585 balance(A) = 0;
586 rlink(A) = llink(B);
587 llink(B) = A;
588 uplink(B) = uplink(A);
589 uplink(A) = B;
590 if (rlink(A)) uplink(rlink(A)) = A;
591 if (llink(B)) uplink(llink(B)) = B;
592 if (uplink(B) == 0) root_ = B;
593 else {
594 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
595 else llink(uplink(B)) = B;
596 }
597 adjust_balance_remove(uplink(B), B);
598 }
599 else {
600 T* X = llink(B);
601 rlink(A) = llink(X);
602 llink(B) = rlink(X);
603 llink(X) = A;
604 rlink(X) = B;
605 if (balance(X) == 0) {
606 balance(A) = 0;
607 balance(B) = 0;
608 }
609 else if (balance(X) == 1) {
610 balance(A) = -1;
611 balance(B) = 0;
612 }
613 else {
614 balance(A) = 0;
615 balance(B) = 1;
616 }
617 balance(X) = 0;
618 uplink(X) = uplink(A);
619 uplink(A) = X;
620 uplink(B) = X;
621 if (rlink(A)) uplink(rlink(A)) = A;
622 if (llink(B)) uplink(llink(B)) = B;
623 if (uplink(X) == 0) root_ = X;
624 else {
625 if (rlink(uplink(X)) == A) rlink(uplink(X)) = X;
626 else llink(uplink(X)) = X;
627 }
628 adjust_balance_remove(uplink(X), X);
629 }
630 }
631 1 0 0 0 0 0 0 0 0 0 else if (bal == -2) {
632 T* B = llink(A);
633 if (balance(B) == 0) {
634 balance(B) = 1;
635 balance(A) = -1;
636 llink(A) = rlink(B);
637 rlink(B) = A;
638 uplink(B) = uplink(A);
639 uplink(A) = B;
640 if (llink(A)) uplink(llink(A)) = A;
641 if (rlink(B)) uplink(rlink(B)) = B;
642 4 0 0 1 0 1 0 0 0 0 if (uplink(B) == 0) root_ = B;
643 else {
644 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
645 else rlink(uplink(B)) = B;
646 }
647 }
648 else if (balance(B) == -1) {
649 balance(B) = 0;
650 balance(A) = 0;
651 llink(A) = rlink(B);
652 rlink(B) = A;
653 uplink(B) = uplink(A);
654 uplink(A) = B;
655 if (llink(A)) uplink(llink(A)) = A;
656 if (rlink(B)) uplink(rlink(B)) = B;
657 if (uplink(B) == 0) root_ = B;
658 else {
659 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
660 else rlink(uplink(B)) = B;
661 }
662 adjust_balance_remove(uplink(B), B);
663 }
664 else {
665 T* X = rlink(B);
666 llink(A) = rlink(X);
667 rlink(B) = llink(X);
668 rlink(X) = A;
669 llink(X) = B;
670 if (balance(X) == 0) {
671 balance(A) = 0;
672 balance(B) = 0;
673 }
674 else if (balance(X) == -1) {
675 balance(A) = 1;
676 balance(B) = 0;
677 }
678 else {
679 balance(A) = 0;
680 balance(B) = -1;
681 }
682 balance(X) = 0;
683 uplink(X) = uplink(A);
684 uplink(A) = X;
685 uplink(B) = X;
686 if (llink(A)) uplink(llink(A)) = A;
687 if (rlink(B)) uplink(rlink(B)) = B;
688 1 0 0 0 0 0 0 0 0 0 if (uplink(X) == 0) root_ = X;
689 else {
690 if (llink(uplink(X)) == A) llink(uplink(X)) = X;
691 else rlink(uplink(X)) = X;
692 }
693 19 0 4 3 2 0 0 0 0 0 adjust_balance_remove(uplink(X), X);
694 }
695 }
696 }
697
698 template <class K, class T>
699 inline
700 EAVLMMap<K,T>::EAVLMMap()
701 {
702 initialize(0);
703 }
704
705 template <class K, class T>
706 inline
707 EAVLMMap<K,T>::EAVLMMap(EAVLMMapNode<K,T> T::* node)
708 {
709 initialize(node);
710 }
711
712 template <class K, class T>
713 inline void
714 EAVLMMap<K,T>::initialize(EAVLMMapNode<K,T> T::* node)
715 {
716 4 0 0 4 1 0 0 0 0 0 node_ = node;
717 3 0 1 1 1 0 0 0 0 0 root_ = 0;
718 start_ = 0;
719 17 0 5 12 2 0 0 0 0 0 length_ = 0;
720 }
721
722 #endif
723
724 // ///////////////////////////////////////////////////////////////////////////
725
726 // Local Variables:
727 // mode: c++
728 // c-file-style: "CLJ"
729 // End:
730