Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / ada / a-rbtgso.adb
blob6742e285291c836fed125d7fd073ba414d905f4d
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- A D A . C O N T A I N E R S . R E D _ B L A C K _ T R E E S . --
6 -- G E N E R I C _ S E T _ O P E R A T I O N S --
7 -- --
8 -- B o d y --
9 -- --
10 -- Copyright (C) 2004-2005, Free Software Foundation, Inc. --
11 -- --
12 -- This specification is derived from the Ada Reference Manual for use with --
13 -- GNAT. The copyright notice above, and the license provisions that follow --
14 -- apply solely to the contents of the part following the private keyword. --
15 -- --
16 -- GNAT is free software; you can redistribute it and/or modify it under --
17 -- terms of the GNU General Public License as published by the Free Soft- --
18 -- ware Foundation; either version 2, or (at your option) any later ver- --
19 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
20 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
21 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
22 -- for more details. You should have received a copy of the GNU General --
23 -- Public License distributed with GNAT; see file COPYING. If not, write --
24 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
25 -- Boston, MA 02110-1301, USA. --
26 -- --
27 -- As a special exception, if other files instantiate generics from this --
28 -- unit, or you link this unit with other files to produce an executable, --
29 -- this unit does not by itself cause the resulting executable to be --
30 -- covered by the GNU General Public License. This exception does not --
31 -- however invalidate any other reasons why the executable file might be --
32 -- covered by the GNU Public License. --
33 -- --
34 -- This unit was originally developed by Matthew J Heaney. --
35 ------------------------------------------------------------------------------
37 with System; use type System.Address;
39 package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
45 procedure Clear (Tree : in out Tree_Type);
47 function Copy (Source : Tree_Type) return Tree_Type;
49 -----------
50 -- Clear --
51 -----------
53 procedure Clear (Tree : in out Tree_Type) is
54 pragma Assert (Tree.Busy = 0);
55 pragma Assert (Tree.Lock = 0);
57 Root : Node_Access := Tree.Root;
59 begin
60 Tree.Root := null;
61 Tree.First := null;
62 Tree.Last := null;
63 Tree.Length := 0;
65 Delete_Tree (Root);
66 end Clear;
68 ----------
69 -- Copy --
70 ----------
72 function Copy (Source : Tree_Type) return Tree_Type is
73 Target : Tree_Type;
75 begin
76 if Source.Length = 0 then
77 return Target;
78 end if;
80 Target.Root := Copy_Tree (Source.Root);
81 Target.First := Tree_Operations.Min (Target.Root);
82 Target.Last := Tree_Operations.Max (Target.Root);
83 Target.Length := Source.Length;
85 return Target;
86 end Copy;
88 ----------------
89 -- Difference --
90 ----------------
92 procedure Difference (Target : in out Tree_Type; Source : Tree_Type) is
93 Tgt : Node_Access := Target.First;
94 Src : Node_Access := Source.First;
96 begin
97 if Target'Address = Source'Address then
98 if Target.Busy > 0 then
99 raise Program_Error;
100 end if;
102 Clear (Target);
103 return;
104 end if;
106 if Source.Length = 0 then
107 return;
108 end if;
110 if Target.Busy > 0 then
111 raise Program_Error;
112 end if;
114 loop
115 if Tgt = null then
116 return;
117 end if;
119 if Src = null then
120 return;
121 end if;
123 if Is_Less (Tgt, Src) then
124 Tgt := Tree_Operations.Next (Tgt);
126 elsif Is_Less (Src, Tgt) then
127 Src := Tree_Operations.Next (Src);
129 else
130 declare
131 X : Node_Access := Tgt;
132 begin
133 Tgt := Tree_Operations.Next (Tgt);
134 Tree_Operations.Delete_Node_Sans_Free (Target, X);
135 Free (X);
136 end;
138 Src := Tree_Operations.Next (Src);
139 end if;
140 end loop;
141 end Difference;
143 function Difference (Left, Right : Tree_Type) return Tree_Type is
144 Tree : Tree_Type;
146 L_Node : Node_Access := Left.First;
147 R_Node : Node_Access := Right.First;
149 Dst_Node : Node_Access;
151 begin
152 if Left'Address = Right'Address then
153 return Tree; -- Empty set
154 end if;
156 if Left.Length = 0 then
157 return Tree; -- Empty set
158 end if;
160 if Right.Length = 0 then
161 return Copy (Left);
162 end if;
164 loop
165 if L_Node = null then
166 return Tree;
167 end if;
169 if R_Node = null then
170 while L_Node /= null loop
171 Insert_With_Hint
172 (Dst_Tree => Tree,
173 Dst_Hint => null,
174 Src_Node => L_Node,
175 Dst_Node => Dst_Node);
177 L_Node := Tree_Operations.Next (L_Node);
179 end loop;
181 return Tree;
182 end if;
184 if Is_Less (L_Node, R_Node) then
185 Insert_With_Hint
186 (Dst_Tree => Tree,
187 Dst_Hint => null,
188 Src_Node => L_Node,
189 Dst_Node => Dst_Node);
191 L_Node := Tree_Operations.Next (L_Node);
193 elsif Is_Less (R_Node, L_Node) then
194 R_Node := Tree_Operations.Next (R_Node);
196 else
197 L_Node := Tree_Operations.Next (L_Node);
198 R_Node := Tree_Operations.Next (R_Node);
199 end if;
200 end loop;
202 exception
203 when others =>
204 Delete_Tree (Tree.Root);
205 raise;
206 end Difference;
208 ------------------
209 -- Intersection --
210 ------------------
212 procedure Intersection
213 (Target : in out Tree_Type;
214 Source : Tree_Type)
216 Tgt : Node_Access := Target.First;
217 Src : Node_Access := Source.First;
219 begin
220 if Target'Address = Source'Address then
221 return;
222 end if;
224 if Target.Busy > 0 then
225 raise Program_Error;
226 end if;
228 if Source.Length = 0 then
229 Clear (Target);
230 return;
231 end if;
233 while Tgt /= null
234 and then Src /= null
235 loop
236 if Is_Less (Tgt, Src) then
237 declare
238 X : Node_Access := Tgt;
239 begin
240 Tgt := Tree_Operations.Next (Tgt);
241 Tree_Operations.Delete_Node_Sans_Free (Target, X);
242 Free (X);
243 end;
245 elsif Is_Less (Src, Tgt) then
246 Src := Tree_Operations.Next (Src);
248 else
249 Tgt := Tree_Operations.Next (Tgt);
250 Src := Tree_Operations.Next (Src);
251 end if;
252 end loop;
254 while Tgt /= null loop
255 declare
256 X : Node_Access := Tgt;
257 begin
258 Tgt := Tree_Operations.Next (Tgt);
259 Tree_Operations.Delete_Node_Sans_Free (Target, X);
260 Free (X);
261 end;
262 end loop;
263 end Intersection;
265 function Intersection (Left, Right : Tree_Type) return Tree_Type is
266 Tree : Tree_Type;
268 L_Node : Node_Access := Left.First;
269 R_Node : Node_Access := Right.First;
271 Dst_Node : Node_Access;
273 begin
274 if Left'Address = Right'Address then
275 return Copy (Left);
276 end if;
278 loop
279 if L_Node = null then
280 return Tree;
281 end if;
283 if R_Node = null then
284 return Tree;
285 end if;
287 if Is_Less (L_Node, R_Node) then
288 L_Node := Tree_Operations.Next (L_Node);
290 elsif Is_Less (R_Node, L_Node) then
291 R_Node := Tree_Operations.Next (R_Node);
293 else
294 Insert_With_Hint
295 (Dst_Tree => Tree,
296 Dst_Hint => null,
297 Src_Node => L_Node,
298 Dst_Node => Dst_Node);
300 L_Node := Tree_Operations.Next (L_Node);
301 R_Node := Tree_Operations.Next (R_Node);
302 end if;
303 end loop;
305 exception
306 when others =>
307 Delete_Tree (Tree.Root);
308 raise;
309 end Intersection;
311 ---------------
312 -- Is_Subset --
313 ---------------
315 function Is_Subset
316 (Subset : Tree_Type;
317 Of_Set : Tree_Type) return Boolean
319 begin
320 if Subset'Address = Of_Set'Address then
321 return True;
322 end if;
324 if Subset.Length > Of_Set.Length then
325 return False;
326 end if;
328 declare
329 Subset_Node : Node_Access := Subset.First;
330 Set_Node : Node_Access := Of_Set.First;
332 begin
333 loop
334 if Set_Node = null then
335 return Subset_Node = null;
336 end if;
338 if Subset_Node = null then
339 return True;
340 end if;
342 if Is_Less (Subset_Node, Set_Node) then
343 return False;
344 end if;
346 if Is_Less (Set_Node, Subset_Node) then
347 Set_Node := Tree_Operations.Next (Set_Node);
348 else
349 Set_Node := Tree_Operations.Next (Set_Node);
350 Subset_Node := Tree_Operations.Next (Subset_Node);
351 end if;
352 end loop;
353 end;
354 end Is_Subset;
356 -------------
357 -- Overlap --
358 -------------
360 function Overlap (Left, Right : Tree_Type) return Boolean is
361 L_Node : Node_Access := Left.First;
362 R_Node : Node_Access := Right.First;
364 begin
365 if Left'Address = Right'Address then
366 return Left.Length /= 0;
367 end if;
369 loop
370 if L_Node = null
371 or else R_Node = null
372 then
373 return False;
374 end if;
376 if Is_Less (L_Node, R_Node) then
377 L_Node := Tree_Operations.Next (L_Node);
379 elsif Is_Less (R_Node, L_Node) then
380 R_Node := Tree_Operations.Next (R_Node);
382 else
383 return True;
384 end if;
385 end loop;
386 end Overlap;
388 --------------------------
389 -- Symmetric_Difference --
390 --------------------------
392 procedure Symmetric_Difference
393 (Target : in out Tree_Type;
394 Source : Tree_Type)
396 Tgt : Node_Access := Target.First;
397 Src : Node_Access := Source.First;
399 New_Tgt_Node : Node_Access;
401 begin
402 if Target.Busy > 0 then
403 raise Program_Error;
404 end if;
406 if Target'Address = Source'Address then
407 Clear (Target);
408 return;
409 end if;
411 loop
412 if Tgt = null then
413 while Src /= null loop
414 Insert_With_Hint
415 (Dst_Tree => Target,
416 Dst_Hint => null,
417 Src_Node => Src,
418 Dst_Node => New_Tgt_Node);
420 Src := Tree_Operations.Next (Src);
421 end loop;
423 return;
424 end if;
426 if Src = null then
427 return;
428 end if;
430 if Is_Less (Tgt, Src) then
431 Tgt := Tree_Operations.Next (Tgt);
433 elsif Is_Less (Src, Tgt) then
434 Insert_With_Hint
435 (Dst_Tree => Target,
436 Dst_Hint => Tgt,
437 Src_Node => Src,
438 Dst_Node => New_Tgt_Node);
440 Src := Tree_Operations.Next (Src);
442 else
443 declare
444 X : Node_Access := Tgt;
445 begin
446 Tgt := Tree_Operations.Next (Tgt);
447 Tree_Operations.Delete_Node_Sans_Free (Target, X);
448 Free (X);
449 end;
451 Src := Tree_Operations.Next (Src);
452 end if;
453 end loop;
454 end Symmetric_Difference;
456 function Symmetric_Difference (Left, Right : Tree_Type) return Tree_Type is
457 Tree : Tree_Type;
459 L_Node : Node_Access := Left.First;
460 R_Node : Node_Access := Right.First;
462 Dst_Node : Node_Access;
464 begin
465 if Left'Address = Right'Address then
466 return Tree; -- Empty set
467 end if;
469 if Right.Length = 0 then
470 return Copy (Left);
471 end if;
473 if Left.Length = 0 then
474 return Copy (Right);
475 end if;
477 loop
478 if L_Node = null then
479 while R_Node /= null loop
480 Insert_With_Hint
481 (Dst_Tree => Tree,
482 Dst_Hint => null,
483 Src_Node => R_Node,
484 Dst_Node => Dst_Node);
485 R_Node := Tree_Operations.Next (R_Node);
486 end loop;
488 return Tree;
489 end if;
491 if R_Node = null then
492 while L_Node /= null loop
493 Insert_With_Hint
494 (Dst_Tree => Tree,
495 Dst_Hint => null,
496 Src_Node => L_Node,
497 Dst_Node => Dst_Node);
499 L_Node := Tree_Operations.Next (L_Node);
500 end loop;
502 return Tree;
503 end if;
505 if Is_Less (L_Node, R_Node) then
506 Insert_With_Hint
507 (Dst_Tree => Tree,
508 Dst_Hint => null,
509 Src_Node => L_Node,
510 Dst_Node => Dst_Node);
512 L_Node := Tree_Operations.Next (L_Node);
514 elsif Is_Less (R_Node, L_Node) then
515 Insert_With_Hint
516 (Dst_Tree => Tree,
517 Dst_Hint => null,
518 Src_Node => R_Node,
519 Dst_Node => Dst_Node);
521 R_Node := Tree_Operations.Next (R_Node);
523 else
524 L_Node := Tree_Operations.Next (L_Node);
525 R_Node := Tree_Operations.Next (R_Node);
526 end if;
527 end loop;
529 exception
530 when others =>
531 Delete_Tree (Tree.Root);
532 raise;
533 end Symmetric_Difference;
535 -----------
536 -- Union --
537 -----------
539 procedure Union (Target : in out Tree_Type; Source : Tree_Type)
541 Hint : Node_Access;
543 procedure Process (Node : Node_Access);
544 pragma Inline (Process);
546 procedure Iterate is new Tree_Operations.Generic_Iteration (Process);
548 -------------
549 -- Process --
550 -------------
552 procedure Process (Node : Node_Access) is
553 begin
554 Insert_With_Hint
555 (Dst_Tree => Target,
556 Dst_Hint => Hint,
557 Src_Node => Node,
558 Dst_Node => Hint);
559 end Process;
561 -- Start of processing for Union
563 begin
564 if Target'Address = Source'Address then
565 return;
566 end if;
568 if Target.Busy > 0 then
569 raise Program_Error;
570 end if;
572 Iterate (Source);
573 end Union;
575 function Union (Left, Right : Tree_Type) return Tree_Type is
576 begin
577 if Left'Address = Right'Address then
578 return Copy (Left);
579 end if;
581 if Left.Length = 0 then
582 return Copy (Right);
583 end if;
585 if Right.Length = 0 then
586 return Copy (Left);
587 end if;
589 declare
590 Tree : Tree_Type := Copy (Left);
592 Hint : Node_Access;
594 procedure Process (Node : Node_Access);
595 pragma Inline (Process);
597 procedure Iterate is
598 new Tree_Operations.Generic_Iteration (Process);
600 -------------
601 -- Process --
602 -------------
604 procedure Process (Node : Node_Access) is
605 begin
606 Insert_With_Hint
607 (Dst_Tree => Tree,
608 Dst_Hint => Hint,
609 Src_Node => Node,
610 Dst_Node => Hint);
611 end Process;
613 -- Start of processing for Union
615 begin
616 Iterate (Right);
617 return Tree;
619 exception
620 when others =>
621 Delete_Tree (Tree.Root);
622 raise;
623 end;
625 end Union;
627 end Ada.Containers.Red_Black_Trees.Generic_Set_Operations;