* expr.c (gfc_copy_shape_excluding): Change && to ||.
[official-gcc.git] / gcc / ada / a-ciorse.adb
blob9cd5e14db36508784f87a62ee9777b66ef36f842
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- ADA.CONTAINERS.INDEFINITE_ORDERED_SETS --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004 Free Software Foundation, Inc. --
10 -- --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
14 -- --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 2, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
24 -- MA 02111-1307, USA. --
25 -- --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
32 -- --
33 -- This unit was originally developed by Matthew J Heaney. --
34 ------------------------------------------------------------------------------
36 with Ada.Containers.Red_Black_Trees.Generic_Operations;
37 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Operations);
39 with Ada.Containers.Red_Black_Trees.Generic_Keys;
40 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys);
42 with Ada.Containers.Red_Black_Trees.Generic_Set_Operations;
43 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Set_Operations);
45 with Ada.Unchecked_Deallocation;
47 with System; use type System.Address;
49 package body Ada.Containers.Indefinite_Ordered_Sets is
51 type Element_Access is access Element_Type;
53 use Red_Black_Trees;
55 type Node_Type is limited record
56 Parent : Node_Access;
57 Left : Node_Access;
58 Right : Node_Access;
59 Color : Red_Black_Trees.Color_Type := Red;
60 Element : Element_Access;
61 end record;
63 -----------------------
64 -- Local Subprograms --
65 -----------------------
67 function Color (Node : Node_Access) return Color_Type;
68 pragma Inline (Color);
70 function Copy_Node (Source : Node_Access) return Node_Access;
71 pragma Inline (Copy_Node);
73 function Copy_Tree (Source_Root : Node_Access) return Node_Access;
75 procedure Delete_Tree (X : in out Node_Access);
77 procedure Free (X : in out Node_Access);
79 procedure Insert_With_Hint
80 (Dst_Tree : in out Tree_Type;
81 Dst_Hint : Node_Access;
82 Src_Node : Node_Access;
83 Dst_Node : out Node_Access);
85 function Is_Greater_Element_Node
86 (Left : Element_Type;
87 Right : Node_Access) return Boolean;
88 pragma Inline (Is_Greater_Element_Node);
90 function Is_Less_Element_Node
91 (Left : Element_Type;
92 Right : Node_Access) return Boolean;
93 pragma Inline (Is_Less_Element_Node);
95 function Is_Less_Node_Node (L, R : Node_Access) return Boolean;
96 pragma Inline (Is_Less_Node_Node);
98 function Left (Node : Node_Access) return Node_Access;
99 pragma Inline (Left);
101 function Parent (Node : Node_Access) return Node_Access;
102 pragma Inline (Parent);
104 function Right (Node : Node_Access) return Node_Access;
105 pragma Inline (Right);
107 procedure Set_Color (Node : Node_Access; Color : Color_Type);
108 pragma Inline (Set_Color);
110 procedure Set_Left (Node : Node_Access; Left : Node_Access);
111 pragma Inline (Set_Left);
113 procedure Set_Parent (Node : Node_Access; Parent : Node_Access);
114 pragma Inline (Set_Parent);
116 procedure Set_Right (Node : Node_Access; Right : Node_Access);
117 pragma Inline (Set_Right);
119 --------------------------
120 -- Local Instantiations --
121 --------------------------
123 procedure Free_Element is
124 new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
126 package Tree_Operations is
127 new Red_Black_Trees.Generic_Operations
128 (Tree_Types => Tree_Types,
129 Null_Node => Node_Access'(null));
131 use Tree_Operations;
133 package Element_Keys is
134 new Red_Black_Trees.Generic_Keys
135 (Tree_Operations => Tree_Operations,
136 Key_Type => Element_Type,
137 Is_Less_Key_Node => Is_Less_Element_Node,
138 Is_Greater_Key_Node => Is_Greater_Element_Node);
140 package Set_Ops is
141 new Generic_Set_Operations
142 (Tree_Operations => Tree_Operations,
143 Insert_With_Hint => Insert_With_Hint,
144 Copy_Tree => Copy_Tree,
145 Delete_Tree => Delete_Tree,
146 Is_Less => Is_Less_Node_Node,
147 Free => Free);
149 ---------
150 -- "<" --
151 ---------
153 function "<" (Left, Right : Cursor) return Boolean is
154 begin
155 return Left.Node.Element.all < Right.Node.Element.all;
156 end "<";
158 function "<" (Left : Cursor; Right : Element_Type) return Boolean is
159 begin
160 return Left.Node.Element.all < Right;
161 end "<";
163 function "<" (Left : Element_Type; Right : Cursor) return Boolean is
164 begin
165 return Left < Right.Node.Element.all;
166 end "<";
168 ---------
169 -- "=" --
170 ---------
172 function "=" (Left, Right : Set) return Boolean is
174 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean;
175 pragma Inline (Is_Equal_Node_Node);
177 function Is_Equal is
178 new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
180 ------------------------
181 -- Is_Equal_Node_Node --
182 ------------------------
184 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean is
185 begin
186 return L.Element.all = R.Element.all;
187 end Is_Equal_Node_Node;
189 -- Start of processing for "="
191 begin
192 if Left'Address = Right'Address then
193 return True;
194 end if;
196 return Is_Equal (Left.Tree, Right.Tree);
197 end "=";
200 ---------
201 -- ">" --
202 ---------
204 function ">" (Left, Right : Cursor) return Boolean is
205 begin
206 -- L > R same as R < L
208 return Right.Node.Element.all < Left.Node.Element.all;
209 end ">";
211 function ">" (Left : Cursor; Right : Element_Type) return Boolean is
212 begin
213 return Right < Left.Node.Element.all;
214 end ">";
216 function ">" (Left : Element_Type; Right : Cursor) return Boolean is
217 begin
218 return Right.Node.Element.all < Left;
219 end ">";
221 ------------
222 -- Adjust --
223 ------------
225 procedure Adjust (Container : in out Set) is
226 Tree : Tree_Type renames Container.Tree;
228 begin
229 if Tree.Length = 0 then
230 pragma Assert (Tree.Root = null);
231 return;
232 end if;
234 begin
235 Tree.Root := Copy_Tree (Tree.Root);
236 exception
237 when others =>
238 Tree := (Length => 0, others => null);
239 raise;
240 end;
242 Tree.First := Min (Tree.Root);
243 Tree.Last := Max (Tree.Root);
244 end Adjust;
246 -------------
247 -- Ceiling --
248 -------------
250 function Ceiling (Container : Set; Item : Element_Type) return Cursor is
251 Node : constant Node_Access :=
252 Element_Keys.Ceiling (Container.Tree, Item);
254 begin
255 if Node = null then
256 return No_Element;
257 end if;
259 return Cursor'(Container'Unchecked_Access, Node);
260 end Ceiling;
262 -----------
263 -- Clear --
264 -----------
266 procedure Clear (Container : in out Set) is
267 Tree : Tree_Type renames Container.Tree;
268 Root : Node_Access := Tree.Root;
269 begin
270 Tree := (Length => 0, others => null);
271 Delete_Tree (Root);
272 end Clear;
274 -----------
275 -- Color --
276 -----------
278 function Color (Node : Node_Access) return Color_Type is
279 begin
280 return Node.Color;
281 end Color;
283 --------------
284 -- Contains --
285 --------------
287 function Contains (Container : Set; Item : Element_Type) return Boolean is
288 begin
289 return Find (Container, Item) /= No_Element;
290 end Contains;
292 ---------------
293 -- Copy_Node --
294 ---------------
296 function Copy_Node (Source : Node_Access) return Node_Access is
297 Element : Element_Access := new Element_Type'(Source.Element.all);
298 begin
299 return new Node_Type'(Parent => null,
300 Left => null,
301 Right => null,
302 Color => Source.Color,
303 Element => Element);
304 exception
305 when others =>
306 Free_Element (Element);
307 raise;
308 end Copy_Node;
310 ---------------
311 -- Copy_Tree --
312 ---------------
314 function Copy_Tree (Source_Root : Node_Access) return Node_Access is
315 Target_Root : Node_Access := Copy_Node (Source_Root);
316 P, X : Node_Access;
318 begin
319 if Source_Root.Right /= null then
320 Target_Root.Right := Copy_Tree (Source_Root.Right);
321 Target_Root.Right.Parent := Target_Root;
322 end if;
324 P := Target_Root;
325 X := Source_Root.Left;
327 while X /= null loop
328 declare
329 Y : Node_Access := Copy_Node (X);
331 begin
332 P.Left := Y;
333 Y.Parent := P;
335 if X.Right /= null then
336 Y.Right := Copy_Tree (X.Right);
337 Y.Right.Parent := Y;
338 end if;
340 P := Y;
341 X := X.Left;
342 end;
343 end loop;
345 return Target_Root;
347 exception
348 when others =>
349 Delete_Tree (Target_Root);
350 raise;
351 end Copy_Tree;
353 ------------
354 -- Delete --
355 ------------
357 procedure Delete (Container : in out Set; Position : in out Cursor) is
358 begin
359 if Position = No_Element then
360 return;
361 end if;
363 if Position.Container /= Set_Access'(Container'Unchecked_Access) then
364 raise Program_Error;
365 end if;
367 Delete_Node_Sans_Free (Container.Tree, Position.Node);
368 Free (Position.Node);
370 Position.Container := null;
371 end Delete;
373 procedure Delete (Container : in out Set; Item : Element_Type) is
374 X : Node_Access :=
375 Element_Keys.Find (Container.Tree, Item);
377 begin
378 if X = null then
379 raise Constraint_Error;
380 end if;
382 Delete_Node_Sans_Free (Container.Tree, X);
383 Free (X);
384 end Delete;
386 ------------------
387 -- Delete_First --
388 ------------------
390 procedure Delete_First (Container : in out Set) is
391 C : Cursor := First (Container);
392 begin
393 Delete (Container, C);
394 end Delete_First;
396 -----------------
397 -- Delete_Last --
398 -----------------
400 procedure Delete_Last (Container : in out Set) is
401 C : Cursor := Last (Container);
402 begin
403 Delete (Container, C);
404 end Delete_Last;
406 -----------------
407 -- Delete_Tree --
408 -----------------
410 procedure Delete_Tree (X : in out Node_Access) is
411 Y : Node_Access;
412 begin
413 while X /= null loop
414 Y := X.Right;
415 Delete_Tree (Y);
416 Y := X.Left;
417 Free (X);
418 X := Y;
419 end loop;
420 end Delete_Tree;
422 ----------------
423 -- Difference --
424 ----------------
426 procedure Difference (Target : in out Set; Source : Set) is
427 begin
428 if Target'Address = Source'Address then
429 Clear (Target);
430 return;
431 end if;
433 Set_Ops.Difference (Target.Tree, Source.Tree);
434 end Difference;
436 function Difference (Left, Right : Set) return Set is
437 begin
438 if Left'Address = Right'Address then
439 return Empty_Set;
440 end if;
442 declare
443 Tree : constant Tree_Type :=
444 Set_Ops.Difference (Left.Tree, Right.Tree);
445 begin
446 return (Controlled with Tree);
447 end;
448 end Difference;
450 -------------
451 -- Element --
452 -------------
454 function Element (Position : Cursor) return Element_Type is
455 begin
456 return Position.Node.Element.all;
457 end Element;
459 -------------
460 -- Exclude --
461 -------------
463 procedure Exclude (Container : in out Set; Item : Element_Type) is
464 X : Node_Access :=
465 Element_Keys.Find (Container.Tree, Item);
466 begin
467 if X /= null then
468 Delete_Node_Sans_Free (Container.Tree, X);
469 Free (X);
470 end if;
471 end Exclude;
473 ----------
474 -- Find --
475 ----------
477 function Find (Container : Set; Item : Element_Type) return Cursor is
478 Node : constant Node_Access :=
479 Element_Keys.Find (Container.Tree, Item);
481 begin
482 if Node = null then
483 return No_Element;
484 end if;
486 return Cursor'(Container'Unchecked_Access, Node);
487 end Find;
489 -----------
490 -- First --
491 -----------
493 function First (Container : Set) return Cursor is
494 begin
495 if Container.Tree.First = null then
496 return No_Element;
497 end if;
499 return Cursor'(Container'Unchecked_Access, Container.Tree.First);
500 end First;
502 -------------------
503 -- First_Element --
504 -------------------
506 function First_Element (Container : Set) return Element_Type is
507 begin
508 return Container.Tree.First.Element.all;
509 end First_Element;
511 -----------
512 -- Floor --
513 -----------
515 function Floor (Container : Set; Item : Element_Type) return Cursor is
516 Node : constant Node_Access :=
517 Element_Keys.Floor (Container.Tree, Item);
519 begin
520 if Node = null then
521 return No_Element;
522 end if;
524 return Cursor'(Container'Unchecked_Access, Node);
525 end Floor;
527 ----------
528 -- Free --
529 ----------
531 procedure Free (X : in out Node_Access) is
532 procedure Deallocate is
533 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
534 begin
535 if X /= null then
536 Free_Element (X.Element);
537 Deallocate (X);
538 end if;
539 end Free;
541 ------------------
542 -- Generic_Keys --
543 ------------------
545 package body Generic_Keys is
547 -----------------------
548 -- Local Subprograms --
549 -----------------------
551 function Is_Greater_Key_Node
552 (Left : Key_Type;
553 Right : Node_Access) return Boolean;
554 pragma Inline (Is_Greater_Key_Node);
556 function Is_Less_Key_Node
557 (Left : Key_Type;
558 Right : Node_Access) return Boolean;
559 pragma Inline (Is_Less_Key_Node);
561 --------------------------
562 -- Local Instantiations --
563 --------------------------
565 package Key_Keys is
566 new Red_Black_Trees.Generic_Keys
567 (Tree_Operations => Tree_Operations,
568 Key_Type => Key_Type,
569 Is_Less_Key_Node => Is_Less_Key_Node,
570 Is_Greater_Key_Node => Is_Greater_Key_Node);
572 ---------
573 -- "<" --
574 ---------
576 function "<" (Left : Key_Type; Right : Cursor) return Boolean is
577 begin
578 return Left < Right.Node.Element.all;
579 end "<";
581 function "<" (Left : Cursor; Right : Key_Type) return Boolean is
582 begin
583 return Right > Left.Node.Element.all;
584 end "<";
586 ---------
587 -- ">" --
588 ---------
590 function ">" (Left : Key_Type; Right : Cursor) return Boolean is
591 begin
592 return Left > Right.Node.Element.all;
593 end ">";
595 function ">" (Left : Cursor; Right : Key_Type) return Boolean is
596 begin
597 return Right < Left.Node.Element.all;
598 end ">";
600 -------------
601 -- Ceiling --
602 -------------
604 function Ceiling (Container : Set; Key : Key_Type) return Cursor is
605 Node : constant Node_Access :=
606 Key_Keys.Ceiling (Container.Tree, Key);
608 begin
609 if Node = null then
610 return No_Element;
611 end if;
613 return Cursor'(Container'Unchecked_Access, Node);
614 end Ceiling;
616 ----------------------------
617 -- Checked_Update_Element --
618 ----------------------------
620 procedure Checked_Update_Element
621 (Container : in out Set;
622 Position : Cursor;
623 Process : not null access
624 procedure (Element : in out Element_Type))
626 begin
627 if Position.Container = null then
628 raise Constraint_Error;
629 end if;
631 if Position.Container /= Set_Access'(Container'Unchecked_Access) then
632 raise Program_Error;
633 end if;
635 declare
636 Old_Key : Key_Type renames Key (Position.Node.Element.all);
638 begin
639 Process (Position.Node.Element.all);
641 if Old_Key < Position.Node.Element.all
642 or else Old_Key > Position.Node.Element.all
643 then
644 null;
645 else
646 return;
647 end if;
648 end;
650 declare
651 Result : Node_Access;
652 Success : Boolean;
654 function New_Node return Node_Access;
655 pragma Inline (New_Node);
657 procedure Insert_Post is
658 new Key_Keys.Generic_Insert_Post (New_Node);
660 procedure Insert is
661 new Key_Keys.Generic_Conditional_Insert (Insert_Post);
663 --------------
664 -- New_Node --
665 --------------
667 function New_Node return Node_Access is
668 begin
669 return Position.Node;
670 end New_Node;
672 -- Start of processing for Checked_Update_Element
674 begin
675 Delete_Node_Sans_Free (Container.Tree, Position.Node);
677 Insert
678 (Tree => Container.Tree,
679 Key => Key (Position.Node.Element.all),
680 Node => Result,
681 Success => Success);
683 if not Success then
684 declare
685 X : Node_Access := Position.Node;
686 begin
687 Free (X);
688 end;
690 raise Program_Error;
691 end if;
693 pragma Assert (Result = Position.Node);
694 end;
695 end Checked_Update_Element;
697 --------------
698 -- Contains --
699 --------------
701 function Contains (Container : Set; Key : Key_Type) return Boolean is
702 begin
703 return Find (Container, Key) /= No_Element;
704 end Contains;
706 ------------
707 -- Delete --
708 ------------
710 procedure Delete (Container : in out Set; Key : Key_Type) is
711 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
713 begin
714 if X = null then
715 raise Constraint_Error;
716 end if;
718 Delete_Node_Sans_Free (Container.Tree, X);
719 Free (X);
720 end Delete;
722 -------------
723 -- Element --
724 -------------
726 function Element (Container : Set; Key : Key_Type) return Element_Type is
727 C : constant Cursor := Find (Container, Key);
728 begin
729 return C.Node.Element.all;
730 end Element;
732 -------------
733 -- Exclude --
734 -------------
736 procedure Exclude (Container : in out Set; Key : Key_Type) is
737 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
739 begin
740 if X /= null then
741 Delete_Node_Sans_Free (Container.Tree, X);
742 Free (X);
743 end if;
744 end Exclude;
746 ----------
747 -- Find --
748 ----------
750 function Find (Container : Set; Key : Key_Type) return Cursor is
751 Node : constant Node_Access :=
752 Key_Keys.Find (Container.Tree, Key);
754 begin
755 if Node = null then
756 return No_Element;
757 end if;
759 return Cursor'(Container'Unchecked_Access, Node);
760 end Find;
762 -----------
763 -- Floor --
764 -----------
766 function Floor (Container : Set; Key : Key_Type) return Cursor is
767 Node : constant Node_Access :=
768 Key_Keys.Floor (Container.Tree, Key);
770 begin
771 if Node = null then
772 return No_Element;
773 end if;
775 return Cursor'(Container'Unchecked_Access, Node);
776 end Floor;
778 -------------------------
779 -- Is_Greater_Key_Node --
780 -------------------------
782 function Is_Greater_Key_Node
783 (Left : Key_Type;
784 Right : Node_Access) return Boolean is
785 begin
786 return Left > Right.Element.all;
787 end Is_Greater_Key_Node;
789 ----------------------
790 -- Is_Less_Key_Node --
791 ----------------------
793 function Is_Less_Key_Node
794 (Left : Key_Type;
795 Right : Node_Access) return Boolean is
796 begin
797 return Left < Right.Element.all;
798 end Is_Less_Key_Node;
800 ---------
801 -- Key --
802 ---------
804 function Key (Position : Cursor) return Key_Type is
805 begin
806 return Key (Position.Node.Element.all);
807 end Key;
809 end Generic_Keys;
811 -----------------
812 -- Has_Element --
813 -----------------
815 function Has_Element (Position : Cursor) return Boolean is
816 begin
817 return Position /= No_Element;
818 end Has_Element;
820 -------------
821 -- Include --
822 -------------
824 procedure Include (Container : in out Set; New_Item : Element_Type) is
825 Position : Cursor;
826 Inserted : Boolean;
828 X : Element_Access;
830 begin
831 Insert (Container, New_Item, Position, Inserted);
833 if not Inserted then
834 X := Position.Node.Element;
835 Position.Node.Element := new Element_Type'(New_Item);
836 Free_Element (X);
837 end if;
838 end Include;
840 ------------
841 -- Insert --
842 ------------
844 procedure Insert
845 (Container : in out Set;
846 New_Item : Element_Type;
847 Position : out Cursor;
848 Inserted : out Boolean)
850 function New_Node return Node_Access;
851 pragma Inline (New_Node);
853 procedure Insert_Post is
854 new Element_Keys.Generic_Insert_Post (New_Node);
856 procedure Insert_Sans_Hint is
857 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
859 --------------
860 -- New_Node --
861 --------------
863 function New_Node return Node_Access is
864 Element : Element_Access := new Element_Type'(New_Item);
865 begin
866 return new Node_Type'(Parent => null,
867 Left => null,
868 Right => null,
869 Color => Red,
870 Element => Element);
871 exception
872 when others =>
873 Free_Element (Element);
874 raise;
875 end New_Node;
877 -- Start of processing for Insert
879 begin
880 Insert_Sans_Hint
881 (Container.Tree,
882 New_Item,
883 Position.Node,
884 Inserted);
886 Position.Container := Container'Unchecked_Access;
887 end Insert;
889 procedure Insert (Container : in out Set; New_Item : Element_Type) is
890 Position : Cursor;
891 Inserted : Boolean;
892 begin
893 Insert (Container, New_Item, Position, Inserted);
895 if not Inserted then
896 raise Constraint_Error;
897 end if;
898 end Insert;
900 ----------------------
901 -- Insert_With_Hint --
902 ----------------------
904 procedure Insert_With_Hint
905 (Dst_Tree : in out Tree_Type;
906 Dst_Hint : Node_Access;
907 Src_Node : Node_Access;
908 Dst_Node : out Node_Access)
910 Success : Boolean;
912 function New_Node return Node_Access;
914 procedure Insert_Post is
915 new Element_Keys.Generic_Insert_Post (New_Node);
917 procedure Insert_Sans_Hint is
918 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
920 procedure Insert_With_Hint is
921 new Element_Keys.Generic_Conditional_Insert_With_Hint
922 (Insert_Post,
923 Insert_Sans_Hint);
925 --------------
926 -- New_Node --
927 --------------
929 function New_Node return Node_Access is
930 Element : Element_Access :=
931 new Element_Type'(Src_Node.Element.all);
932 Node : Node_Access;
934 begin
935 begin
936 Node := new Node_Type;
937 exception
938 when others =>
939 Free_Element (Element);
940 raise;
941 end;
943 Node.Element := Element;
944 return Node;
945 end New_Node;
947 -- Start of processing for Insert_With_Hint
949 begin
950 Insert_With_Hint
951 (Dst_Tree,
952 Dst_Hint,
953 Src_Node.Element.all,
954 Dst_Node,
955 Success);
956 end Insert_With_Hint;
958 ------------------
959 -- Intersection --
960 ------------------
962 procedure Intersection (Target : in out Set; Source : Set) is
963 begin
964 if Target'Address = Source'Address then
965 return;
966 end if;
968 Set_Ops.Intersection (Target.Tree, Source.Tree);
969 end Intersection;
971 function Intersection (Left, Right : Set) return Set is
972 begin
973 if Left'Address = Right'Address then
974 return Left;
975 end if;
977 declare
978 Tree : constant Tree_Type :=
979 Set_Ops.Intersection (Left.Tree, Right.Tree);
980 begin
981 return (Controlled with Tree);
982 end;
983 end Intersection;
985 --------------
986 -- Is_Empty --
987 --------------
989 function Is_Empty (Container : Set) return Boolean is
990 begin
991 return Length (Container) = 0;
992 end Is_Empty;
994 -----------------------------
995 -- Is_Greater_Element_Node --
996 -----------------------------
998 function Is_Greater_Element_Node
999 (Left : Element_Type;
1000 Right : Node_Access) return Boolean is
1001 begin
1002 -- e > node same as node < e
1004 return Right.Element.all < Left;
1005 end Is_Greater_Element_Node;
1008 --------------------------
1009 -- Is_Less_Element_Node --
1010 --------------------------
1012 function Is_Less_Element_Node
1013 (Left : Element_Type;
1014 Right : Node_Access) return Boolean is
1015 begin
1016 return Left < Right.Element.all;
1017 end Is_Less_Element_Node;
1019 -----------------------
1020 -- Is_Less_Node_Node --
1021 -----------------------
1023 function Is_Less_Node_Node (L, R : Node_Access) return Boolean is
1024 begin
1025 return L.Element.all < R.Element.all;
1026 end Is_Less_Node_Node;
1028 ---------------
1029 -- Is_Subset --
1030 ---------------
1032 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
1033 begin
1034 if Subset'Address = Of_Set'Address then
1035 return True;
1036 end if;
1038 return Set_Ops.Is_Subset (Subset => Subset.Tree, Of_Set => Of_Set.Tree);
1039 end Is_Subset;
1041 -------------
1042 -- Iterate --
1043 -------------
1045 procedure Iterate
1046 (Container : Set;
1047 Process : not null access procedure (Position : Cursor))
1049 procedure Process_Node (Node : Node_Access);
1050 pragma Inline (Process_Node);
1052 procedure Local_Iterate is
1053 new Tree_Operations.Generic_Iteration (Process_Node);
1055 ------------------
1056 -- Process_Node --
1057 ------------------
1059 procedure Process_Node (Node : Node_Access) is
1060 begin
1061 Process (Cursor'(Container'Unchecked_Access, Node));
1062 end Process_Node;
1064 -- Start of processing for Iterate
1066 begin
1067 Local_Iterate (Container.Tree);
1068 end Iterate;
1070 ----------
1071 -- Last --
1072 ----------
1074 function Last (Container : Set) return Cursor is
1075 begin
1076 if Container.Tree.Last = null then
1077 return No_Element;
1078 end if;
1080 return Cursor'(Container'Unchecked_Access, Container.Tree.Last);
1081 end Last;
1083 ------------------
1084 -- Last_Element --
1085 ------------------
1087 function Last_Element (Container : Set) return Element_Type is
1088 begin
1089 return Container.Tree.Last.Element.all;
1090 end Last_Element;
1092 ----------
1093 -- Left --
1094 ----------
1096 function Left (Node : Node_Access) return Node_Access is
1097 begin
1098 return Node.Left;
1099 end Left;
1101 ------------
1102 -- Length --
1103 ------------
1105 function Length (Container : Set) return Count_Type is
1106 begin
1107 return Container.Tree.Length;
1108 end Length;
1110 ----------
1111 -- Move --
1112 ----------
1114 procedure Move (Target : in out Set; Source : in out Set) is
1115 begin
1116 if Target'Address = Source'Address then
1117 return;
1118 end if;
1120 Move (Target => Target.Tree, Source => Source.Tree);
1121 end Move;
1123 ----------
1124 -- Next --
1125 ----------
1127 procedure Next (Position : in out Cursor) is
1128 begin
1129 Position := Next (Position);
1130 end Next;
1132 function Next (Position : Cursor) return Cursor is
1133 begin
1134 if Position = No_Element then
1135 return No_Element;
1136 end if;
1138 declare
1139 Node : constant Node_Access :=
1140 Tree_Operations.Next (Position.Node);
1141 begin
1142 if Node = null then
1143 return No_Element;
1144 end if;
1146 return Cursor'(Position.Container, Node);
1147 end;
1148 end Next;
1150 -------------
1151 -- Overlap --
1152 -------------
1154 function Overlap (Left, Right : Set) return Boolean is
1155 begin
1156 if Left'Address = Right'Address then
1157 return Left.Tree.Length /= 0;
1158 end if;
1160 return Set_Ops.Overlap (Left.Tree, Right.Tree);
1161 end Overlap;
1163 ------------
1164 -- Parent --
1165 ------------
1167 function Parent (Node : Node_Access) return Node_Access is
1168 begin
1169 return Node.Parent;
1170 end Parent;
1172 --------------
1173 -- Previous --
1174 --------------
1176 procedure Previous (Position : in out Cursor) is
1177 begin
1178 Position := Previous (Position);
1179 end Previous;
1181 function Previous (Position : Cursor) return Cursor is
1182 begin
1183 if Position = No_Element then
1184 return No_Element;
1185 end if;
1187 declare
1188 Node : constant Node_Access :=
1189 Tree_Operations.Previous (Position.Node);
1190 begin
1191 if Node = null then
1192 return No_Element;
1193 end if;
1195 return Cursor'(Position.Container, Node);
1196 end;
1197 end Previous;
1199 -------------------
1200 -- Query_Element --
1201 -------------------
1203 procedure Query_Element
1204 (Position : Cursor;
1205 Process : not null access procedure (Element : Element_Type))
1207 begin
1208 Process (Position.Node.Element.all);
1209 end Query_Element;
1211 ----------
1212 -- Read --
1213 ----------
1215 procedure Read
1216 (Stream : access Ada.Streams.Root_Stream_Type'Class;
1217 Container : out Set)
1219 N : Count_Type'Base;
1221 function New_Node return Node_Access;
1223 procedure Read is
1224 new Tree_Operations.Generic_Read (New_Node);
1226 --------------
1227 -- New_Node --
1228 --------------
1230 function New_Node return Node_Access is
1231 Node : Node_Access := new Node_Type;
1233 begin
1234 Node.Element := new Element_Type'(Element_Type'Input (Stream));
1235 return Node;
1237 exception
1238 when others =>
1239 Free (Node);
1240 raise;
1241 end New_Node;
1243 -- Start of processing for Read
1245 begin
1246 Clear (Container);
1247 Count_Type'Base'Read (Stream, N);
1248 pragma Assert (N >= 0);
1249 Read (Container.Tree, N);
1250 end Read;
1252 -------------
1253 -- Replace --
1254 -------------
1256 procedure Replace (Container : in out Set; New_Item : Element_Type) is
1257 Node : constant Node_Access :=
1258 Element_Keys.Find (Container.Tree, New_Item);
1260 X : Element_Access;
1262 begin
1263 if Node = null then
1264 raise Constraint_Error;
1265 end if;
1267 X := Node.Element;
1268 Node.Element := new Element_Type'(New_Item);
1269 Free_Element (X);
1270 end Replace;
1272 -- TODO ???
1273 -- procedure Replace
1274 -- (Container : in out Set;
1275 -- Key : Key_Type;
1276 -- New_Item : Element_Type)
1277 -- is
1278 -- Node : Node_Access := Key_Keys.Find (Container.Tree, Key);
1280 -- begin
1281 -- if Node = null then
1282 -- raise Constraint_Error;
1283 -- end if;
1285 -- Replace_Element (Container, Node, New_Item);
1286 -- end Replace;
1288 ---------------------
1289 -- Replace_Element --
1290 ---------------------
1292 -- TODO: ???
1293 -- procedure Replace_Element
1294 -- (Container : in out Set;
1295 -- Position : Node_Access;
1296 -- By : Element_Type)
1297 -- is
1299 -- Node : Node_Access := Position;
1301 -- begin
1302 -- if By < Node.Element.all
1303 -- or else Node.Element.all < By
1304 -- then
1305 -- null;
1307 -- else
1308 -- declare
1309 -- X : Element_Access := Node.Element;
1311 -- begin
1312 -- Node.Element := new Element_Type'(By);
1314 -- -- NOTE: If there's an exception here, then just
1315 -- -- let it propagate. We haven't modified the
1316 -- -- state of the container, so there's nothing else
1317 -- -- we need to do.
1319 -- Free_Element (X);
1320 -- end;
1322 -- return;
1323 -- end if;
1325 -- Delete_Node_Sans_Free (Container.Tree, Node);
1327 -- begin
1328 -- Free_Element (Node.Element);
1329 -- exception
1330 -- when others =>
1331 -- Node.Element := null; -- don't attempt to dealloc X.E again
1332 -- Free (Node);
1333 -- raise;
1334 -- end;
1336 -- begin
1337 -- Node.Element := new Element_Type'(By);
1338 -- exception
1339 -- when others =>
1340 -- Free (Node);
1341 -- raise;
1342 -- end;
1344 -- declare
1345 -- function New_Node return Node_Access;
1346 -- pragma Inline (New_Node);
1348 -- function New_Node return Node_Access is
1349 -- begin
1350 -- return Node;
1351 -- end New_Node;
1353 -- procedure Insert_Post is
1354 -- new Element_Keys.Generic_Insert_Post (New_Node);
1356 -- procedure Insert is
1357 -- new Element_Keys.Generic_Conditional_Insert (Insert_Post);
1359 -- Result : Node_Access;
1360 -- Success : Boolean;
1362 -- begin
1363 -- Insert
1364 -- (Tree => Container.Tree,
1365 -- Key => Node.Element.all,
1366 -- Node => Result,
1367 -- Success => Success);
1369 -- if not Success then
1370 -- Free (Node);
1371 -- raise Program_Error;
1372 -- end if;
1374 -- pragma Assert (Result = Node);
1375 -- end;
1376 -- end Replace_Element;
1379 -- procedure Replace_Element
1380 -- (Container : in out Set;
1381 -- Position : Cursor;
1382 -- By : Element_Type)
1383 -- is
1384 -- begin
1385 -- if Position.Container = null then
1386 -- raise Constraint_Error;
1387 -- end if;
1389 -- if Position.Container /= Set_Access'(Container'Unchecked_Access) then
1390 -- raise Program_Error;
1391 -- end if;
1393 -- Replace_Element (Container, Position.Node, By);
1394 -- end Replace_Element;
1396 ---------------------
1397 -- Reverse_Iterate --
1398 ---------------------
1400 procedure Reverse_Iterate
1401 (Container : Set;
1402 Process : not null access procedure (Position : Cursor))
1404 procedure Process_Node (Node : Node_Access);
1405 pragma Inline (Process_Node);
1407 procedure Local_Reverse_Iterate is
1408 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1410 ------------------
1411 -- Process_Node --
1412 ------------------
1414 procedure Process_Node (Node : Node_Access) is
1415 begin
1416 Process (Cursor'(Container'Unchecked_Access, Node));
1417 end Process_Node;
1419 -- Start of processing for Reverse_Iterate
1421 begin
1422 Local_Reverse_Iterate (Container.Tree);
1423 end Reverse_Iterate;
1425 -----------
1426 -- Right --
1427 -----------
1429 function Right (Node : Node_Access) return Node_Access is
1430 begin
1431 return Node.Right;
1432 end Right;
1434 ---------------
1435 -- Set_Color --
1436 ---------------
1438 procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1439 begin
1440 Node.Color := Color;
1441 end Set_Color;
1443 --------------
1444 -- Set_Left --
1445 --------------
1447 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1448 begin
1449 Node.Left := Left;
1450 end Set_Left;
1452 ----------------
1453 -- Set_Parent --
1454 ----------------
1456 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1457 begin
1458 Node.Parent := Parent;
1459 end Set_Parent;
1461 ---------------
1462 -- Set_Right --
1463 ---------------
1465 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1466 begin
1467 Node.Right := Right;
1468 end Set_Right;
1470 --------------------------
1471 -- Symmetric_Difference --
1472 --------------------------
1474 procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1475 begin
1476 if Target'Address = Source'Address then
1477 Clear (Target);
1478 return;
1479 end if;
1481 Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1482 end Symmetric_Difference;
1484 function Symmetric_Difference (Left, Right : Set) return Set is
1485 begin
1486 if Left'Address = Right'Address then
1487 return Empty_Set;
1488 end if;
1490 declare
1491 Tree : constant Tree_Type :=
1492 Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1493 begin
1494 return (Controlled with Tree);
1495 end;
1496 end Symmetric_Difference;
1498 -----------
1499 -- Union --
1500 -----------
1502 procedure Union (Target : in out Set; Source : Set) is
1503 begin
1504 if Target'Address = Source'Address then
1505 return;
1506 end if;
1508 Set_Ops.Union (Target.Tree, Source.Tree);
1509 end Union;
1511 function Union (Left, Right : Set) return Set is
1512 begin
1513 if Left'Address = Right'Address then
1514 return Left;
1515 end if;
1517 declare
1518 Tree : constant Tree_Type :=
1519 Set_Ops.Union (Left.Tree, Right.Tree);
1520 begin
1521 return (Controlled with Tree);
1522 end;
1523 end Union;
1525 -----------
1526 -- Write --
1527 -----------
1529 procedure Write
1530 (Stream : access Ada.Streams.Root_Stream_Type'Class;
1531 Container : Set)
1533 procedure Process (Node : Node_Access);
1534 pragma Inline (Process);
1536 procedure Iterate is
1537 new Tree_Operations.Generic_Iteration (Process);
1539 -------------
1540 -- Process --
1541 -------------
1543 procedure Process (Node : Node_Access) is
1544 begin
1545 Element_Type'Output (Stream, Node.Element.all);
1546 end Process;
1548 -- Start of processing for Write
1550 begin
1551 Count_Type'Base'Write (Stream, Container.Tree.Length);
1552 Iterate (Container.Tree);
1553 end Write;
1555 end Ada.Containers.Indefinite_Ordered_Sets;