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 _ 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_Sets
is
49 ------------------------------
50 -- Access to Fields of Node --
51 ------------------------------
53 -- These subprograms provide functional notation for access to fields
54 -- of a node, and procedural notation for modifiying these fields.
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_Color
(Node
: Node_Access
; Color
: Color_Type
);
69 pragma Inline
(Set_Color
);
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_Parent
(Node
: Node_Access
; Parent
: Node_Access
);
78 pragma Inline
(Set_Parent
);
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
) return Boolean is
162 return Left
.Node
.Element
< Right
;
165 function "<" (Left
: Element_Type
; Right
: Cursor
) return Boolean is
167 return Left
< Right
.Node
.Element
;
174 function "=" (Left
, Right
: Set
) return Boolean is
176 return Is_Equal
(Left
.Tree
, Right
.Tree
);
183 function ">" (Left
, Right
: Cursor
) return Boolean is
185 -- L > R same as R < L
187 return Right
.Node
.Element
< Left
.Node
.Element
;
190 function ">" (Left
: Element_Type
; Right
: Cursor
) return Boolean is
192 return Right
.Node
.Element
< Left
;
195 function ">" (Left
: Cursor
; Right
: Element_Type
) return Boolean is
197 return Right
< Left
.Node
.Element
;
205 new Tree_Operations
.Generic_Adjust
(Copy_Tree
);
207 procedure Adjust
(Container
: in out Set
) is
209 Adjust
(Container
.Tree
);
216 function Ceiling
(Container
: Set
; Item
: Element_Type
) return Cursor
is
217 Node
: constant Node_Access
:=
218 Element_Keys
.Ceiling
(Container
.Tree
, Item
);
225 return Cursor
'(Container'Unrestricted_Access, Node);
233 new Tree_Operations.Generic_Clear (Delete_Tree);
235 procedure Clear (Container : in out Set) is
237 Clear (Container.Tree);
244 function Color (Node : Node_Access) return Color_Type is
255 Item : Element_Type) return Boolean
258 return Find (Container, Item) /= No_Element;
265 function Copy_Node (Source : Node_Access) return Node_Access is
266 Target : constant Node_Access :=
267 new Node_Type'(Parent
=> null,
270 Color
=> Source
.Color
,
271 Element
=> Source
.Element
);
280 procedure Delete
(Container
: in out Set
; Position
: in out Cursor
) is
282 if Position
.Node
= null then
283 raise Constraint_Error
;
286 if Position
.Container
/= Container
'Unrestricted_Access then
290 Tree_Operations
.Delete_Node_Sans_Free
(Container
.Tree
, Position
.Node
);
291 Free
(Position
.Node
);
292 Position
.Container
:= null;
295 procedure Delete
(Container
: in out Set
; Item
: Element_Type
) is
296 X
: Node_Access
:= Element_Keys
.Find
(Container
.Tree
, Item
);
300 raise Constraint_Error
;
303 Tree_Operations
.Delete_Node_Sans_Free
(Container
.Tree
, X
);
311 procedure Delete_First
(Container
: in out Set
) is
312 Tree
: Tree_Type
renames Container
.Tree
;
313 X
: Node_Access
:= Tree
.First
;
317 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, X
);
326 procedure Delete_Last
(Container
: in out Set
) is
327 Tree
: Tree_Type
renames Container
.Tree
;
328 X
: Node_Access
:= Tree
.Last
;
332 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, X
);
341 procedure Difference
(Target
: in out Set
; Source
: Set
) is
343 Set_Ops
.Difference
(Target
.Tree
, Source
.Tree
);
346 function Difference
(Left
, Right
: Set
) return Set
is
347 Tree
: constant Tree_Type
:=
348 Set_Ops
.Difference
(Left
.Tree
, Right
.Tree
);
350 return Set
'(Controlled with Tree);
357 function Element (Position : Cursor) return Element_Type is
359 return Position.Node.Element;
362 -------------------------
363 -- Equivalent_Elements --
364 -------------------------
366 function Equivalent_Elements (Left, Right : Element_Type) return Boolean is
375 end Equivalent_Elements;
377 ---------------------
378 -- Equivalent_Sets --
379 ---------------------
381 function Equivalent_Sets (Left, Right : Set) return Boolean is
382 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean;
383 pragma Inline (Is_Equivalent_Node_Node);
385 function Is_Equivalent is
386 new Tree_Operations.Generic_Equal (Is_Equivalent_Node_Node);
388 -----------------------------
389 -- Is_Equivalent_Node_Node --
390 -----------------------------
392 function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean is
394 if L.Element < R.Element then
396 elsif R.Element < L.Element then
401 end Is_Equivalent_Node_Node;
403 -- Start of processing for Equivalent_Sets
406 return Is_Equivalent (Left.Tree, Right.Tree);
413 procedure Exclude (Container : in out Set; Item : Element_Type) is
414 X : Node_Access := Element_Keys.Find (Container.Tree, Item);
418 Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
427 function Find (Container : Set; Item : Element_Type) return Cursor is
428 Node : constant Node_Access :=
429 Element_Keys.Find (Container.Tree, Item);
436 return Cursor'(Container
'Unrestricted_Access, Node
);
443 function First
(Container
: Set
) return Cursor
is
445 if Container
.Tree
.First
= null then
449 return Cursor
'(Container'Unrestricted_Access, Container.Tree.First);
456 function First_Element (Container : Set) return Element_Type is
458 return Container.Tree.First.Element;
465 function Floor (Container : Set; Item : Element_Type) return Cursor is
466 Node : constant Node_Access :=
467 Element_Keys.Floor (Container.Tree, Item);
474 return Cursor'(Container
'Unrestricted_Access, Node
);
481 package body Generic_Keys
is
483 -----------------------
484 -- Local Subprograms --
485 -----------------------
487 function Is_Greater_Key_Node
489 Right
: Node_Access
) return Boolean;
490 pragma Inline
(Is_Greater_Key_Node
);
492 function Is_Less_Key_Node
494 Right
: Node_Access
) return Boolean;
495 pragma Inline
(Is_Less_Key_Node
);
497 --------------------------
498 -- Local Instantiations --
499 --------------------------
502 new Red_Black_Trees
.Generic_Keys
503 (Tree_Operations
=> Tree_Operations
,
504 Key_Type
=> Key_Type
,
505 Is_Less_Key_Node
=> Is_Less_Key_Node
,
506 Is_Greater_Key_Node
=> Is_Greater_Key_Node
);
512 function Ceiling
(Container
: Set
; Key
: Key_Type
) return Cursor
is
513 Node
: constant Node_Access
:=
514 Key_Keys
.Ceiling
(Container
.Tree
, Key
);
521 return Cursor
'(Container'Unrestricted_Access, Node);
528 function Contains (Container : Set; Key : Key_Type) return Boolean is
530 return Find (Container, Key) /= No_Element;
537 procedure Delete (Container : in out Set; Key : Key_Type) is
538 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
542 raise Constraint_Error;
545 Delete_Node_Sans_Free (Container.Tree, X);
555 Key : Key_Type) return Element_Type
557 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
563 ---------------------
564 -- Equivalent_Keys --
565 ---------------------
567 function Equivalent_Keys (Left, Right : Key_Type) return Boolean is
582 procedure Exclude (Container : in out Set; Key : Key_Type) is
583 X : Node_Access := Key_Keys.Find (Container.Tree, Key);
587 Delete_Node_Sans_Free (Container.Tree, X);
596 function Find (Container : Set; Key : Key_Type) return Cursor is
597 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
604 return Cursor'(Container
'Unrestricted_Access, Node
);
611 function Floor
(Container
: Set
; Key
: Key_Type
) return Cursor
is
612 Node
: constant Node_Access
:= Key_Keys
.Floor
(Container
.Tree
, Key
);
619 return Cursor
'(Container'Unrestricted_Access, Node);
622 -------------------------
623 -- Is_Greater_Key_Node --
624 -------------------------
626 function Is_Greater_Key_Node
628 Right : Node_Access) return Boolean
631 return Key (Right.Element) < Left;
632 end Is_Greater_Key_Node;
634 ----------------------
635 -- Is_Less_Key_Node --
636 ----------------------
638 function Is_Less_Key_Node
640 Right : Node_Access) return Boolean
643 return Left < Key (Right.Element);
644 end Is_Less_Key_Node;
650 function Key (Position : Cursor) return Key_Type is
652 return Key (Position.Node.Element);
660 (Container : in out Set;
662 New_Item : Element_Type)
664 Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
668 raise Constraint_Error;
671 Replace_Element (Container.Tree, Node, New_Item);
674 -----------------------------------
675 -- Update_Element_Preserving_Key --
676 -----------------------------------
678 procedure Update_Element_Preserving_Key
679 (Container : in out Set;
681 Process : not null access procedure (Element : in out Element_Type))
683 Tree : Tree_Type renames Container.Tree;
686 if Position.Node = null then
687 raise Constraint_Error;
690 if Position.Container /= Container'Unrestricted_Access then
695 E : Element_Type renames Position.Node.Element;
696 K : constant Key_Type := Key (E);
698 B : Natural renames Tree.Busy;
699 L : Natural renames Tree.Lock;
717 if Equivalent_Keys (K, Key (E)) then
723 X : Node_Access := Position.Node;
725 Tree_Operations.Delete_Node_Sans_Free (Tree, X);
730 end Update_Element_Preserving_Key;
738 function Has_Element (Position : Cursor) return Boolean is
740 return Position /= No_Element;
747 procedure Include (Container : in out Set; New_Item : Element_Type) is
752 Insert (Container, New_Item, Position, Inserted);
755 if Container.Tree.Lock > 0 then
759 Position.Node.Element := New_Item;
768 (Container : in out Set;
769 New_Item : Element_Type;
770 Position : out Cursor;
771 Inserted : out Boolean)
773 function New_Node return Node_Access;
774 pragma Inline (New_Node);
776 procedure Insert_Post is
777 new Element_Keys.Generic_Insert_Post (New_Node);
779 procedure Insert_Sans_Hint is
780 new Element_Keys.Generic_Conditional_Insert (Insert_Post);
786 function New_Node return Node_Access is
787 Node : constant Node_Access :=
788 new Node_Type'(Parent
=> null,
792 Element
=> New_Item
);
797 -- Start of processing for Insert
806 Position
.Container
:= Container
'Unrestricted_Access;
810 (Container
: in out Set
;
811 New_Item
: Element_Type
)
817 Insert
(Container
, New_Item
, Position
, Inserted
);
820 raise Constraint_Error
;
824 ----------------------
825 -- Insert_With_Hint --
826 ----------------------
828 procedure Insert_With_Hint
829 (Dst_Tree
: in out Tree_Type
;
830 Dst_Hint
: Node_Access
;
831 Src_Node
: Node_Access
;
832 Dst_Node
: out Node_Access
)
836 function New_Node
return Node_Access
;
837 pragma Inline
(New_Node
);
839 procedure Insert_Post
is
840 new Element_Keys
.Generic_Insert_Post
(New_Node
);
842 procedure Insert_Sans_Hint
is
843 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
845 procedure Local_Insert_With_Hint
is
846 new Element_Keys
.Generic_Conditional_Insert_With_Hint
854 function New_Node
return Node_Access
is
855 Node
: constant Node_Access
:=
856 new Node_Type
'(Parent => null,
860 Element => Src_Node.Element);
865 -- Start of processing for Insert_With_Hint
868 Local_Insert_With_Hint
874 end Insert_With_Hint;
880 procedure Intersection (Target : in out Set; Source : Set) is
882 Set_Ops.Intersection (Target.Tree, Source.Tree);
885 function Intersection (Left, Right : Set) return Set is
886 Tree : constant Tree_Type :=
887 Set_Ops.Intersection (Left.Tree, Right.Tree);
889 return Set'(Controlled
with Tree
);
896 function Is_Empty
(Container
: Set
) return Boolean is
898 return Container
.Tree
.Length
= 0;
901 ------------------------
902 -- Is_Equal_Node_Node --
903 ------------------------
905 function Is_Equal_Node_Node
(L
, R
: Node_Access
) return Boolean is
907 return L
.Element
= R
.Element
;
908 end Is_Equal_Node_Node
;
910 -----------------------------
911 -- Is_Greater_Element_Node --
912 -----------------------------
914 function Is_Greater_Element_Node
915 (Left
: Element_Type
;
916 Right
: Node_Access
) return Boolean
919 -- Compute e > node same as node < e
921 return Right
.Element
< Left
;
922 end Is_Greater_Element_Node
;
924 --------------------------
925 -- Is_Less_Element_Node --
926 --------------------------
928 function Is_Less_Element_Node
929 (Left
: Element_Type
;
930 Right
: Node_Access
) return Boolean
933 return Left
< Right
.Element
;
934 end Is_Less_Element_Node
;
936 -----------------------
937 -- Is_Less_Node_Node --
938 -----------------------
940 function Is_Less_Node_Node
(L
, R
: Node_Access
) return Boolean is
942 return L
.Element
< R
.Element
;
943 end Is_Less_Node_Node
;
949 function Is_Subset
(Subset
: Set
; Of_Set
: Set
) return Boolean is
951 return Set_Ops
.Is_Subset
(Subset
=> Subset
.Tree
, Of_Set
=> Of_Set
.Tree
);
960 Process
: not null access procedure (Position
: Cursor
))
962 procedure Process_Node
(Node
: Node_Access
);
963 pragma Inline
(Process_Node
);
965 procedure Local_Iterate
is
966 new Tree_Operations
.Generic_Iteration
(Process_Node
);
972 procedure Process_Node
(Node
: Node_Access
) is
974 Process
(Cursor
'(Container'Unrestricted_Access, Node));
977 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
978 B : Natural renames T.Busy;
980 -- Start of prccessing for Iterate
1000 function Last (Container : Set) return Cursor is
1002 if Container.Tree.Last = null then
1006 return Cursor'(Container
'Unrestricted_Access, Container
.Tree
.Last
);
1013 function Last_Element
(Container
: Set
) return Element_Type
is
1015 return Container
.Tree
.Last
.Element
;
1022 function Left
(Node
: Node_Access
) return Node_Access
is
1031 function Length
(Container
: Set
) return Count_Type
is
1033 return Container
.Tree
.Length
;
1041 new Tree_Operations
.Generic_Move
(Clear
);
1043 procedure Move
(Target
: in out Set
; Source
: in out Set
) is
1045 Move
(Target
=> Target
.Tree
, Source
=> Source
.Tree
);
1052 function Next
(Position
: Cursor
) return Cursor
is
1054 if Position
= No_Element
then
1059 Node
: constant Node_Access
:=
1060 Tree_Operations
.Next
(Position
.Node
);
1067 return Cursor
'(Position.Container, Node);
1071 procedure Next (Position : in out Cursor) is
1073 Position := Next (Position);
1080 function Overlap (Left, Right : Set) return Boolean is
1082 return Set_Ops.Overlap (Left.Tree, Right.Tree);
1089 function Parent (Node : Node_Access) return Node_Access is
1098 function Previous (Position : Cursor) return Cursor is
1100 if Position = No_Element then
1105 Node : constant Node_Access :=
1106 Tree_Operations.Previous (Position.Node);
1113 return Cursor'(Position
.Container
, Node
);
1117 procedure Previous
(Position
: in out Cursor
) is
1119 Position
:= Previous
(Position
);
1126 procedure Query_Element
1128 Process
: not null access procedure (Element
: Element_Type
))
1130 E
: Element_Type
renames Position
.Node
.Element
;
1132 S
: Set
renames Position
.Container
.all;
1133 T
: Tree_Type
renames S
.Tree
'Unrestricted_Access.all;
1135 B
: Natural renames T
.Busy
;
1136 L
: Natural renames T
.Lock
;
1160 (Stream
: access Root_Stream_Type
'Class;
1161 Container
: out Set
)
1164 (Stream
: access Root_Stream_Type
'Class) return Node_Access
;
1165 pragma Inline
(Read_Node
);
1168 new Tree_Operations
.Generic_Read
(Clear
, Read_Node
);
1175 (Stream
: access Root_Stream_Type
'Class) return Node_Access
1177 Node
: Node_Access
:= new Node_Type
;
1180 Element_Type
'Read (Stream
, Node
.Element
);
1189 -- Start of processing for Read
1192 Read
(Stream
, Container
.Tree
);
1199 procedure Replace
(Container
: in out Set
; New_Item
: Element_Type
) is
1200 Node
: constant Node_Access
:=
1201 Element_Keys
.Find
(Container
.Tree
, New_Item
);
1205 raise Constraint_Error
;
1208 if Container
.Tree
.Lock
> 0 then
1209 raise Program_Error
;
1212 Node
.Element
:= New_Item
;
1215 ---------------------
1216 -- Replace_Element --
1217 ---------------------
1219 procedure Replace_Element
1220 (Tree
: in out Tree_Type
;
1222 Item
: Element_Type
)
1225 if Item
< Node
.Element
1226 or else Node
.Element
< Item
1230 if Tree
.Lock
> 0 then
1231 raise Program_Error
;
1234 Node
.Element
:= Item
;
1238 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, Node
); -- Checks busy-bit
1240 Insert_New_Item
: declare
1241 function New_Node
return Node_Access
;
1242 pragma Inline
(New_Node
);
1244 procedure Insert_Post
is
1245 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1248 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
1254 function New_Node
return Node_Access
is
1256 Node
.Element
:= Item
;
1260 Result
: Node_Access
;
1263 -- Start of processing for Insert_New_Item
1270 Success
=> Inserted
); -- TODO: change param name
1273 pragma Assert
(Result
= Node
);
1278 null; -- Assignment must have failed
1279 end Insert_New_Item
;
1281 Reinsert_Old_Element
: declare
1282 function New_Node
return Node_Access
;
1283 pragma Inline
(New_Node
);
1285 procedure Insert_Post
is
1286 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1289 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
1295 function New_Node
return Node_Access
is
1300 Result
: Node_Access
;
1303 -- Start of processing for Reinsert_Old_Element
1308 Key
=> Node
.Element
,
1310 Success
=> Inserted
); -- TODO: change param name
1313 null; -- Assignment must have failed
1314 end Reinsert_Old_Element
;
1316 raise Program_Error
;
1317 end Replace_Element
;
1319 procedure Replace_Element
1320 (Container
: in out Set
;
1322 New_Item
: Element_Type
)
1325 if Position
.Node
= null then
1326 raise Constraint_Error
;
1329 if Position
.Container
/= Container
'Unrestricted_Access then
1330 raise Program_Error
;
1333 Replace_Element
(Container
.Tree
, Position
.Node
, New_Item
);
1334 end Replace_Element
;
1336 ---------------------
1337 -- Reverse_Iterate --
1338 ---------------------
1340 procedure Reverse_Iterate
1342 Process
: not null access procedure (Position
: Cursor
))
1344 procedure Process_Node
(Node
: Node_Access
);
1345 pragma Inline
(Process_Node
);
1347 procedure Local_Reverse_Iterate
is
1348 new Tree_Operations
.Generic_Reverse_Iteration
(Process_Node
);
1354 procedure Process_Node
(Node
: Node_Access
) is
1356 Process
(Cursor
'(Container'Unrestricted_Access, Node));
1359 T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
1360 B : Natural renames T.Busy;
1362 -- Start of processing for Reverse_Iterate
1368 Local_Reverse_Iterate (T);
1376 end Reverse_Iterate;
1382 function Right (Node : Node_Access) return Node_Access is
1391 procedure Set_Color (Node : Node_Access; Color : Color_Type) is
1393 Node.Color := Color;
1400 procedure Set_Left (Node : Node_Access; Left : Node_Access) is
1409 procedure Set_Parent (Node : Node_Access; Parent : Node_Access) is
1411 Node.Parent := Parent;
1418 procedure Set_Right (Node : Node_Access; Right : Node_Access) is
1420 Node.Right := Right;
1423 --------------------------
1424 -- Symmetric_Difference --
1425 --------------------------
1427 procedure Symmetric_Difference (Target : in out Set; Source : Set) is
1429 Set_Ops.Symmetric_Difference (Target.Tree, Source.Tree);
1430 end Symmetric_Difference;
1432 function Symmetric_Difference (Left, Right : Set) return Set is
1433 Tree : constant Tree_Type :=
1434 Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
1436 return Set'(Controlled
with Tree
);
1437 end Symmetric_Difference
;
1443 procedure Union
(Target
: in out Set
; Source
: Set
) is
1445 Set_Ops
.Union
(Target
.Tree
, Source
.Tree
);
1448 function Union
(Left
, Right
: Set
) return Set
is
1449 Tree
: constant Tree_Type
:=
1450 Set_Ops
.Union
(Left
.Tree
, Right
.Tree
);
1452 return Set
'(Controlled with Tree);
1460 (Stream : access Root_Stream_Type'Class;
1463 procedure Write_Node
1464 (Stream : access Root_Stream_Type'Class;
1465 Node : Node_Access);
1466 pragma Inline (Write_Node);
1469 new Tree_Operations.Generic_Write (Write_Node);
1475 procedure Write_Node
1476 (Stream : access Root_Stream_Type'Class;
1480 Element_Type'Write (Stream, Node.Element);
1483 -- Start of processing for Write
1486 Write (Stream, Container.Tree);
1489 end Ada.Containers.Ordered_Sets;