1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . O R D E R E D _ M U L T I S E T S --
9 -- Copyright (C) 2004-2005 Free Software Foundation, Inc. --
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. --
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, 51 Franklin Street, Fifth Floor, --
24 -- Boston, MA 02110-1301, USA. --
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. --
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 package body Ada
.Containers
.Ordered_Multisets
is
49 -----------------------------
50 -- Node Access Subprograms --
51 -----------------------------
53 -- These subprograms provide a functional interface to access fields
54 -- of a node, and a procedural interface for modifying these values.
56 function Color
(Node
: Node_Access
) return Color_Type
;
57 pragma Inline
(Color
);
59 function Left
(Node
: Node_Access
) return Node_Access
;
62 function Parent
(Node
: Node_Access
) return Node_Access
;
63 pragma Inline
(Parent
);
65 function Right
(Node
: Node_Access
) return Node_Access
;
66 pragma Inline
(Right
);
68 procedure Set_Parent
(Node
: Node_Access
; Parent
: Node_Access
);
69 pragma Inline
(Set_Parent
);
71 procedure Set_Left
(Node
: Node_Access
; Left
: Node_Access
);
72 pragma Inline
(Set_Left
);
74 procedure Set_Right
(Node
: Node_Access
; Right
: Node_Access
);
75 pragma Inline
(Set_Right
);
77 procedure Set_Color
(Node
: Node_Access
; Color
: Color_Type
);
78 pragma Inline
(Set_Color
);
80 -----------------------
81 -- Local Subprograms --
82 -----------------------
84 function Copy_Node
(Source
: Node_Access
) return Node_Access
;
85 pragma Inline
(Copy_Node
);
87 procedure Insert_With_Hint
88 (Dst_Tree
: in out Tree_Type
;
89 Dst_Hint
: Node_Access
;
90 Src_Node
: Node_Access
;
91 Dst_Node
: out Node_Access
);
93 function Is_Equal_Node_Node
(L
, R
: Node_Access
) return Boolean;
94 pragma Inline
(Is_Equal_Node_Node
);
96 function Is_Greater_Element_Node
98 Right
: Node_Access
) return Boolean;
99 pragma Inline
(Is_Greater_Element_Node
);
101 function Is_Less_Element_Node
102 (Left
: Element_Type
;
103 Right
: Node_Access
) return Boolean;
104 pragma Inline
(Is_Less_Element_Node
);
106 function Is_Less_Node_Node
(L
, R
: Node_Access
) return Boolean;
107 pragma Inline
(Is_Less_Node_Node
);
109 procedure Replace_Element
110 (Tree
: in out Tree_Type
;
112 Item
: Element_Type
);
114 --------------------------
115 -- Local Instantiations --
116 --------------------------
119 new Ada
.Unchecked_Deallocation
(Node_Type
, Node_Access
);
121 package Tree_Operations
is
122 new Red_Black_Trees
.Generic_Operations
(Tree_Types
);
124 procedure Delete_Tree
is
125 new Tree_Operations
.Generic_Delete_Tree
(Free
);
127 function Copy_Tree
is
128 new Tree_Operations
.Generic_Copy_Tree
(Copy_Node
, Delete_Tree
);
133 new Tree_Operations
.Generic_Equal
(Is_Equal_Node_Node
);
135 package Element_Keys
is
136 new Red_Black_Trees
.Generic_Keys
137 (Tree_Operations
=> Tree_Operations
,
138 Key_Type
=> Element_Type
,
139 Is_Less_Key_Node
=> Is_Less_Element_Node
,
140 Is_Greater_Key_Node
=> Is_Greater_Element_Node
);
143 new Generic_Set_Operations
144 (Tree_Operations
=> Tree_Operations
,
145 Insert_With_Hint
=> Insert_With_Hint
,
146 Copy_Tree
=> Copy_Tree
,
147 Delete_Tree
=> Delete_Tree
,
148 Is_Less
=> Is_Less_Node_Node
,
155 function "<" (Left
, Right
: Cursor
) return Boolean is
157 return Left
.Node
.Element
< Right
.Node
.Element
;
160 function "<" (Left
: Cursor
; Right
: Element_Type
)
163 return Left
.Node
.Element
< Right
;
166 function "<" (Left
: Element_Type
; Right
: Cursor
)
169 return Left
< Right
.Node
.Element
;
176 function "=" (Left
, Right
: Set
) return Boolean is
178 return Is_Equal
(Left
.Tree
, Right
.Tree
);
185 function ">" (Left
, Right
: Cursor
) return Boolean is
187 -- L > R same as R < L
189 return Right
.Node
.Element
< Left
.Node
.Element
;
192 function ">" (Left
: Cursor
; Right
: Element_Type
)
195 return Right
< Left
.Node
.Element
;
198 function ">" (Left
: Element_Type
; Right
: Cursor
)
201 return Right
.Node
.Element
< Left
;
209 new Tree_Operations
.Generic_Adjust
(Copy_Tree
);
211 procedure Adjust
(Container
: in out Set
) is
213 Adjust
(Container
.Tree
);
220 function Ceiling
(Container
: Set
; Item
: Element_Type
) return Cursor
is
221 Node
: constant Node_Access
:=
222 Element_Keys
.Ceiling
(Container
.Tree
, Item
);
229 return Cursor
'(Container'Unrestricted_Access, Node);
237 new Tree_Operations.Generic_Clear (Delete_Tree);
239 procedure Clear (Container : in out Set) is
241 Clear (Container.Tree);
248 function Color (Node : Node_Access) return Color_Type is
257 function Contains (Container : Set; Item : Element_Type) return Boolean is
259 return Find (Container, Item) /= No_Element;
266 function Copy_Node (Source : Node_Access) return Node_Access is
267 Target : constant Node_Access :=
268 new Node_Type'(Parent
=> null,
271 Color
=> Source
.Color
,
272 Element
=> Source
.Element
);
281 procedure Delete
(Container
: in out Set
; Item
: Element_Type
) is
282 Tree
: Tree_Type
renames Container
.Tree
;
283 Node
: Node_Access
:= Element_Keys
.Ceiling
(Tree
, Item
);
284 Done
: constant Node_Access
:= Element_Keys
.Upper_Bound
(Tree
, Item
);
289 raise Constraint_Error
;
294 Node
:= Tree_Operations
.Next
(Node
);
295 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, X
);
298 exit when Node
= Done
;
302 procedure Delete
(Container
: in out Set
; Position
: in out Cursor
) is
304 if Position
.Node
= null then
305 raise Constraint_Error
;
308 if Position
.Container
/= Container
'Unrestricted_Access then
312 Delete_Node_Sans_Free
(Container
.Tree
, Position
.Node
);
313 Free
(Position
.Node
);
315 Position
.Container
:= null;
322 procedure Delete_First
(Container
: in out Set
) is
323 Tree
: Tree_Type
renames Container
.Tree
;
324 X
: Node_Access
:= Tree
.First
;
331 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, X
);
339 procedure Delete_Last
(Container
: in out Set
) is
340 Tree
: Tree_Type
renames Container
.Tree
;
341 X
: Node_Access
:= Tree
.Last
;
348 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, X
);
356 procedure Difference
(Target
: in out Set
; Source
: Set
) is
358 Set_Ops
.Difference
(Target
.Tree
, Source
.Tree
);
361 function Difference
(Left
, Right
: Set
) return Set
is
362 Tree
: constant Tree_Type
:=
363 Set_Ops
.Difference
(Left
.Tree
, Right
.Tree
);
365 return Set
'(Controlled with Tree);
372 function Element (Position : Cursor) return Element_Type is
374 return Position.Node.Element;
377 ---------------------
378 -- Equivalent_Sets --
379 ---------------------
381 function Equivalent_Sets (Left, Right : Set) return Boolean is
383 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean;
384 pragma Inline (Is_Equivalent_Node_Node);
386 function Is_Equivalent is
387 new Tree_Operations.Generic_Equal (Is_Equivalent_Node_Node);
389 -----------------------------
390 -- Is_Equivalent_Node_Node --
391 -----------------------------
393 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean is
395 if L.Element < R.Element then
397 elsif R.Element < L.Element then
402 end Is_Equivalent_Node_Node;
404 -- Start of processing for Equivalent_Sets
407 return Is_Equivalent (Left.Tree, Right.Tree);
414 procedure Exclude (Container : in out Set; Item : Element_Type) is
415 Tree : Tree_Type renames Container.Tree;
416 Node : Node_Access := Element_Keys.Ceiling (Tree, Item);
417 Done : constant Node_Access := Element_Keys.Upper_Bound (Tree, Item);
420 while Node /= Done loop
422 Node := Tree_Operations.Next (Node);
423 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
432 function Find (Container : Set; Item : Element_Type) return Cursor is
433 Node : constant Node_Access :=
434 Element_Keys.Find (Container.Tree, Item);
441 return Cursor'(Container
'Unrestricted_Access, Node
);
448 function First
(Container
: Set
) return Cursor
is
450 if Container
.Tree
.First
= null then
454 return Cursor
'(Container'Unrestricted_Access, Container.Tree.First);
461 function First_Element (Container : Set) return Element_Type is
463 return Container.Tree.First.Element;
470 function Floor (Container : Set; Item : Element_Type) return Cursor is
471 Node : constant Node_Access :=
472 Element_Keys.Floor (Container.Tree, Item);
479 return Cursor'(Container
'Unrestricted_Access, Node
);
486 package body Generic_Keys
is
488 -----------------------
489 -- Local Subprograms --
490 -----------------------
492 function Is_Greater_Key_Node
494 Right
: Node_Access
) return Boolean;
495 pragma Inline
(Is_Greater_Key_Node
);
497 function Is_Less_Key_Node
499 Right
: Node_Access
) return Boolean;
500 pragma Inline
(Is_Less_Key_Node
);
502 --------------------------
503 -- Local_Instantiations --
504 --------------------------
507 new Red_Black_Trees
.Generic_Keys
508 (Tree_Operations
=> Tree_Operations
,
509 Key_Type
=> Key_Type
,
510 Is_Less_Key_Node
=> Is_Less_Key_Node
,
511 Is_Greater_Key_Node
=> Is_Greater_Key_Node
);
517 function "<" (Left
: Key_Type
; Right
: Cursor
) return Boolean is
519 return Left
< Right
.Node
.Element
;
522 function "<" (Left
: Cursor
; Right
: Key_Type
) return Boolean is
524 return Right
> Left
.Node
.Element
;
531 function ">" (Left
: Cursor
; Right
: Key_Type
) return Boolean is
533 return Right
< Left
.Node
.Element
;
536 function ">" (Left
: Key_Type
; Right
: Cursor
) return Boolean is
538 return Left
> Right
.Node
.Element
;
545 function Ceiling
(Container
: Set
; Key
: Key_Type
) return Cursor
is
546 Node
: constant Node_Access
:=
547 Key_Keys
.Ceiling
(Container
.Tree
, Key
);
554 return Cursor
'(Container'Unrestricted_Access, Node);
561 function Contains (Container : Set; Key : Key_Type) return Boolean is
563 return Find (Container, Key) /= No_Element;
570 procedure Delete (Container : in out Set; Key : Key_Type) is
571 Tree : Tree_Type renames Container.Tree;
572 Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
573 Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
578 raise Constraint_Error;
583 Node := Tree_Operations.Next (Node);
584 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
587 exit when Node = Done;
595 function Element (Container : Set; Key : Key_Type) return Element_Type is
596 Node : constant Node_Access :=
597 Key_Keys.Find (Container.Tree, Key);
606 procedure Exclude (Container : in out Set; Key : Key_Type) is
607 Tree : Tree_Type renames Container.Tree;
608 Node : Node_Access := Key_Keys.Ceiling (Tree, Key);
609 Done : constant Node_Access := Key_Keys.Upper_Bound (Tree, Key);
612 while Node /= Done loop
614 Node := Tree_Operations.Next (Node);
615 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
624 function Find (Container : Set; Key : Key_Type) return Cursor is
625 Node : constant Node_Access :=
626 Key_Keys.Find (Container.Tree, Key);
633 return Cursor'(Container
'Unrestricted_Access, Node
);
640 function Floor
(Container
: Set
; Key
: Key_Type
) return Cursor
is
641 Node
: constant Node_Access
:=
642 Key_Keys
.Floor
(Container
.Tree
, Key
);
649 return Cursor
'(Container'Unrestricted_Access, Node);
652 -------------------------
653 -- Is_Greater_Key_Node --
654 -------------------------
656 function Is_Greater_Key_Node
658 Right : Node_Access) return Boolean is
660 return Left > Right.Element;
661 end Is_Greater_Key_Node;
663 ----------------------
664 -- Is_Less_Key_Node --
665 ----------------------
667 function Is_Less_Key_Node
669 Right : Node_Access) return Boolean is
671 return Left < Right.Element;
672 end Is_Less_Key_Node;
681 Process : not null access procedure (Position : Cursor))
683 procedure Process_Node (Node : Node_Access);
684 pragma Inline (Process_Node);
686 procedure Local_Iterate is
687 new Key_Keys.Generic_Iteration (Process_Node);
693 procedure Process_Node (Node : Node_Access) is
695 Process (Cursor'(Container
'Unrestricted_Access, Node
));
698 T
: Tree_Type
renames Container
.Tree
'Unrestricted_Access.all;
699 B
: Natural renames T
.Busy
;
701 -- Start of processing for Iterate
707 Local_Iterate
(T
, Key
);
721 function Key
(Position
: Cursor
) return Key_Type
is
723 return Key
(Position
.Node
.Element
);
726 ---------------------
727 -- Reverse_Iterate --
728 ---------------------
730 procedure Reverse_Iterate
733 Process
: not null access procedure (Position
: Cursor
))
735 procedure Process_Node
(Node
: Node_Access
);
736 pragma Inline
(Process_Node
);
738 procedure Local_Reverse_Iterate
is
739 new Key_Keys
.Generic_Reverse_Iteration
(Process_Node
);
745 procedure Process_Node
(Node
: Node_Access
) is
747 Process
(Cursor
'(Container'Unrestricted_Access, Node));
750 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
751 B : Natural renames T.Busy;
753 -- Start of processing for Reverse_Iterate
759 Local_Reverse_Iterate (T, Key);
769 -----------------------------------
770 -- Update_Element_Preserving_Key --
771 -----------------------------------
773 procedure Update_Element_Preserving_Key
774 (Container : in out Set;
776 Process : not null access procedure (Element : in out Element_Type))
778 Tree : Tree_Type renames Container.Tree;
781 if Position.Node = null then
782 raise Constraint_Error;
785 if Position.Container /= Container'Unrestricted_Access then
790 E : Element_Type renames Position.Node.Element;
791 K : Key_Type renames Key (E);
793 B : Natural renames Tree.Busy;
794 L : Natural renames Tree.Lock;
822 X : Node_Access := Position.Node;
824 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
829 end Update_Element_Preserving_Key;
837 function Has_Element (Position : Cursor) return Boolean is
839 return Position /= No_Element;
846 procedure Insert (Container : in out Set; New_Item : Element_Type) is
849 Insert (Container, New_Item, Position);
853 (Container : in out Set;
854 New_Item : Element_Type;
855 Position : out Cursor)
857 function New_Node return Node_Access;
858 pragma Inline (New_Node);
860 procedure Insert_Post is
861 new Element_Keys.Generic_Insert_Post (New_Node);
863 procedure Unconditional_Insert_Sans_Hint is
864 new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
870 function New_Node return Node_Access is
871 Node : constant Node_Access :=
872 new Node_Type'(Parent
=> null,
876 Element
=> New_Item
);
881 -- Start of processing for Insert
884 Unconditional_Insert_Sans_Hint
889 Position
.Container
:= Container
'Unrestricted_Access;
892 ----------------------
893 -- Insert_With_Hint --
894 ----------------------
896 procedure Insert_With_Hint
897 (Dst_Tree
: in out Tree_Type
;
898 Dst_Hint
: Node_Access
;
899 Src_Node
: Node_Access
;
900 Dst_Node
: out Node_Access
)
902 function New_Node
return Node_Access
;
903 pragma Inline
(New_Node
);
905 procedure Insert_Post
is
906 new Element_Keys
.Generic_Insert_Post
(New_Node
);
908 procedure Insert_Sans_Hint
is
909 new Element_Keys
.Generic_Unconditional_Insert
(Insert_Post
);
911 procedure Local_Insert_With_Hint
is
912 new Element_Keys
.Generic_Unconditional_Insert_With_Hint
920 function New_Node
return Node_Access
is
921 Node
: constant Node_Access
:=
922 new Node_Type
'(Parent => null,
926 Element => Src_Node.Element);
931 -- Start of processing for Insert_With_Hint
934 Local_Insert_With_Hint
939 end Insert_With_Hint;
945 procedure Intersection (Target : in out Set; Source : Set) is
947 Set_Ops.Intersection (Target.Tree, Source.Tree);
950 function Intersection (Left, Right : Set) return Set is
951 Tree : constant Tree_Type :=
952 Set_Ops.Intersection (Left.Tree, Right.Tree);
954 return Set'(Controlled
with Tree
);
961 function Is_Empty
(Container
: Set
) return Boolean is
963 return Container
.Tree
.Length
= 0;
966 ------------------------
967 -- Is_Equal_Node_Node --
968 ------------------------
970 function Is_Equal_Node_Node
(L
, R
: Node_Access
) return Boolean is
972 return L
.Element
= R
.Element
;
973 end Is_Equal_Node_Node
;
975 -----------------------------
976 -- Is_Greater_Element_Node --
977 -----------------------------
979 function Is_Greater_Element_Node
980 (Left
: Element_Type
;
981 Right
: Node_Access
) return Boolean
984 -- e > node same as node < e
986 return Right
.Element
< Left
;
987 end Is_Greater_Element_Node
;
989 --------------------------
990 -- Is_Less_Element_Node --
991 --------------------------
993 function Is_Less_Element_Node
994 (Left
: Element_Type
;
995 Right
: Node_Access
) return Boolean
998 return Left
< Right
.Element
;
999 end Is_Less_Element_Node
;
1001 -----------------------
1002 -- Is_Less_Node_Node --
1003 -----------------------
1005 function Is_Less_Node_Node
(L
, R
: Node_Access
) return Boolean is
1007 return L
.Element
< R
.Element
;
1008 end Is_Less_Node_Node
;
1014 function Is_Subset
(Subset
: Set
; Of_Set
: Set
) return Boolean is
1016 return Set_Ops
.Is_Subset
(Subset
=> Subset
.Tree
, Of_Set
=> Of_Set
.Tree
);
1025 Process
: not null access procedure (Position
: Cursor
))
1027 procedure Process_Node
(Node
: Node_Access
);
1028 pragma Inline
(Process_Node
);
1030 procedure Local_Iterate
is
1031 new Tree_Operations
.Generic_Iteration
(Process_Node
);
1037 procedure Process_Node
(Node
: Node_Access
) is
1039 Process
(Cursor
'(Container'Unrestricted_Access, Node));
1042 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1043 B : Natural renames T.Busy;
1045 -- Start of processing for Iterate
1063 Item : Element_Type;
1064 Process : not null access procedure (Position : Cursor))
1066 procedure Process_Node (Node : Node_Access);
1067 pragma Inline (Process_Node);
1069 procedure Local_Iterate is
1070 new Element_Keys.Generic_Iteration (Process_Node);
1076 procedure Process_Node (Node : Node_Access) is
1078 Process (Cursor'(Container
'Unrestricted_Access, Node
));
1081 T
: Tree_Type
renames Container
.Tree
'Unrestricted_Access.all;
1082 B
: Natural renames T
.Busy
;
1084 -- Start of processing for Iterate
1090 Local_Iterate
(T
, Item
);
1104 function Last
(Container
: Set
) return Cursor
is
1106 if Container
.Tree
.Last
= null then
1110 return Cursor
'(Container'Unrestricted_Access, Container.Tree.Last);
1117 function Last_Element (Container : Set) return Element_Type is
1119 return Container.Tree.Last.Element;
1126 function Left (Node : Node_Access) return Node_Access is
1135 function Length (Container : Set) return Count_Type is
1137 return Container.Tree.Length;
1145 new Tree_Operations.Generic_Move (Clear);
1147 procedure Move (Target : in out Set; Source : in out Set) is
1149 Move (Target => Target.Tree, Source => Source.Tree);
1156 procedure Next (Position : in out Cursor)
1159 Position := Next (Position);
1162 function Next (Position : Cursor) return Cursor is
1164 if Position = No_Element then
1169 Node : constant Node_Access :=
1170 Tree_Operations.Next (Position.Node);
1176 return Cursor'(Position
.Container
, Node
);
1184 function Overlap
(Left
, Right
: Set
) return Boolean is
1186 return Set_Ops
.Overlap
(Left
.Tree
, Right
.Tree
);
1193 function Parent
(Node
: Node_Access
) return Node_Access
is
1202 procedure Previous
(Position
: in out Cursor
)
1205 Position
:= Previous
(Position
);
1208 function Previous
(Position
: Cursor
) return Cursor
is
1210 if Position
= No_Element
then
1215 Node
: constant Node_Access
:=
1216 Tree_Operations
.Previous
(Position
.Node
);
1222 return Cursor
'(Position.Container, Node);
1230 procedure Query_Element
1232 Process : not null access procedure (Element : Element_Type))
1234 E : Element_Type renames Position.Node.Element;
1236 S : Set renames Position.Container.all;
1237 T : Tree_Type renames S.Tree'Unrestricted_Access.all;
1239 B : Natural renames T.Busy;
1240 L : Natural renames T.Lock;
1264 (Stream : access Root_Stream_Type'Class;
1265 Container : out Set)
1268 (Stream : access Root_Stream_Type'Class) return Node_Access;
1269 pragma Inline (Read_Node);
1272 new Tree_Operations.Generic_Read (Clear, Read_Node);
1279 (Stream : access Root_Stream_Type'Class) return Node_Access
1281 Node : Node_Access := new Node_Type;
1283 Element_Type'Read (Stream, Node.Element);
1287 Free (Node); -- Note that Free deallocates elem too
1291 -- Start of processing for Read
1294 Read (Stream, Container.Tree);
1297 ---------------------
1298 -- Replace_Element --
1299 ---------------------
1301 procedure Replace_Element
1302 (Tree : in out Tree_Type;
1304 Item : Element_Type)
1307 if Item < Node.Element
1308 or else Node.Element < Item
1312 if Tree.Lock > 0 then
1313 raise Program_Error;
1316 Node.Element := Item;
1320 Tree_Operations.Delete_Node_Sans_Free (Tree, Node); -- Checks busy-bit
1322 Insert_New_Item : declare
1323 function New_Node return Node_Access;
1324 pragma Inline (New_Node);
1326 procedure Insert_Post is
1327 new Element_Keys.Generic_Insert_Post (New_Node);
1329 procedure Unconditional_Insert is
1330 new Element_Keys.Generic_Unconditional_Insert (Insert_Post);
1336 function New_Node return Node_Access is
1338 Node.Element := Item;
1342 Result : Node_Access;
1344 -- Start of processing for Insert_New_Item
1347 Unconditional_Insert
1352 pragma Assert (Result = Node);
1353 end Insert_New_Item;
1354 end Replace_Element;
1356 procedure Replace_Element
1361 Tree : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1364 if Position.Node = null then
1365 raise Constraint_Error;
1368 if Position.Container /= Container'Unrestricted_Access then
1369 raise Program_Error;
1372 Replace_Element (Tree, Position.Node, By);
1373 end Replace_Element;
1375 ---------------------
1376 -- Reverse_Iterate --
1377 ---------------------
1379 procedure Reverse_Iterate
1381 Process : not null access procedure (Position : Cursor))
1383 procedure Process_Node (Node : Node_Access);
1384 pragma Inline (Process_Node);
1386 procedure Local_Reverse_Iterate is
1387 new Tree_Operations.Generic_Reverse_Iteration (Process_Node);
1393 procedure Process_Node (Node : Node_Access) is
1395 Process (Cursor'(Container
'Unrestricted_Access, Node
));
1398 T
: Tree_Type
renames Container
.Tree
'Unrestricted_Access.all;
1399 B
: Natural renames T
.Busy
;
1401 -- Start of processing for Reverse_Iterate
1407 Local_Reverse_Iterate
(T
);
1415 end Reverse_Iterate
;
1417 procedure Reverse_Iterate
1419 Item
: Element_Type
;
1420 Process
: not null access procedure (Position
: Cursor
))
1422 procedure Process_Node
(Node
: Node_Access
);
1423 pragma Inline
(Process_Node
);
1425 procedure Local_Reverse_Iterate
is
1426 new Element_Keys
.Generic_Reverse_Iteration
(Process_Node
);
1432 procedure Process_Node
(Node
: Node_Access
) is
1434 Process
(Cursor
'(Container'Unrestricted_Access, Node));
1437 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1438 B : Natural renames T.Busy;
1440 -- Start of processing for Reverse_Iterate
1446 Local_Reverse_Iterate (T, Item);
1454 end Reverse_Iterate;
1460 function Right (Node : Node_Access) return Node_Access is
1469 procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1471 Node.Color := Color;
1478 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1487 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1489 Node.Parent := Parent;
1496 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1498 Node.Right := Right;
1501 --------------------------
1502 -- Symmetric_Difference --
1503 --------------------------
1505 procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1507 Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1508 end Symmetric_Difference;
1510 function Symmetric_Difference (Left, Right : Set) return Set is
1511 Tree : constant Tree_Type :=
1512 Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1514 return Set'(Controlled
with Tree
);
1515 end Symmetric_Difference
;
1521 procedure Union
(Target
: in out Set
; Source
: Set
) is
1523 Set_Ops
.Union
(Target
.Tree
, Source
.Tree
);
1526 function Union
(Left
, Right
: Set
) return Set
is
1527 Tree
: constant Tree_Type
:=
1528 Set_Ops
.Union
(Left
.Tree
, Right
.Tree
);
1530 return Set
'(Controlled with Tree);
1538 (Stream : access Root_Stream_Type'Class;
1541 procedure Write_Node
1542 (Stream : access Root_Stream_Type'Class;
1543 Node : Node_Access);
1544 pragma Inline (Write_Node);
1547 new Tree_Operations.Generic_Write (Write_Node);
1553 procedure Write_Node
1554 (Stream : access Root_Stream_Type'Class;
1558 Element_Type'Write (Stream, Node.Element);
1561 -- Start of processing for Write
1564 Write (Stream, Container.Tree);
1567 end Ada.Containers.Ordered_Multisets;