[PATCH 03/11] Handle typedefs for CodeView
[official-gcc.git] / gcc / ada / libgnat / a-rbtgso.adb
blob5329466ca6b604bdbd569444d3c8cb196cd6ab2b
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_SET_OPERATIONS --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004-2024, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- This unit was originally developed by Matthew J Heaney. --
28 ------------------------------------------------------------------------------
30 with System; use type System.Address;
32 package body Ada.Containers.Red_Black_Trees.Generic_Set_Operations is
34 pragma Warnings (Off, "variable ""Busy*"" is not referenced");
35 pragma Warnings (Off, "variable ""Lock*"" is not referenced");
36 -- See comment in Ada.Containers.Helpers
38 -----------------------
39 -- Local Subprograms --
40 -----------------------
42 procedure Clear (Tree : in out Tree_Type);
44 function Copy (Source : Tree_Type) return Tree_Type;
46 -----------
47 -- Clear --
48 -----------
50 procedure Clear (Tree : in out Tree_Type) is
51 use type Helpers.Tamper_Counts;
52 pragma Assert (Tree.TC = (Busy => 0, Lock => 0));
54 Root : Node_Access := Tree.Root;
55 pragma Warnings (Off, Root);
57 begin
58 Tree.Root := null;
59 Tree.First := null;
60 Tree.Last := null;
61 Tree.Length := 0;
63 Delete_Tree (Root);
64 end Clear;
66 ----------
67 -- Copy --
68 ----------
70 function Copy (Source : Tree_Type) return Tree_Type is
71 Target : Tree_Type;
73 begin
74 if Source.Length = 0 then
75 return Target;
76 end if;
78 Target.Root := Copy_Tree (Source.Root);
79 Target.First := Tree_Operations.Min (Target.Root);
80 Target.Last := Tree_Operations.Max (Target.Root);
81 Target.Length := Source.Length;
83 return Target;
84 end Copy;
86 ----------------
87 -- Difference --
88 ----------------
90 procedure Difference (Target : in out Tree_Type; Source : Tree_Type) is
91 Tgt : Node_Access;
92 Src : Node_Access;
94 Compare : Integer;
96 begin
97 TC_Check (Target.TC);
99 if Target'Address = Source'Address then
100 Clear (Target);
101 return;
102 end if;
104 if Source.Length = 0 then
105 return;
106 end if;
108 Tgt := Target.First;
109 Src := Source.First;
110 loop
111 if Tgt = null then
112 exit;
113 end if;
115 if Src = null then
116 exit;
117 end if;
119 -- Per AI05-0022, the container implementation is required to detect
120 -- element tampering by a generic actual subprogram.
122 declare
123 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
124 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
125 begin
126 if Is_Less (Tgt, Src) then
127 Compare := -1;
128 elsif Is_Less (Src, Tgt) then
129 Compare := 1;
130 else
131 Compare := 0;
132 end if;
133 end;
135 if Compare < 0 then
136 Tgt := Tree_Operations.Next (Tgt);
138 elsif Compare > 0 then
139 Src := Tree_Operations.Next (Src);
141 else
142 declare
143 X : Node_Access := Tgt;
144 begin
145 Tgt := Tree_Operations.Next (Tgt);
146 Tree_Operations.Delete_Node_Sans_Free (Target, X);
147 Free (X);
148 end;
150 Src := Tree_Operations.Next (Src);
151 end if;
152 end loop;
153 end Difference;
155 function Difference (Left, Right : Tree_Type) return Tree_Type is
156 begin
157 if Left'Address = Right'Address then
158 return Tree_Type'(others => <>); -- Empty set
159 end if;
161 if Left.Length = 0 then
162 return Tree_Type'(others => <>); -- Empty set
163 end if;
165 if Right.Length = 0 then
166 return Copy (Left);
167 end if;
169 -- Per AI05-0022, the container implementation is required to detect
170 -- element tampering by a generic actual subprogram.
172 declare
173 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
174 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
176 Tree : Tree_Type;
178 L_Node : Node_Access;
179 R_Node : Node_Access;
181 Dst_Node : Node_Access;
182 pragma Warnings (Off, Dst_Node);
184 begin
185 L_Node := Left.First;
186 R_Node := Right.First;
187 loop
188 if L_Node = null then
189 exit;
190 end if;
192 if R_Node = null then
193 while L_Node /= null loop
194 Insert_With_Hint
195 (Dst_Tree => Tree,
196 Dst_Hint => null,
197 Src_Node => L_Node,
198 Dst_Node => Dst_Node);
200 L_Node := Tree_Operations.Next (L_Node);
201 end loop;
203 exit;
204 end if;
206 if Is_Less (L_Node, R_Node) then
207 Insert_With_Hint
208 (Dst_Tree => Tree,
209 Dst_Hint => null,
210 Src_Node => L_Node,
211 Dst_Node => Dst_Node);
213 L_Node := Tree_Operations.Next (L_Node);
215 elsif Is_Less (R_Node, L_Node) then
216 R_Node := Tree_Operations.Next (R_Node);
218 else
219 L_Node := Tree_Operations.Next (L_Node);
220 R_Node := Tree_Operations.Next (R_Node);
221 end if;
222 end loop;
224 return Tree;
226 exception
227 when others =>
228 Delete_Tree (Tree.Root);
229 raise;
230 end;
231 end Difference;
233 ------------------
234 -- Intersection --
235 ------------------
237 procedure Intersection
238 (Target : in out Tree_Type;
239 Source : Tree_Type)
241 Tgt : Node_Access;
242 Src : Node_Access;
244 Compare : Integer;
246 begin
247 if Target'Address = Source'Address then
248 return;
249 end if;
251 TC_Check (Target.TC);
253 if Source.Length = 0 then
254 Clear (Target);
255 return;
256 end if;
258 Tgt := Target.First;
259 Src := Source.First;
260 while Tgt /= null
261 and then Src /= null
262 loop
263 -- Per AI05-0022, the container implementation is required to detect
264 -- element tampering by a generic actual subprogram.
266 declare
267 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
268 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
269 begin
270 if Is_Less (Tgt, Src) then
271 Compare := -1;
272 elsif Is_Less (Src, Tgt) then
273 Compare := 1;
274 else
275 Compare := 0;
276 end if;
277 end;
279 if Compare < 0 then
280 declare
281 X : Node_Access := Tgt;
282 begin
283 Tgt := Tree_Operations.Next (Tgt);
284 Tree_Operations.Delete_Node_Sans_Free (Target, X);
285 Free (X);
286 end;
288 elsif Compare > 0 then
289 Src := Tree_Operations.Next (Src);
291 else
292 Tgt := Tree_Operations.Next (Tgt);
293 Src := Tree_Operations.Next (Src);
294 end if;
295 end loop;
297 while Tgt /= null loop
298 declare
299 X : Node_Access := Tgt;
300 begin
301 Tgt := Tree_Operations.Next (Tgt);
302 Tree_Operations.Delete_Node_Sans_Free (Target, X);
303 Free (X);
304 end;
305 end loop;
306 end Intersection;
308 function Intersection (Left, Right : Tree_Type) return Tree_Type is
309 begin
310 if Left'Address = Right'Address then
311 return Copy (Left);
312 end if;
314 -- Per AI05-0022, the container implementation is required to detect
315 -- element tampering by a generic actual subprogram.
317 declare
318 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
319 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
321 Tree : Tree_Type;
323 L_Node : Node_Access;
324 R_Node : Node_Access;
326 Dst_Node : Node_Access;
327 pragma Warnings (Off, Dst_Node);
329 begin
330 L_Node := Left.First;
331 R_Node := Right.First;
332 loop
333 if L_Node = null then
334 exit;
335 end if;
337 if R_Node = null then
338 exit;
339 end if;
341 if Is_Less (L_Node, R_Node) then
342 L_Node := Tree_Operations.Next (L_Node);
344 elsif Is_Less (R_Node, L_Node) then
345 R_Node := Tree_Operations.Next (R_Node);
347 else
348 Insert_With_Hint
349 (Dst_Tree => Tree,
350 Dst_Hint => null,
351 Src_Node => L_Node,
352 Dst_Node => Dst_Node);
354 L_Node := Tree_Operations.Next (L_Node);
355 R_Node := Tree_Operations.Next (R_Node);
356 end if;
357 end loop;
359 return Tree;
361 exception
362 when others =>
363 Delete_Tree (Tree.Root);
364 raise;
365 end;
366 end Intersection;
368 ---------------
369 -- Is_Subset --
370 ---------------
372 function Is_Subset
373 (Subset : Tree_Type;
374 Of_Set : Tree_Type) return Boolean
376 begin
377 if Subset'Address = Of_Set'Address then
378 return True;
379 end if;
381 if Subset.Length > Of_Set.Length then
382 return False;
383 end if;
385 -- Per AI05-0022, the container implementation is required to detect
386 -- element tampering by a generic actual subprogram.
388 declare
389 Lock_Subset : With_Lock (Subset.TC'Unrestricted_Access);
390 Lock_Of_Set : With_Lock (Of_Set.TC'Unrestricted_Access);
392 Subset_Node : Node_Access;
393 Set_Node : Node_Access;
395 begin
396 Subset_Node := Subset.First;
397 Set_Node := Of_Set.First;
398 loop
399 if Set_Node = null then
400 return Subset_Node = null;
401 end if;
403 if Subset_Node = null then
404 return True;
405 end if;
407 if Is_Less (Subset_Node, Set_Node) then
408 return False;
409 end if;
411 if Is_Less (Set_Node, Subset_Node) then
412 Set_Node := Tree_Operations.Next (Set_Node);
413 else
414 Set_Node := Tree_Operations.Next (Set_Node);
415 Subset_Node := Tree_Operations.Next (Subset_Node);
416 end if;
417 end loop;
418 end;
419 end Is_Subset;
421 -------------
422 -- Overlap --
423 -------------
425 function Overlap (Left, Right : Tree_Type) return Boolean is
426 begin
427 if Left'Address = Right'Address then
428 return Left.Length /= 0;
429 end if;
431 -- Per AI05-0022, the container implementation is required to detect
432 -- element tampering by a generic actual subprogram.
434 declare
435 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
436 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
438 L_Node : Node_Access;
439 R_Node : Node_Access;
440 begin
441 L_Node := Left.First;
442 R_Node := Right.First;
443 loop
444 if L_Node = null
445 or else R_Node = null
446 then
447 return False;
448 end if;
450 if Is_Less (L_Node, R_Node) then
451 L_Node := Tree_Operations.Next (L_Node);
453 elsif Is_Less (R_Node, L_Node) then
454 R_Node := Tree_Operations.Next (R_Node);
456 else
457 return True;
458 end if;
459 end loop;
460 end;
461 end Overlap;
463 --------------------------
464 -- Symmetric_Difference --
465 --------------------------
467 procedure Symmetric_Difference
468 (Target : in out Tree_Type;
469 Source : Tree_Type)
471 Tgt : Node_Access;
472 Src : Node_Access;
474 New_Tgt_Node : Node_Access;
475 pragma Warnings (Off, New_Tgt_Node);
477 Compare : Integer;
479 begin
480 if Target'Address = Source'Address then
481 Clear (Target);
482 return;
483 end if;
485 Tgt := Target.First;
486 Src := Source.First;
487 loop
488 if Tgt = null then
489 while Src /= null loop
490 Insert_With_Hint
491 (Dst_Tree => Target,
492 Dst_Hint => null,
493 Src_Node => Src,
494 Dst_Node => New_Tgt_Node);
496 Src := Tree_Operations.Next (Src);
497 end loop;
499 return;
500 end if;
502 if Src = null then
503 return;
504 end if;
506 -- Per AI05-0022, the container implementation is required to detect
507 -- element tampering by a generic actual subprogram.
509 declare
510 Lock_Target : With_Lock (Target.TC'Unrestricted_Access);
511 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
512 begin
513 if Is_Less (Tgt, Src) then
514 Compare := -1;
515 elsif Is_Less (Src, Tgt) then
516 Compare := 1;
517 else
518 Compare := 0;
519 end if;
520 end;
522 if Compare < 0 then
523 Tgt := Tree_Operations.Next (Tgt);
525 elsif Compare > 0 then
526 Insert_With_Hint
527 (Dst_Tree => Target,
528 Dst_Hint => Tgt,
529 Src_Node => Src,
530 Dst_Node => New_Tgt_Node);
532 Src := Tree_Operations.Next (Src);
534 else
535 declare
536 X : Node_Access := Tgt;
537 begin
538 Tgt := Tree_Operations.Next (Tgt);
539 Tree_Operations.Delete_Node_Sans_Free (Target, X);
540 Free (X);
541 end;
543 Src := Tree_Operations.Next (Src);
544 end if;
545 end loop;
546 end Symmetric_Difference;
548 function Symmetric_Difference (Left, Right : Tree_Type) return Tree_Type is
549 begin
550 if Left'Address = Right'Address then
551 return Tree_Type'(others => <>); -- Empty set
552 end if;
554 if Right.Length = 0 then
555 return Copy (Left);
556 end if;
558 if Left.Length = 0 then
559 return Copy (Right);
560 end if;
562 -- Per AI05-0022, the container implementation is required to detect
563 -- element tampering by a generic actual subprogram.
565 declare
566 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
567 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
569 Tree : Tree_Type;
571 L_Node : Node_Access;
572 R_Node : Node_Access;
574 Dst_Node : Node_Access;
575 pragma Warnings (Off, Dst_Node);
577 begin
578 L_Node := Left.First;
579 R_Node := Right.First;
580 loop
581 if L_Node = null then
582 while R_Node /= null loop
583 Insert_With_Hint
584 (Dst_Tree => Tree,
585 Dst_Hint => null,
586 Src_Node => R_Node,
587 Dst_Node => Dst_Node);
588 R_Node := Tree_Operations.Next (R_Node);
589 end loop;
591 exit;
592 end if;
594 if R_Node = null then
595 while L_Node /= null loop
596 Insert_With_Hint
597 (Dst_Tree => Tree,
598 Dst_Hint => null,
599 Src_Node => L_Node,
600 Dst_Node => Dst_Node);
602 L_Node := Tree_Operations.Next (L_Node);
603 end loop;
605 exit;
606 end if;
608 if Is_Less (L_Node, R_Node) then
609 Insert_With_Hint
610 (Dst_Tree => Tree,
611 Dst_Hint => null,
612 Src_Node => L_Node,
613 Dst_Node => Dst_Node);
615 L_Node := Tree_Operations.Next (L_Node);
617 elsif Is_Less (R_Node, L_Node) then
618 Insert_With_Hint
619 (Dst_Tree => Tree,
620 Dst_Hint => null,
621 Src_Node => R_Node,
622 Dst_Node => Dst_Node);
624 R_Node := Tree_Operations.Next (R_Node);
626 else
627 L_Node := Tree_Operations.Next (L_Node);
628 R_Node := Tree_Operations.Next (R_Node);
629 end if;
630 end loop;
632 return Tree;
634 exception
635 when others =>
636 Delete_Tree (Tree.Root);
637 raise;
638 end;
639 end Symmetric_Difference;
641 -----------
642 -- Union --
643 -----------
645 procedure Union (Target : in out Tree_Type; Source : Tree_Type) is
646 Hint : Node_Access;
648 procedure Process (Node : Node_Access);
649 pragma Inline (Process);
651 procedure Iterate is new Tree_Operations.Generic_Iteration (Process);
653 -------------
654 -- Process --
655 -------------
657 procedure Process (Node : Node_Access) is
658 begin
659 Insert_With_Hint
660 (Dst_Tree => Target,
661 Dst_Hint => Hint, -- use node most recently inserted as hint
662 Src_Node => Node,
663 Dst_Node => Hint);
664 end Process;
666 -- Start of processing for Union
668 begin
669 if Target'Address = Source'Address then
670 return;
671 end if;
673 -- Per AI05-0022, the container implementation is required to detect
674 -- element tampering by a generic actual subprogram.
676 declare
677 Lock_Source : With_Lock (Source.TC'Unrestricted_Access);
678 begin
679 Iterate (Source);
680 end;
681 end Union;
683 function Union (Left, Right : Tree_Type) return Tree_Type is
684 begin
685 if Left'Address = Right'Address then
686 return Copy (Left);
687 end if;
689 if Left.Length = 0 then
690 return Copy (Right);
691 end if;
693 if Right.Length = 0 then
694 return Copy (Left);
695 end if;
697 declare
698 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
699 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
701 Tree : Tree_Type := Copy (Left);
703 Hint : Node_Access;
705 procedure Process (Node : Node_Access);
706 pragma Inline (Process);
708 procedure Iterate is
709 new Tree_Operations.Generic_Iteration (Process);
711 -------------
712 -- Process --
713 -------------
715 procedure Process (Node : Node_Access) is
716 begin
717 Insert_With_Hint
718 (Dst_Tree => Tree,
719 Dst_Hint => Hint, -- use node most recently inserted as hint
720 Src_Node => Node,
721 Dst_Node => Hint);
722 end Process;
724 -- Start of processing for Union
726 begin
727 Iterate (Right);
728 return Tree;
730 exception
731 when others =>
732 Delete_Tree (Tree.Root);
733 raise;
734 end;
735 end Union;
737 end Ada.Containers.Red_Black_Trees.Generic_Set_Operations;