* arm.c (FL_WBUF): Define.
[official-gcc.git] / gcc / ada / a-ciormu.adb
blob1d608b0367215f532d49a18f5beef03072f0c191
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- ADA.CONTAINERS.INDEFINITE_ORDERED_MULTISETS --
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.Unchecked_Deallocation;
38 with Ada.Containers.Red_Black_Trees.Generic_Operations;
39 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Operations);
41 with Ada.Containers.Red_Black_Trees.Generic_Keys;
42 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys);
44 with Ada.Containers.Red_Black_Trees.Generic_Set_Operations;
45 pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Set_Operations);
47 with System; use type System.Address;
49 package body Ada.Containers.Indefinite_Ordered_Multisets is
51 use Red_Black_Trees;
53 type Element_Access is access Element_Type;
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 -- Node Access Subprograms --
65 -----------------------------
67 -- These subprograms provide a functional interface to access fields
68 -- of a node, and a procedural interface for modifying these values.
70 function Color (Node : Node_Access) return Color_Type;
71 pragma Inline (Color);
73 function Left (Node : Node_Access) return Node_Access;
74 pragma Inline (Left);
76 function Parent (Node : Node_Access) return Node_Access;
77 pragma Inline (Parent);
79 function Right (Node : Node_Access) return Node_Access;
80 pragma Inline (Right);
82 procedure Set_Parent (Node : Node_Access; Parent : Node_Access);
83 pragma Inline (Set_Parent);
85 procedure Set_Left (Node : Node_Access; Left : Node_Access);
86 pragma Inline (Set_Left);
88 procedure Set_Right (Node : Node_Access; Right : Node_Access);
89 pragma Inline (Set_Right);
91 procedure Set_Color (Node : Node_Access; Color : Color_Type);
92 pragma Inline (Set_Color);
94 -----------------------
95 -- Local Subprograms --
96 -----------------------
98 function Copy_Node (Source : Node_Access) return Node_Access;
99 pragma Inline (Copy_Node);
101 function Copy_Tree (Source_Root : Node_Access) return Node_Access;
103 procedure Delete_Tree (X : in out Node_Access);
105 procedure Free (X : in out Node_Access);
107 procedure Insert_With_Hint
108 (Dst_Tree : in out Tree_Type;
109 Dst_Hint : Node_Access;
110 Src_Node : Node_Access;
111 Dst_Node : out Node_Access);
113 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean;
114 pragma Inline (Is_Equal_Node_Node);
116 function Is_Greater_Element_Node
117 (Left : Element_Type;
118 Right : Node_Access) return Boolean;
119 pragma Inline (Is_Greater_Element_Node);
121 function Is_Less_Element_Node
122 (Left : Element_Type;
123 Right : Node_Access) return Boolean;
124 pragma Inline (Is_Less_Element_Node);
126 function Is_Less_Node_Node (L, R : Node_Access) return Boolean;
127 pragma Inline (Is_Less_Node_Node);
129 --------------------------
130 -- Local Instantiations --
131 --------------------------
133 package Tree_Operations is
134 new Red_Black_Trees.Generic_Operations
135 (Tree_Types => Tree_Types,
136 Null_Node => Node_Access'(null));
138 use Tree_Operations;
140 procedure Free_Element is
141 new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
143 function Is_Equal is
144 new Tree_Operations.Generic_Equal (Is_Equal_Node_Node);
146 package Set_Ops is
147 new Generic_Set_Operations
148 (Tree_Operations => Tree_Operations,
149 Insert_With_Hint => Insert_With_Hint,
150 Copy_Tree => Copy_Tree,
151 Delete_Tree => Delete_Tree,
152 Is_Less => Is_Less_Node_Node,
153 Free => Free);
155 package Element_Keys is
156 new Red_Black_Trees.Generic_Keys
157 (Tree_Operations => Tree_Operations,
158 Key_Type => Element_Type,
159 Is_Less_Key_Node => Is_Less_Element_Node,
160 Is_Greater_Key_Node => Is_Greater_Element_Node);
162 ---------
163 -- "<" --
164 ---------
166 function "<" (Left, Right : Cursor) return Boolean is
167 begin
168 return Left.Node.Element.all < Right.Node.Element.all;
169 end "<";
171 function "<" (Left : Cursor; Right : Element_Type) return Boolean is
172 begin
173 return Left.Node.Element.all < Right;
174 end "<";
176 function "<" (Left : Element_Type; Right : Cursor) return Boolean is
177 begin
178 return Left < Right.Node.Element.all;
179 end "<";
181 ---------
182 -- "=" --
183 ---------
185 function "=" (Left, Right : Set) return Boolean is begin
186 if Left'Address = Right'Address then
187 return True;
188 end if;
190 return Is_Equal (Left.Tree, Right.Tree);
191 end "=";
193 ---------
194 -- ">" --
195 ---------
197 function ">" (Left : Cursor; Right : Element_Type) return Boolean is
198 begin
199 return Right < Left.Node.Element.all;
200 end ">";
202 function ">" (Left, Right : Cursor) return Boolean is
203 begin
204 -- L > R same as R < L
206 return Right.Node.Element.all < Left.Node.Element.all;
207 end ">";
209 function ">" (Left : Element_Type; Right : Cursor) return Boolean is
210 begin
211 return Right.Node.Element.all < Left;
212 end ">";
214 ------------
215 -- Adjust --
216 ------------
218 procedure Adjust (Container : in out Set) is
219 Tree : Tree_Type renames Container.Tree;
221 N : constant Count_Type := Tree.Length;
222 X : constant Node_Access := Tree.Root;
224 begin
225 if N = 0 then
226 pragma Assert (X = null);
227 return;
228 end if;
230 Tree := (Length => 0, others => null);
232 Tree.Root := Copy_Tree (X);
233 Tree.First := Min (Tree.Root);
234 Tree.Last := Max (Tree.Root);
235 Tree.Length := N;
236 end Adjust;
238 -------------
239 -- Ceiling --
240 -------------
242 function Ceiling (Container : Set; Item : Element_Type) return Cursor is
243 Node : constant Node_Access :=
244 Element_Keys.Ceiling (Container.Tree, Item);
246 begin
247 if Node = null then
248 return No_Element;
249 end if;
251 return Cursor'(Container'Unchecked_Access, Node);
252 end Ceiling;
254 -----------
255 -- Clear --
256 -----------
258 procedure Clear (Container : in out Set) is
259 Tree : Tree_Type renames Container.Tree;
260 Root : Node_Access := Tree.Root;
261 begin
262 Tree := (Length => 0, others => null);
263 Delete_Tree (Root);
264 end Clear;
266 -----------
267 -- Color --
268 -----------
270 function Color (Node : Node_Access) return Color_Type is
271 begin
272 return Node.Color;
273 end Color;
275 --------------
276 -- Contains --
277 --------------
279 function Contains (Container : Set; Item : Element_Type) return Boolean is
280 begin
281 return Find (Container, Item) /= No_Element;
282 end Contains;
284 ---------------
285 -- Copy_Node --
286 ---------------
288 function Copy_Node (Source : Node_Access) return Node_Access is
289 X : Element_Access := new Element_Type'(Source.Element.all);
291 begin
292 return new Node_Type'(Parent => null,
293 Left => null,
294 Right => null,
295 Color => Source.Color,
296 Element => X);
298 exception
299 when others =>
300 Free_Element (X);
301 raise;
302 end Copy_Node;
304 ---------------
305 -- Copy_Tree --
306 ---------------
308 function Copy_Tree (Source_Root : Node_Access) return Node_Access is
309 Target_Root : Node_Access := Copy_Node (Source_Root);
311 P, X : Node_Access;
313 begin
314 if Source_Root.Right /= null then
315 Target_Root.Right := Copy_Tree (Source_Root.Right);
316 Target_Root.Right.Parent := Target_Root;
317 end if;
319 P := Target_Root;
320 X := Source_Root.Left;
321 while X /= null loop
322 declare
323 Y : Node_Access := Copy_Node (X);
325 begin
326 P.Left := Y;
327 Y.Parent := P;
329 if X.Right /= null then
330 Y.Right := Copy_Tree (X.Right);
331 Y.Right.Parent := Y;
332 end if;
334 P := Y;
335 X := X.Left;
336 end;
337 end loop;
339 return Target_Root;
341 exception
342 when others =>
343 Delete_Tree (Target_Root);
344 raise;
345 end Copy_Tree;
347 ------------
348 -- Delete --
349 ------------
351 procedure Delete (Container : in out Set; Item : Element_Type) is
352 Tree : Tree_Type renames Container.Tree;
353 Node : Node_Access := Element_Keys.Ceiling (Tree, Item);
354 Done : constant Node_Access := Element_Keys.Upper_Bound (Tree, Item);
355 X : Node_Access;
357 begin
358 if Node = Done then
359 raise Constraint_Error;
360 end if;
362 loop
363 X := Node;
364 Node := Tree_Operations.Next (Node);
365 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
366 Free (X);
368 exit when Node = Done;
369 end loop;
370 end Delete;
372 procedure Delete (Container : in out Set; Position : in out Cursor) is
373 begin
374 if Position = No_Element then
375 return;
376 end if;
378 if Position.Container /= Set_Access'(Container'Unchecked_Access) then
379 raise Program_Error;
380 end if;
382 Delete_Node_Sans_Free (Container.Tree, Position.Node);
383 Free (Position.Node);
385 Position.Container := null;
386 end Delete;
388 ------------------
389 -- Delete_First --
390 ------------------
392 procedure Delete_First (Container : in out Set) is
393 Tree : Tree_Type renames Container.Tree;
394 X : Node_Access := Tree.First;
396 begin
397 if X = null then
398 return;
399 end if;
401 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
402 Free (X);
403 end Delete_First;
405 -----------------
406 -- Delete_Last --
407 -----------------
409 procedure Delete_Last (Container : in out Set) is
410 Tree : Tree_Type renames Container.Tree;
411 X : Node_Access := Tree.Last;
413 begin
414 if X = null then
415 return;
416 end if;
418 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
419 Free (X);
420 end Delete_Last;
422 -----------------
423 -- Delete_Tree --
424 -----------------
426 procedure Delete_Tree (X : in out Node_Access) is
427 Y : Node_Access;
428 begin
429 while X /= null loop
430 Y := X.Right;
431 Delete_Tree (Y);
432 Y := X.Left;
433 Free (X);
434 X := Y;
435 end loop;
436 end Delete_Tree;
438 ----------------
439 -- Difference --
440 ----------------
442 procedure Difference (Target : in out Set; Source : Set) is
443 begin
444 if Target'Address = Source'Address then
445 Clear (Target);
446 return;
447 end if;
449 Set_Ops.Difference (Target.Tree, Source.Tree);
450 end Difference;
452 function Difference (Left, Right : Set) return Set is
453 begin
454 if Left'Address = Right'Address then
455 return Empty_Set;
456 end if;
458 declare
459 Tree : constant Tree_Type :=
460 Set_Ops.Difference (Left.Tree, Right.Tree);
461 begin
462 return (Controlled with Tree);
463 end;
464 end Difference;
466 -------------
467 -- Element --
468 -------------
470 function Element (Position : Cursor) return Element_Type is
471 begin
472 return Position.Node.Element.all;
473 end Element;
475 -------------
476 -- Exclude --
477 -------------
479 procedure Exclude (Container : in out Set; Item : Element_Type) is
480 Tree : Tree_Type renames Container.Tree;
481 Node : Node_Access := Element_Keys.Ceiling (Tree, Item);
482 Done : constant Node_Access := Element_Keys.Upper_Bound (Tree, Item);
483 X : Node_Access;
484 begin
485 while Node /= Done loop
486 X := Node;
487 Node := Tree_Operations.Next (Node);
488 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
489 Free (X);
490 end loop;
491 end Exclude;
493 ----------
494 -- Find --
495 ----------
497 function Find (Container : Set; Item : Element_Type) return Cursor is
498 Node : constant Node_Access :=
499 Element_Keys.Find (Container.Tree, Item);
501 begin
502 if Node = null then
503 return No_Element;
504 end if;
506 return Cursor'(Container'Unchecked_Access, Node);
507 end Find;
509 -----------
510 -- First --
511 -----------
513 function First (Container : Set) return Cursor is
514 begin
515 if Container.Tree.First = null then
516 return No_Element;
517 end if;
519 return Cursor'(Container'Unchecked_Access, Container.Tree.First);
520 end First;
522 -------------------
523 -- First_Element --
524 -------------------
526 function First_Element (Container : Set) return Element_Type is
527 begin
528 return Container.Tree.First.Element.all;
529 end First_Element;
531 -----------
532 -- Floor --
533 -----------
535 function Floor (Container : Set; Item : Element_Type) return Cursor is
536 Node : constant Node_Access :=
537 Element_Keys.Floor (Container.Tree, Item);
539 begin
540 if Node = null then
541 return No_Element;
542 end if;
544 return Cursor'(Container'Unchecked_Access, Node);
545 end Floor;
547 ----------
548 -- Free --
549 ----------
551 procedure Free (X : in out Node_Access) is
552 procedure Deallocate is
553 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
554 begin
555 if X /= null then
556 Free_Element (X.Element);
557 Deallocate (X);
558 end if;
559 end Free;
561 ------------------
562 -- Generic_Keys --
563 ------------------
565 package body Generic_Keys is
567 -----------------------
568 -- Local Subprograms --
569 -----------------------
571 function Is_Less_Key_Node
572 (Left : Key_Type;
573 Right : Node_Access) return Boolean;
574 pragma Inline (Is_Less_Key_Node);
576 function Is_Greater_Key_Node
577 (Left : Key_Type;
578 Right : Node_Access) return Boolean;
579 pragma Inline (Is_Greater_Key_Node);
581 --------------------------
582 -- Local Instantiations --
583 --------------------------
585 package Key_Keys is
586 new Red_Black_Trees.Generic_Keys
587 (Tree_Operations => Tree_Operations,
588 Key_Type => Key_Type,
589 Is_Less_Key_Node => Is_Less_Key_Node,
590 Is_Greater_Key_Node => Is_Greater_Key_Node);
592 ---------
593 -- "<" --
594 ---------
596 function "<" (Left : Key_Type; Right : Cursor) return Boolean is
597 begin
598 return Left < Right.Node.Element.all;
599 end "<";
601 function "<" (Left : Cursor; Right : Key_Type) return Boolean is
602 begin
603 return Right > Left.Node.Element.all;
604 end "<";
606 ---------
607 -- ">" --
608 ---------
610 function ">" (Left : Key_Type; Right : Cursor) return Boolean is
611 begin
612 return Left > Right.Node.Element.all;
613 end ">";
615 function ">" (Left : Cursor; Right : Key_Type) return Boolean is
616 begin
617 return Right < Left.Node.Element.all;
618 end ">";
620 -------------
621 -- Ceiling --
622 -------------
624 function Ceiling (Container : Set; Key : Key_Type) return Cursor is
625 Node : constant Node_Access :=
626 Key_Keys.Ceiling (Container.Tree, Key);
628 begin
629 if Node = null then
630 return No_Element;
631 end if;
633 return Cursor'(Container'Unchecked_Access, Node);
634 end Ceiling;
636 ----------------------------
637 -- Checked_Update_Element --
638 ----------------------------
640 procedure Checked_Update_Element
641 (Container : in out Set;
642 Position : Cursor;
643 Process : not null access procedure (Element : in out Element_Type))
645 begin
646 if Position.Container = null then
647 raise Constraint_Error;
648 end if;
650 if Position.Container /= Set_Access'(Container'Unchecked_Access) then
651 raise Program_Error;
652 end if;
654 declare
655 Old_Key : Key_Type renames Key (Position.Node.Element.all);
657 begin
658 Process (Position.Node.Element.all);
660 if Old_Key < Position.Node.Element.all
661 or else Old_Key > Position.Node.Element.all
662 then
663 null;
664 else
665 return;
666 end if;
667 end;
669 Delete_Node_Sans_Free (Container.Tree, Position.Node);
671 Do_Insert : declare
672 Result : Node_Access;
674 function New_Node return Node_Access;
675 pragma Inline (New_Node);
677 procedure Insert_Post is
678 new Key_Keys.Generic_Insert_Post (New_Node);
680 procedure Insert is
681 new Key_Keys.Generic_Unconditional_Insert (Insert_Post);
683 --------------
684 -- New_Node --
685 --------------
687 function New_Node return Node_Access is
688 begin
689 return Position.Node;
690 end New_Node;
692 -- Start of processing for Do_Insert
694 begin
695 Insert
696 (Tree => Container.Tree,
697 Key => Key (Position.Node.Element.all),
698 Node => Result);
700 pragma Assert (Result = Position.Node);
701 end Do_Insert;
702 end Checked_Update_Element;
704 --------------
705 -- Contains --
706 --------------
708 function Contains (Container : Set; Key : Key_Type) return Boolean is
709 begin
710 return Find (Container, Key) /= No_Element;
711 end Contains;
713 ------------
714 -- Delete --
715 ------------
717 procedure Delete (Container : in out Set; Key : Key_Type) is
718 Tree : Tree_Type renames Container.Tree;
719 Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
720 Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
721 X : Node_Access;
723 begin
724 if Node = Done then
725 raise Constraint_Error;
726 end if;
728 loop
729 X := Node;
730 Node := Tree_Operations.Next (Node);
731 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
732 Free (X);
734 exit when Node = Done;
735 end loop;
736 end Delete;
738 -------------
739 -- Element --
740 -------------
742 function Element (Container : Set; Key : Key_Type) return Element_Type is
743 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
744 begin
745 return Node.Element.all;
746 end Element;
748 -------------
749 -- Exclude --
750 -------------
752 procedure Exclude (Container : in out Set; Key : Key_Type) is
753 Tree : Tree_Type renames Container.Tree;
754 Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
755 Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
756 X : Node_Access;
758 begin
759 while Node /= Done loop
760 X := Node;
761 Node := Tree_Operations.Next (Node);
762 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
763 Free (X);
764 end loop;
765 end Exclude;
767 ----------
768 -- Find --
769 ----------
771 function Find (Container : Set; Key : Key_Type) return Cursor is
772 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
774 begin
775 if Node = null then
776 return No_Element;
777 end if;
779 return Cursor'(Container'Unchecked_Access, Node);
780 end Find;
782 -----------
783 -- Floor --
784 -----------
786 function Floor (Container : Set; Key : Key_Type) return Cursor is
787 Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key);
789 begin
790 if Node = null then
791 return No_Element;
792 end if;
794 return Cursor'(Container'Unchecked_Access, Node);
795 end Floor;
797 -------------------------
798 -- Is_Greater_Key_Node --
799 -------------------------
801 function Is_Greater_Key_Node
802 (Left : Key_Type;
803 Right : Node_Access) return Boolean is
804 begin
805 return Left > Right.Element.all;
806 end Is_Greater_Key_Node;
808 ----------------------
809 -- Is_Less_Key_Node --
810 ----------------------
812 function Is_Less_Key_Node
813 (Left : Key_Type;
814 Right : Node_Access) return Boolean is
815 begin
816 return Left < Right.Element.all;
817 end Is_Less_Key_Node;
819 -------------
820 -- Iterate --
821 -------------
823 procedure Iterate
824 (Container : Set;
825 Key : Key_Type;
826 Process : not null access procedure (Position : Cursor))
828 procedure Process_Node (Node : Node_Access);
829 pragma Inline (Process_Node);
831 procedure Local_Iterate is
832 new Key_Keys.Generic_Iteration (Process_Node);
834 ------------------
835 -- Process_Node --
836 ------------------
838 procedure Process_Node (Node : Node_Access) is
839 begin
840 Process (Cursor'(Container'Unchecked_Access, Node));
841 end Process_Node;
843 -- Start of processing for Iterate
845 begin
846 Local_Iterate (Container.Tree, Key);
847 end Iterate;
849 ---------
850 -- Key --
851 ---------
853 function Key (Position : Cursor) return Key_Type is
854 begin
855 return Key (Position.Node.Element.all);
856 end Key;
858 -------------
859 -- Replace --
860 -------------
862 -- In post-madision api: ???
864 -- procedure Replace
865 -- (Container : in out Set;
866 -- Key : Key_Type;
867 -- New_Item : Element_Type)
868 -- is
869 -- Node : Node_Access := Key_Keys.Find (Container.Tree, Key);
871 -- begin
872 -- if Node = null then
873 -- raise Constraint_Error;
874 -- end if;
876 -- Replace_Node (Container, Node, New_Item);
877 -- end Replace;
879 ---------------------
880 -- Reverse_Iterate --
881 ---------------------
883 procedure Reverse_Iterate
884 (Container : Set;
885 Key : Key_Type;
886 Process : not null access procedure (Position : Cursor))
888 procedure Process_Node (Node : Node_Access);
889 pragma Inline (Process_Node);
891 -------------
892 -- Iterate --
893 -------------
895 procedure Local_Reverse_Iterate is
896 new Key_Keys.Generic_Reverse_Iteration (Process_Node);
898 ------------------
899 -- Process_Node --
900 ------------------
902 procedure Process_Node (Node : Node_Access) is
903 begin
904 Process (Cursor'(Container'Unchecked_Access, Node));
905 end Process_Node;
907 -- Start of processing for Reverse_Iterate
909 begin
910 Local_Reverse_Iterate (Container.Tree, Key);
911 end Reverse_Iterate;
913 end Generic_Keys;
915 -----------------
916 -- Has_Element --
917 -----------------
919 function Has_Element (Position : Cursor) return Boolean is
920 begin
921 return Position /= No_Element;
922 end Has_Element;
924 ------------
925 -- Insert --
926 ------------
928 procedure Insert (Container : in out Set; New_Item : Element_Type) is
929 Position : Cursor;
930 begin
931 Insert (Container, New_Item, Position);
932 end Insert;
934 procedure Insert
935 (Container : in out Set;
936 New_Item : Element_Type;
937 Position : out Cursor)
939 function New_Node return Node_Access;
940 pragma Inline (New_Node);
942 procedure Insert_Post is
943 new Element_Keys.Generic_Insert_Post (New_Node);
945 procedure Unconditional_Insert_Sans_Hint is
946 new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
948 --------------
949 -- New_Node --
950 --------------
952 function New_Node return Node_Access is
953 X : Element_Access := new Element_Type'(New_Item);
955 begin
956 return new Node_Type'(Parent => null,
957 Left => null,
958 Right => null,
959 Color => Red,
960 Element => X);
962 exception
963 when others =>
964 Free_Element (X);
965 raise;
966 end New_Node;
968 -- Start of processing for Insert
970 begin
971 Unconditional_Insert_Sans_Hint
972 (Container.Tree,
973 New_Item,
974 Position.Node);
976 Position.Container := Container'Unchecked_Access;
977 end Insert;
979 ----------------------
980 -- Insert_With_Hint --
981 ----------------------
983 procedure Insert_With_Hint
984 (Dst_Tree : in out Tree_Type;
985 Dst_Hint : Node_Access;
986 Src_Node : Node_Access;
987 Dst_Node : out Node_Access)
989 function New_Node return Node_Access;
990 pragma Inline (New_Node);
992 procedure Insert_Post is
993 new Element_Keys.Generic_Insert_Post (New_Node);
995 procedure Insert_Sans_Hint is
996 new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
998 procedure Local_Insert_With_Hint is
999 new Element_Keys.Generic_Unconditional_Insert_With_Hint
1000 (Insert_Post,
1001 Insert_Sans_Hint);
1003 --------------
1004 -- New_Node --
1005 --------------
1007 function New_Node return Node_Access is
1008 X : Element_Access := new Element_Type'(Src_Node.Element.all);
1010 begin
1011 return new Node_Type'(Parent => null,
1012 Left => null,
1013 Right => null,
1014 Color => Red,
1015 Element => X);
1017 exception
1018 when others =>
1019 Free_Element (X);
1020 raise;
1021 end New_Node;
1023 -- Start of processing for Insert_With_Hint
1025 begin
1026 Local_Insert_With_Hint
1027 (Dst_Tree,
1028 Dst_Hint,
1029 Src_Node.Element.all,
1030 Dst_Node);
1031 end Insert_With_Hint;
1033 ------------------
1034 -- Intersection --
1035 ------------------
1037 procedure Intersection (Target : in out Set; Source : Set) is
1038 begin
1039 if Target'Address = Source'Address then
1040 return;
1041 end if;
1043 Set_Ops.Intersection (Target.Tree, Source.Tree);
1044 end Intersection;
1046 function Intersection (Left, Right : Set) return Set is
1047 begin
1048 if Left'Address = Right'Address then
1049 return Left;
1050 end if;
1052 declare
1053 Tree : constant Tree_Type :=
1054 Set_Ops.Intersection (Left.Tree, Right.Tree);
1055 begin
1056 return (Controlled with Tree);
1057 end;
1058 end Intersection;
1060 --------------
1061 -- Is_Empty --
1062 --------------
1064 function Is_Empty (Container : Set) return Boolean is
1065 begin
1066 return Container.Tree.Length = 0;
1067 end Is_Empty;
1069 ------------------------
1070 -- Is_Equal_Node_Node --
1071 ------------------------
1073 function Is_Equal_Node_Node (L, R : Node_Access) return Boolean is
1074 begin
1075 return L.Element.all = R.Element.all;
1076 end Is_Equal_Node_Node;
1078 -----------------------------
1079 -- Is_Greater_Element_Node --
1080 -----------------------------
1082 function Is_Greater_Element_Node
1083 (Left : Element_Type;
1084 Right : Node_Access) return Boolean
1086 begin
1087 -- e > node same as node < e
1089 return Right.Element.all < Left;
1090 end Is_Greater_Element_Node;
1092 --------------------------
1093 -- Is_Less_Element_Node --
1094 --------------------------
1096 function Is_Less_Element_Node
1097 (Left : Element_Type;
1098 Right : Node_Access) return Boolean
1100 begin
1101 return Left < Right.Element.all;
1102 end Is_Less_Element_Node;
1104 -----------------------
1105 -- Is_Less_Node_Node --
1106 -----------------------
1108 function Is_Less_Node_Node (L, R : Node_Access) return Boolean is
1109 begin
1110 return L.Element.all < R.Element.all;
1111 end Is_Less_Node_Node;
1113 ---------------
1114 -- Is_Subset --
1115 ---------------
1117 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean is
1118 begin
1119 if Subset'Address = Of_Set'Address then
1120 return True;
1121 end if;
1123 return Set_Ops.Is_Subset (Subset => Subset.Tree, Of_Set => Of_Set.Tree);
1124 end Is_Subset;
1126 -------------
1127 -- Iterate --
1128 -------------
1130 procedure Iterate
1131 (Container : Set;
1132 Item : Element_Type;
1133 Process : not null access procedure (Position : Cursor))
1135 procedure Process_Node (Node : Node_Access);
1136 pragma Inline (Process_Node);
1138 procedure Local_Iterate is
1139 new Element_Keys.Generic_Iteration (Process_Node);
1141 ------------------
1142 -- Process_Node --
1143 ------------------
1145 procedure Process_Node (Node : Node_Access) is
1146 begin
1147 Process (Cursor'(Container'Unchecked_Access, Node));
1148 end Process_Node;
1150 -- Start of processing for Iterate
1152 begin
1153 Local_Iterate (Container.Tree, Item);
1154 end Iterate;
1156 procedure Iterate
1157 (Container : Set;
1158 Process : not null access procedure (Position : Cursor))
1160 procedure Process_Node (Node : Node_Access);
1161 pragma Inline (Process_Node);
1163 procedure Local_Iterate is
1164 new Tree_Operations.Generic_Iteration (Process_Node);
1166 ------------------
1167 -- Process_Node --
1168 ------------------
1170 procedure Process_Node (Node : Node_Access) is
1171 begin
1172 Process (Cursor'(Container'Unchecked_Access, Node));
1173 end Process_Node;
1175 -- Start of processing for Iterate
1177 begin
1178 Local_Iterate (Container.Tree);
1179 end Iterate;
1181 ----------
1182 -- Last --
1183 ----------
1185 function Last (Container : Set) return Cursor is
1186 begin
1187 if Container.Tree.Last = null then
1188 return No_Element;
1189 end if;
1191 return Cursor'(Container'Unchecked_Access, Container.Tree.Last);
1192 end Last;
1194 ------------------
1195 -- Last_Element --
1196 ------------------
1198 function Last_Element (Container : Set) return Element_Type is
1199 begin
1200 return Container.Tree.Last.Element.all;
1201 end Last_Element;
1203 ----------
1204 -- Left --
1205 ----------
1207 function Left (Node : Node_Access) return Node_Access is
1208 begin
1209 return Node.Left;
1210 end Left;
1212 ------------
1213 -- Length --
1214 ------------
1216 function Length (Container : Set) return Count_Type is
1217 begin
1218 return Container.Tree.Length;
1219 end Length;
1221 ----------
1222 -- Move --
1223 ----------
1225 procedure Move (Target : in out Set; Source : in out Set) is
1226 begin
1227 if Target'Address = Source'Address then
1228 return;
1229 end if;
1231 Move (Target => Target.Tree, Source => Source.Tree);
1232 end Move;
1234 ----------
1235 -- Next --
1236 ----------
1238 function Next (Position : Cursor) return Cursor is
1239 begin
1240 if Position = No_Element then
1241 return No_Element;
1242 end if;
1244 declare
1245 Node : constant Node_Access :=
1246 Tree_Operations.Next (Position.Node);
1248 begin
1249 if Node = null then
1250 return No_Element;
1251 end if;
1253 return Cursor'(Position.Container, Node);
1254 end;
1255 end Next;
1257 procedure Next (Position : in out Cursor) is
1258 begin
1259 Position := Next (Position);
1260 end Next;
1262 -------------
1263 -- Overlap --
1264 -------------
1266 function Overlap (Left, Right : Set) return Boolean is
1267 begin
1268 if Left'Address = Right'Address then
1269 return Left.Tree.Length /= 0;
1270 end if;
1272 return Set_Ops.Overlap (Left.Tree, Right.Tree);
1273 end Overlap;
1275 ------------
1276 -- Parent --
1277 ------------
1279 function Parent (Node : Node_Access) return Node_Access is
1280 begin
1281 return Node.Parent;
1282 end Parent;
1284 --------------
1285 -- Previous --
1286 --------------
1288 function Previous (Position : Cursor) return Cursor is
1289 begin
1290 if Position = No_Element then
1291 return No_Element;
1292 end if;
1294 declare
1295 Node : constant Node_Access :=
1296 Tree_Operations.Previous (Position.Node);
1298 begin
1299 if Node = null then
1300 return No_Element;
1301 end if;
1303 return Cursor'(Position.Container, Node);
1304 end;
1305 end Previous;
1307 procedure Previous (Position : in out Cursor) is
1308 begin
1309 Position := Previous (Position);
1310 end Previous;
1312 -------------------
1313 -- Query_Element --
1314 -------------------
1316 procedure Query_Element
1317 (Position : Cursor;
1318 Process : not null access procedure (Element : Element_Type))
1320 begin
1321 Process (Position.Node.Element.all);
1322 end Query_Element;
1324 ----------
1325 -- Read --
1326 ----------
1328 procedure Read
1329 (Stream : access Root_Stream_Type'Class;
1330 Container : out Set)
1332 N : Count_Type'Base;
1334 function New_Node return Node_Access;
1335 pragma Inline (New_Node);
1337 procedure Local_Read is new Tree_Operations.Generic_Read (New_Node);
1339 --------------
1340 -- New_Node --
1341 --------------
1343 function New_Node return Node_Access is
1344 Node : Node_Access := new Node_Type;
1346 begin
1347 begin
1348 Node.Element := new Element_Type'(Element_Type'Input (Stream));
1349 exception
1350 when others =>
1351 Free (Node);
1352 raise;
1353 end;
1355 return Node;
1356 end New_Node;
1358 -- Start of processing for Read
1360 begin
1361 Clear (Container);
1363 Count_Type'Base'Read (Stream, N);
1364 pragma Assert (N >= 0);
1366 Local_Read (Container.Tree, N);
1367 end Read;
1369 -------------
1370 -- Replace --
1371 -------------
1373 -- NOTE: from post-madison api???
1375 -- procedure Replace
1376 -- (Container : in out Set;
1377 -- Position : Cursor;
1378 -- By : Element_Type)
1379 -- is
1380 -- begin
1381 -- if Position.Container = null then
1382 -- raise Constraint_Error;
1383 -- end if;
1385 -- if Position.Container /= Set_Access'(Container'Unchecked_Access) then
1386 -- raise Program_Error;
1387 -- end if;
1389 -- Replace_Node (Container, Position.Node, By);
1390 -- end Replace;
1392 ------------------
1393 -- Replace_Node --
1394 ------------------
1396 -- NOTE: from post-madison api???
1398 -- procedure Replace_Node
1399 -- (Container : in out Set;
1400 -- Position : Node_Access;
1401 -- By : Element_Type);
1402 -- is
1403 -- Tree : Tree_Type renames Container.Tree;
1404 -- Node : Node_Access := Position;
1406 -- begin
1407 -- if By < Node.Element
1408 -- or else Node.Element < By
1409 -- then
1410 -- null;
1412 -- else
1413 -- begin
1414 -- Node.Element := By;
1416 -- exception
1417 -- when others =>
1418 -- Tree_Operations.Delete_Node_Sans_Free (Tree, Node);
1419 -- Free (Node);
1420 -- raise;
1421 -- end;
1423 -- return;
1424 -- end if;
1426 -- Tree_Operations.Delete_Node_Sans_Free (Tree, Node);
1428 -- begin
1429 -- Node.Element := By;
1431 -- exception
1432 -- when others =>
1433 -- Free (Node);
1434 -- raise;
1435 -- end;
1437 -- declare
1438 -- Result : Node_Access;
1439 -- Success : Boolean;
1441 -- function New_Node return Node_Access;
1442 -- pragma Inline (New_Node);
1444 -- procedure Insert_Post is
1445 -- new Element_Keys.Generic_Insert_Post (New_Node);
1447 -- procedure Insert is
1448 -- new Element_Keys.Generic_Conditional_Insert (Insert_Post);
1450 -- --------------
1451 -- -- New_Node --
1452 -- --------------
1454 -- function New_Node return Node_Access is
1455 -- begin
1456 -- return Node;
1457 -- end New_Node;
1459 -- -- Start of processing for Replace_Node
1461 -- begin
1462 -- Insert
1463 -- (Tree => Tree,
1464 -- Key => Node.Element,
1465 -- Node => Result,
1466 -- Success => Success);
1468 -- if not Success then
1469 -- Free (Node);
1470 -- raise Program_Error;
1471 -- end if;
1473 -- pragma Assert (Result = Node);
1474 -- end;
1475 -- end Replace_Node;
1477 ---------------------
1478 -- Reverse_Iterate --
1479 ---------------------
1481 procedure Reverse_Iterate
1482 (Container : Set;
1483 Item : Element_Type;
1484 Process : not null access procedure (Position : Cursor))
1486 procedure Process_Node (Node : Node_Access);
1487 pragma Inline (Process_Node);
1489 procedure Local_Reverse_Iterate is
1490 new Element_Keys.Generic_Reverse_Iteration (Process_Node);
1492 ------------------
1493 -- Process_Node --
1494 ------------------
1496 procedure Process_Node (Node : Node_Access) is
1497 begin
1498 Process (Cursor'(Container'Unchecked_Access, Node));
1499 end Process_Node;
1501 -- Start of processing for Reverse_Iterate
1503 begin
1504 Local_Reverse_Iterate (Container.Tree, Item);
1505 end Reverse_Iterate;
1507 procedure Reverse_Iterate
1508 (Container : Set;
1509 Process : not null access procedure (Position : Cursor))
1511 procedure Process_Node (Node : Node_Access);
1512 pragma Inline (Process_Node);
1514 procedure Local_Reverse_Iterate is
1515 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1517 ------------------
1518 -- Process_Node --
1519 ------------------
1521 procedure Process_Node (Node : Node_Access) is
1522 begin
1523 Process (Cursor'(Container'Unchecked_Access, Node));
1524 end Process_Node;
1526 -- Start of processing for Reverse_Iterate
1528 begin
1529 Local_Reverse_Iterate (Container.Tree);
1530 end Reverse_Iterate;
1532 -----------
1533 -- Right --
1534 -----------
1536 function Right (Node : Node_Access) return Node_Access is
1537 begin
1538 return Node.Right;
1539 end Right;
1541 ---------------
1542 -- Set_Color --
1543 ---------------
1545 procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1546 begin
1547 Node.Color := Color;
1548 end Set_Color;
1550 --------------
1551 -- Set_Left --
1552 --------------
1554 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1555 begin
1556 Node.Left := Left;
1557 end Set_Left;
1559 ----------------
1560 -- Set_Parent --
1561 ----------------
1563 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1564 begin
1565 Node.Parent := Parent;
1566 end Set_Parent;
1568 ---------------
1569 -- Set_Right --
1570 ---------------
1572 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1573 begin
1574 Node.Right := Right;
1575 end Set_Right;
1577 --------------------------
1578 -- Symmetric_Difference --
1579 --------------------------
1581 procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1582 begin
1583 if Target'Address = Source'Address then
1584 Clear (Target);
1585 return;
1586 end if;
1588 Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1589 end Symmetric_Difference;
1591 function Symmetric_Difference (Left, Right : Set) return Set is
1592 begin
1593 if Left'Address = Right'Address then
1594 return Empty_Set;
1595 end if;
1597 declare
1598 Tree : constant Tree_Type :=
1599 Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1600 begin
1601 return (Controlled with Tree);
1602 end;
1603 end Symmetric_Difference;
1605 -----------
1606 -- Union --
1607 -----------
1609 procedure Union (Target : in out Set; Source : Set) is
1610 begin
1611 if Target'Address = Source'Address then
1612 return;
1613 end if;
1615 Set_Ops.Union (Target.Tree, Source.Tree);
1616 end Union;
1618 function Union (Left, Right : Set) return Set is begin
1619 if Left'Address = Right'Address then
1620 return Left;
1621 end if;
1623 declare
1624 Tree : constant Tree_Type := Set_Ops.Union (Left.Tree, Right.Tree);
1625 begin
1626 return (Controlled with Tree);
1627 end;
1628 end Union;
1630 -----------
1631 -- Write --
1632 -----------
1634 procedure Write
1635 (Stream : access Root_Stream_Type'Class;
1636 Container : Set)
1638 procedure Process (Node : Node_Access);
1639 pragma Inline (Process);
1641 procedure Iterate is new Tree_Operations.Generic_Iteration (Process);
1643 -------------
1644 -- Process --
1645 -------------
1647 procedure Process (Node : Node_Access) is
1648 begin
1649 Element_Type'Output (Stream, Node.Element.all);
1650 end Process;
1652 -- Start of processing for Write
1654 begin
1655 Count_Type'Base'Write (Stream, Container.Tree.Length);
1656 Iterate (Container.Tree);
1657 end Write;
1659 end Ada.Containers.Indefinite_Ordered_Multisets;