* libgfortran.h (support_fpu_underflow_control,
[official-gcc.git] / gcc / ada / a-btgbso.adb
blob2aef270f64d08bee9e40f03a605ee3f17aa5f0c6
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_BOUNDED_SET_OPERATIONS --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004-2013, 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_Bounded_Set_Operations is
34 -----------------------
35 -- Local Subprograms --
36 -----------------------
38 function Copy (Source : Set_Type) return Set_Type;
40 ----------
41 -- Copy --
42 ----------
44 function Copy (Source : Set_Type) return Set_Type is
45 begin
46 return Target : Set_Type (Source.Length) do
47 Assign (Target => Target, Source => Source);
48 end return;
49 end Copy;
51 ----------------
52 -- Difference --
53 ----------------
55 procedure Set_Difference (Target : in out Set_Type; Source : Set_Type) is
56 BT : Natural renames Target.Busy;
57 LT : Natural renames Target.Lock;
59 BS : Natural renames Source'Unrestricted_Access.Busy;
60 LS : Natural renames Source'Unrestricted_Access.Lock;
62 Tgt, Src : Count_Type;
64 TN : Nodes_Type renames Target.Nodes;
65 SN : Nodes_Type renames Source.Nodes;
67 Compare : Integer;
69 begin
70 if Target'Address = Source'Address then
71 if Target.Busy > 0 then
72 raise Program_Error with
73 "attempt to tamper with cursors (container is busy)";
74 end if;
76 Tree_Operations.Clear_Tree (Target);
77 return;
78 end if;
80 if Source.Length = 0 then
81 return;
82 end if;
84 if Target.Busy > 0 then
85 raise Program_Error with
86 "attempt to tamper with cursors (container is busy)";
87 end if;
89 Tgt := Target.First;
90 Src := Source.First;
91 loop
92 if Tgt = 0 then
93 exit;
94 end if;
96 if Src = 0 then
97 exit;
98 end if;
100 -- Per AI05-0022, the container implementation is required to detect
101 -- element tampering by a generic actual subprogram.
103 begin
104 BT := BT + 1;
105 LT := LT + 1;
107 BS := BS + 1;
108 LS := LS + 1;
110 if Is_Less (TN (Tgt), SN (Src)) then
111 Compare := -1;
112 elsif Is_Less (SN (Src), TN (Tgt)) then
113 Compare := 1;
114 else
115 Compare := 0;
116 end if;
118 BT := BT - 1;
119 LT := LT - 1;
121 BS := BS - 1;
122 LS := LS - 1;
123 exception
124 when others =>
125 BT := BT - 1;
126 LT := LT - 1;
128 BS := BS - 1;
129 LS := LS - 1;
131 raise;
132 end;
134 if Compare < 0 then
135 Tgt := Tree_Operations.Next (Target, Tgt);
137 elsif Compare > 0 then
138 Src := Tree_Operations.Next (Source, Src);
140 else
141 declare
142 X : constant Count_Type := Tgt;
143 begin
144 Tgt := Tree_Operations.Next (Target, Tgt);
146 Tree_Operations.Delete_Node_Sans_Free (Target, X);
147 Tree_Operations.Free (Target, X);
148 end;
150 Src := Tree_Operations.Next (Source, Src);
151 end if;
152 end loop;
153 end Set_Difference;
155 function Set_Difference (Left, Right : Set_Type) return Set_Type is
156 begin
157 if Left'Address = Right'Address then
158 return S : Set_Type (0); -- Empty set
159 end if;
161 if Left.Length = 0 then
162 return S : Set_Type (0); -- Empty set
163 end if;
165 if Right.Length = 0 then
166 return Copy (Left);
167 end if;
169 return Result : Set_Type (Left.Length) do
170 -- Per AI05-0022, the container implementation is required to detect
171 -- element tampering by a generic actual subprogram.
173 declare
174 BL : Natural renames Left'Unrestricted_Access.Busy;
175 LL : Natural renames Left'Unrestricted_Access.Lock;
177 BR : Natural renames Right'Unrestricted_Access.Busy;
178 LR : Natural renames Right'Unrestricted_Access.Lock;
180 L_Node : Count_Type;
181 R_Node : Count_Type;
183 Dst_Node : Count_Type;
184 pragma Warnings (Off, Dst_Node);
186 begin
187 BL := BL + 1;
188 LL := LL + 1;
190 BR := BR + 1;
191 LR := LR + 1;
193 L_Node := Left.First;
194 R_Node := Right.First;
195 loop
196 if L_Node = 0 then
197 exit;
198 end if;
200 if R_Node = 0 then
201 while L_Node /= 0 loop
202 Insert_With_Hint
203 (Dst_Set => Result,
204 Dst_Hint => 0,
205 Src_Node => Left.Nodes (L_Node),
206 Dst_Node => Dst_Node);
208 L_Node := Tree_Operations.Next (Left, L_Node);
209 end loop;
211 exit;
212 end if;
214 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
215 Insert_With_Hint
216 (Dst_Set => Result,
217 Dst_Hint => 0,
218 Src_Node => Left.Nodes (L_Node),
219 Dst_Node => Dst_Node);
221 L_Node := Tree_Operations.Next (Left, L_Node);
223 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
224 R_Node := Tree_Operations.Next (Right, R_Node);
226 else
227 L_Node := Tree_Operations.Next (Left, L_Node);
228 R_Node := Tree_Operations.Next (Right, R_Node);
229 end if;
230 end loop;
232 BL := BL - 1;
233 LL := LL - 1;
235 BR := BR - 1;
236 LR := LR - 1;
237 exception
238 when others =>
239 BL := BL - 1;
240 LL := LL - 1;
242 BR := BR - 1;
243 LR := LR - 1;
245 raise;
246 end;
247 end return;
248 end Set_Difference;
250 ------------------
251 -- Intersection --
252 ------------------
254 procedure Set_Intersection
255 (Target : in out Set_Type;
256 Source : Set_Type)
258 BT : Natural renames Target.Busy;
259 LT : Natural renames Target.Lock;
261 BS : Natural renames Source'Unrestricted_Access.Busy;
262 LS : Natural renames Source'Unrestricted_Access.Lock;
264 Tgt : Count_Type;
265 Src : Count_Type;
267 Compare : Integer;
269 begin
270 if Target'Address = Source'Address then
271 return;
272 end if;
274 if Target.Busy > 0 then
275 raise Program_Error with
276 "attempt to tamper with cursors (container is busy)";
277 end if;
279 if Source.Length = 0 then
280 Tree_Operations.Clear_Tree (Target);
281 return;
282 end if;
284 Tgt := Target.First;
285 Src := Source.First;
286 while Tgt /= 0
287 and then Src /= 0
288 loop
289 -- Per AI05-0022, the container implementation is required to detect
290 -- element tampering by a generic actual subprogram.
292 begin
293 BT := BT + 1;
294 LT := LT + 1;
296 BS := BS + 1;
297 LS := LS + 1;
299 if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
300 Compare := -1;
301 elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
302 Compare := 1;
303 else
304 Compare := 0;
305 end if;
307 BT := BT - 1;
308 LT := LT - 1;
310 BS := BS - 1;
311 LS := LS - 1;
312 exception
313 when others =>
314 BT := BT - 1;
315 LT := LT - 1;
317 BS := BS - 1;
318 LS := LS - 1;
320 raise;
321 end;
323 if Compare < 0 then
324 declare
325 X : constant Count_Type := Tgt;
326 begin
327 Tgt := Tree_Operations.Next (Target, Tgt);
329 Tree_Operations.Delete_Node_Sans_Free (Target, X);
330 Tree_Operations.Free (Target, X);
331 end;
333 elsif Compare > 0 then
334 Src := Tree_Operations.Next (Source, Src);
336 else
337 Tgt := Tree_Operations.Next (Target, Tgt);
338 Src := Tree_Operations.Next (Source, Src);
339 end if;
340 end loop;
342 while Tgt /= 0 loop
343 declare
344 X : constant Count_Type := Tgt;
345 begin
346 Tgt := Tree_Operations.Next (Target, Tgt);
348 Tree_Operations.Delete_Node_Sans_Free (Target, X);
349 Tree_Operations.Free (Target, X);
350 end;
351 end loop;
352 end Set_Intersection;
354 function Set_Intersection (Left, Right : Set_Type) return Set_Type is
355 begin
356 if Left'Address = Right'Address then
357 return Copy (Left);
358 end if;
360 return Result : Set_Type (Count_Type'Min (Left.Length, Right.Length)) do
362 -- Per AI05-0022, the container implementation is required to detect
363 -- element tampering by a generic actual subprogram.
365 declare
366 BL : Natural renames Left'Unrestricted_Access.Busy;
367 LL : Natural renames Left'Unrestricted_Access.Lock;
369 BR : Natural renames Right'Unrestricted_Access.Busy;
370 LR : Natural renames Right'Unrestricted_Access.Lock;
372 L_Node : Count_Type;
373 R_Node : Count_Type;
375 Dst_Node : Count_Type;
376 pragma Warnings (Off, Dst_Node);
378 begin
379 BL := BL + 1;
380 LL := LL + 1;
382 BR := BR + 1;
383 LR := LR + 1;
385 L_Node := Left.First;
386 R_Node := Right.First;
387 loop
388 if L_Node = 0 then
389 exit;
390 end if;
392 if R_Node = 0 then
393 exit;
394 end if;
396 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
397 L_Node := Tree_Operations.Next (Left, L_Node);
399 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
400 R_Node := Tree_Operations.Next (Right, R_Node);
402 else
403 Insert_With_Hint
404 (Dst_Set => Result,
405 Dst_Hint => 0,
406 Src_Node => Left.Nodes (L_Node),
407 Dst_Node => Dst_Node);
409 L_Node := Tree_Operations.Next (Left, L_Node);
410 R_Node := Tree_Operations.Next (Right, R_Node);
411 end if;
412 end loop;
414 BL := BL - 1;
415 LL := LL - 1;
417 BR := BR - 1;
418 LR := LR - 1;
419 exception
420 when others =>
421 BL := BL - 1;
422 LL := LL - 1;
424 BR := BR - 1;
425 LR := LR - 1;
427 raise;
428 end;
429 end return;
430 end Set_Intersection;
432 ---------------
433 -- Is_Subset --
434 ---------------
436 function Set_Subset
437 (Subset : Set_Type;
438 Of_Set : Set_Type) return Boolean
440 begin
441 if Subset'Address = Of_Set'Address then
442 return True;
443 end if;
445 if Subset.Length > Of_Set.Length then
446 return False;
447 end if;
449 -- Per AI05-0022, the container implementation is required to detect
450 -- element tampering by a generic actual subprogram.
452 declare
453 BL : Natural renames Subset'Unrestricted_Access.Busy;
454 LL : Natural renames Subset'Unrestricted_Access.Lock;
456 BR : Natural renames Of_Set'Unrestricted_Access.Busy;
457 LR : Natural renames Of_Set'Unrestricted_Access.Lock;
459 Subset_Node : Count_Type;
460 Set_Node : Count_Type;
462 Result : Boolean;
464 begin
465 BL := BL + 1;
466 LL := LL + 1;
468 BR := BR + 1;
469 LR := LR + 1;
471 Subset_Node := Subset.First;
472 Set_Node := Of_Set.First;
473 loop
474 if Set_Node = 0 then
475 Result := Subset_Node = 0;
476 exit;
477 end if;
479 if Subset_Node = 0 then
480 Result := True;
481 exit;
482 end if;
484 if Is_Less (Subset.Nodes (Subset_Node),
485 Of_Set.Nodes (Set_Node))
486 then
487 Result := False;
488 exit;
489 end if;
491 if Is_Less (Of_Set.Nodes (Set_Node),
492 Subset.Nodes (Subset_Node))
493 then
494 Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
495 else
496 Set_Node := Tree_Operations.Next (Of_Set, Set_Node);
497 Subset_Node := Tree_Operations.Next (Subset, Subset_Node);
498 end if;
499 end loop;
501 BL := BL - 1;
502 LL := LL - 1;
504 BR := BR - 1;
505 LR := LR - 1;
507 return Result;
508 exception
509 when others =>
510 BL := BL - 1;
511 LL := LL - 1;
513 BR := BR - 1;
514 LR := LR - 1;
516 raise;
517 end;
518 end Set_Subset;
520 -------------
521 -- Overlap --
522 -------------
524 function Set_Overlap (Left, Right : Set_Type) return Boolean is
525 begin
526 if Left'Address = Right'Address then
527 return Left.Length /= 0;
528 end if;
530 -- Per AI05-0022, the container implementation is required to detect
531 -- element tampering by a generic actual subprogram.
533 declare
534 BL : Natural renames Left'Unrestricted_Access.Busy;
535 LL : Natural renames Left'Unrestricted_Access.Lock;
537 BR : Natural renames Right'Unrestricted_Access.Busy;
538 LR : Natural renames Right'Unrestricted_Access.Lock;
540 L_Node : Count_Type;
541 R_Node : Count_Type;
543 Result : Boolean;
545 begin
546 BL := BL + 1;
547 LL := LL + 1;
549 BR := BR + 1;
550 LR := LR + 1;
552 L_Node := Left.First;
553 R_Node := Right.First;
554 loop
555 if L_Node = 0
556 or else R_Node = 0
557 then
558 Result := False;
559 exit;
560 end if;
562 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
563 L_Node := Tree_Operations.Next (Left, L_Node);
565 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
566 R_Node := Tree_Operations.Next (Right, R_Node);
568 else
569 Result := True;
570 exit;
571 end if;
572 end loop;
574 BL := BL - 1;
575 LL := LL - 1;
577 BR := BR - 1;
578 LR := LR - 1;
580 return Result;
581 exception
582 when others =>
583 BL := BL - 1;
584 LL := LL - 1;
586 BR := BR - 1;
587 LR := LR - 1;
589 raise;
590 end;
591 end Set_Overlap;
593 --------------------------
594 -- Symmetric_Difference --
595 --------------------------
597 procedure Set_Symmetric_Difference
598 (Target : in out Set_Type;
599 Source : Set_Type)
601 BT : Natural renames Target.Busy;
602 LT : Natural renames Target.Lock;
604 BS : Natural renames Source'Unrestricted_Access.Busy;
605 LS : Natural renames Source'Unrestricted_Access.Lock;
607 Tgt : Count_Type;
608 Src : Count_Type;
610 New_Tgt_Node : Count_Type;
611 pragma Warnings (Off, New_Tgt_Node);
613 Compare : Integer;
615 begin
616 if Target'Address = Source'Address then
617 Tree_Operations.Clear_Tree (Target);
618 return;
619 end if;
621 Tgt := Target.First;
622 Src := Source.First;
623 loop
624 if Tgt = 0 then
625 while Src /= 0 loop
626 Insert_With_Hint
627 (Dst_Set => Target,
628 Dst_Hint => 0,
629 Src_Node => Source.Nodes (Src),
630 Dst_Node => New_Tgt_Node);
632 Src := Tree_Operations.Next (Source, Src);
633 end loop;
635 return;
636 end if;
638 if Src = 0 then
639 return;
640 end if;
642 -- Per AI05-0022, the container implementation is required to detect
643 -- element tampering by a generic actual subprogram.
645 begin
646 BT := BT + 1;
647 LT := LT + 1;
649 BS := BS + 1;
650 LS := LS + 1;
652 if Is_Less (Target.Nodes (Tgt), Source.Nodes (Src)) then
653 Compare := -1;
654 elsif Is_Less (Source.Nodes (Src), Target.Nodes (Tgt)) then
655 Compare := 1;
656 else
657 Compare := 0;
658 end if;
660 BT := BT - 1;
661 LT := LT - 1;
663 BS := BS - 1;
664 LS := LS - 1;
665 exception
666 when others =>
667 BT := BT - 1;
668 LT := LT - 1;
670 BS := BS - 1;
671 LS := LS - 1;
673 raise;
674 end;
676 if Compare < 0 then
677 Tgt := Tree_Operations.Next (Target, Tgt);
679 elsif Compare > 0 then
680 Insert_With_Hint
681 (Dst_Set => Target,
682 Dst_Hint => Tgt,
683 Src_Node => Source.Nodes (Src),
684 Dst_Node => New_Tgt_Node);
686 Src := Tree_Operations.Next (Source, Src);
688 else
689 declare
690 X : constant Count_Type := Tgt;
691 begin
692 Tgt := Tree_Operations.Next (Target, Tgt);
694 Tree_Operations.Delete_Node_Sans_Free (Target, X);
695 Tree_Operations.Free (Target, X);
696 end;
698 Src := Tree_Operations.Next (Source, Src);
699 end if;
700 end loop;
701 end Set_Symmetric_Difference;
703 function Set_Symmetric_Difference
704 (Left, Right : Set_Type) return Set_Type
706 begin
707 if Left'Address = Right'Address then
708 return S : Set_Type (0); -- Empty set
709 end if;
711 if Right.Length = 0 then
712 return Copy (Left);
713 end if;
715 if Left.Length = 0 then
716 return Copy (Right);
717 end if;
719 return Result : Set_Type (Left.Length + Right.Length) do
721 -- Per AI05-0022, the container implementation is required to detect
722 -- element tampering by a generic actual subprogram.
724 declare
725 BL : Natural renames Left'Unrestricted_Access.Busy;
726 LL : Natural renames Left'Unrestricted_Access.Lock;
728 BR : Natural renames Right'Unrestricted_Access.Busy;
729 LR : Natural renames Right'Unrestricted_Access.Lock;
731 L_Node : Count_Type;
732 R_Node : Count_Type;
734 Dst_Node : Count_Type;
735 pragma Warnings (Off, Dst_Node);
737 begin
738 BL := BL + 1;
739 LL := LL + 1;
741 BR := BR + 1;
742 LR := LR + 1;
744 L_Node := Left.First;
745 R_Node := Right.First;
746 loop
747 if L_Node = 0 then
748 while R_Node /= 0 loop
749 Insert_With_Hint
750 (Dst_Set => Result,
751 Dst_Hint => 0,
752 Src_Node => Right.Nodes (R_Node),
753 Dst_Node => Dst_Node);
755 R_Node := Tree_Operations.Next (Right, R_Node);
756 end loop;
758 exit;
759 end if;
761 if R_Node = 0 then
762 while L_Node /= 0 loop
763 Insert_With_Hint
764 (Dst_Set => Result,
765 Dst_Hint => 0,
766 Src_Node => Left.Nodes (L_Node),
767 Dst_Node => Dst_Node);
769 L_Node := Tree_Operations.Next (Left, L_Node);
770 end loop;
772 exit;
773 end if;
775 if Is_Less (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
776 Insert_With_Hint
777 (Dst_Set => Result,
778 Dst_Hint => 0,
779 Src_Node => Left.Nodes (L_Node),
780 Dst_Node => Dst_Node);
782 L_Node := Tree_Operations.Next (Left, L_Node);
784 elsif Is_Less (Right.Nodes (R_Node), Left.Nodes (L_Node)) then
785 Insert_With_Hint
786 (Dst_Set => Result,
787 Dst_Hint => 0,
788 Src_Node => Right.Nodes (R_Node),
789 Dst_Node => Dst_Node);
791 R_Node := Tree_Operations.Next (Right, R_Node);
793 else
794 L_Node := Tree_Operations.Next (Left, L_Node);
795 R_Node := Tree_Operations.Next (Right, R_Node);
796 end if;
797 end loop;
799 BL := BL - 1;
800 LL := LL - 1;
802 BR := BR - 1;
803 LR := LR - 1;
804 exception
805 when others =>
806 BL := BL - 1;
807 LL := LL - 1;
809 BR := BR - 1;
810 LR := LR - 1;
812 raise;
813 end;
814 end return;
815 end Set_Symmetric_Difference;
817 -----------
818 -- Union --
819 -----------
821 procedure Set_Union (Target : in out Set_Type; Source : Set_Type) is
822 Hint : Count_Type := 0;
824 procedure Process (Node : Count_Type);
825 pragma Inline (Process);
827 procedure Iterate is new Tree_Operations.Generic_Iteration (Process);
829 -------------
830 -- Process --
831 -------------
833 procedure Process (Node : Count_Type) is
834 begin
835 Insert_With_Hint
836 (Dst_Set => Target,
837 Dst_Hint => Hint,
838 Src_Node => Source.Nodes (Node),
839 Dst_Node => Hint);
840 end Process;
842 -- Start of processing for Union
844 begin
845 if Target'Address = Source'Address then
846 return;
847 end if;
849 -- Per AI05-0022, the container implementation is required to detect
850 -- element tampering by a generic actual subprogram.
852 declare
853 BS : Natural renames Source'Unrestricted_Access.Busy;
854 LS : Natural renames Source'Unrestricted_Access.Lock;
856 begin
857 BS := BS + 1;
858 LS := LS + 1;
860 -- Note that there's no way to decide a priori whether the target has
861 -- enough capacity for the union with source. We cannot simply
862 -- compare the sum of the existing lengths to the capacity of the
863 -- target, because equivalent items from source are not included in
864 -- the union.
866 Iterate (Source);
868 BS := BS - 1;
869 LS := LS - 1;
870 exception
871 when others =>
872 BS := BS - 1;
873 LS := LS - 1;
875 raise;
876 end;
877 end Set_Union;
879 function Set_Union (Left, Right : Set_Type) return Set_Type is
880 begin
881 if Left'Address = Right'Address then
882 return Copy (Left);
883 end if;
885 if Left.Length = 0 then
886 return Copy (Right);
887 end if;
889 if Right.Length = 0 then
890 return Copy (Left);
891 end if;
893 return Result : Set_Type (Left.Length + Right.Length) do
894 declare
895 BL : Natural renames Left'Unrestricted_Access.Busy;
896 LL : Natural renames Left'Unrestricted_Access.Lock;
898 BR : Natural renames Right'Unrestricted_Access.Busy;
899 LR : Natural renames Right'Unrestricted_Access.Lock;
901 begin
902 BL := BL + 1;
903 LL := LL + 1;
905 BR := BR + 1;
906 LR := LR + 1;
908 Assign (Target => Result, Source => Left);
910 Insert_Right : declare
911 Hint : Count_Type := 0;
913 procedure Process (Node : Count_Type);
914 pragma Inline (Process);
916 procedure Iterate is
917 new Tree_Operations.Generic_Iteration (Process);
919 -------------
920 -- Process --
921 -------------
923 procedure Process (Node : Count_Type) is
924 begin
925 Insert_With_Hint
926 (Dst_Set => Result,
927 Dst_Hint => Hint,
928 Src_Node => Right.Nodes (Node),
929 Dst_Node => Hint);
930 end Process;
932 -- Start of processing for Insert_Right
934 begin
935 Iterate (Right);
936 end Insert_Right;
938 BL := BL - 1;
939 LL := LL - 1;
941 BR := BR - 1;
942 LR := LR - 1;
943 exception
944 when others =>
945 BL := BL - 1;
946 LL := LL - 1;
948 BR := BR - 1;
949 LR := LR - 1;
951 raise;
952 end;
953 end return;
954 end Set_Union;
956 end Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations;