1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . F O R M A L _ O R D E R E D _ S E T S --
9 -- Copyright (C) 2010-2014, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 ------------------------------------------------------------------------------
28 with Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Operations
;
30 (Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Operations
);
32 with Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Keys
;
33 pragma Elaborate_All
(Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Keys
);
35 with Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Set_Operations
;
37 (Ada
.Containers
.Red_Black_Trees
.Generic_Bounded_Set_Operations
);
39 with System
; use type System
.Address
;
41 package body Ada
.Containers
.Formal_Ordered_Sets
is
42 pragma SPARK_Mode
(Off
);
44 ------------------------------
45 -- Access to Fields of Node --
46 ------------------------------
48 -- These subprograms provide functional notation for access to fields
49 -- of a node, and procedural notation for modifiying these fields.
51 function Color
(Node
: Node_Type
) return Red_Black_Trees
.Color_Type
;
52 pragma Inline
(Color
);
54 function Left_Son
(Node
: Node_Type
) return Count_Type
;
55 pragma Inline
(Left_Son
);
57 function Parent
(Node
: Node_Type
) return Count_Type
;
58 pragma Inline
(Parent
);
60 function Right_Son
(Node
: Node_Type
) return Count_Type
;
61 pragma Inline
(Right_Son
);
64 (Node
: in out Node_Type
;
65 Color
: Red_Black_Trees
.Color_Type
);
66 pragma Inline
(Set_Color
);
68 procedure Set_Left
(Node
: in out Node_Type
; Left
: Count_Type
);
69 pragma Inline
(Set_Left
);
71 procedure Set_Right
(Node
: in out Node_Type
; Right
: Count_Type
);
72 pragma Inline
(Set_Right
);
74 procedure Set_Parent
(Node
: in out Node_Type
; Parent
: Count_Type
);
75 pragma Inline
(Set_Parent
);
77 -----------------------
78 -- Local Subprograms --
79 -----------------------
84 with procedure Set_Element
(Node
: in out Node_Type
);
85 procedure Generic_Allocate
86 (Tree
: in out Tree_Types
.Tree_Type
'Class;
87 Node
: out Count_Type
);
89 procedure Free
(Tree
: in out Set
; X
: Count_Type
);
91 procedure Insert_Sans_Hint
92 (Container
: in out Set
;
93 New_Item
: Element_Type
;
94 Node
: out Count_Type
;
95 Inserted
: out Boolean);
97 procedure Insert_With_Hint
98 (Dst_Set
: in out Set
;
99 Dst_Hint
: Count_Type
;
100 Src_Node
: Node_Type
;
101 Dst_Node
: out Count_Type
);
103 function Is_Greater_Element_Node
104 (Left
: Element_Type
;
105 Right
: Node_Type
) return Boolean;
106 pragma Inline
(Is_Greater_Element_Node
);
108 function Is_Less_Element_Node
109 (Left
: Element_Type
;
110 Right
: Node_Type
) return Boolean;
111 pragma Inline
(Is_Less_Element_Node
);
113 function Is_Less_Node_Node
(L
, R
: Node_Type
) return Boolean;
114 pragma Inline
(Is_Less_Node_Node
);
116 procedure Replace_Element
119 Item
: Element_Type
);
121 --------------------------
122 -- Local Instantiations --
123 --------------------------
125 package Tree_Operations
is
126 new Red_Black_Trees
.Generic_Bounded_Operations
133 package Element_Keys
is
134 new Red_Black_Trees
.Generic_Bounded_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
);
141 new Red_Black_Trees
.Generic_Bounded_Set_Operations
142 (Tree_Operations
=> Tree_Operations
,
145 Insert_With_Hint
=> Insert_With_Hint
,
146 Is_Less
=> Is_Less_Node_Node
);
152 function "=" (Left
, Right
: Set
) return Boolean is
158 if Length
(Left
) /= Length
(Right
) then
162 if Is_Empty
(Left
) then
166 Lst
:= Next
(Left
, Last
(Left
).Node
);
168 Node
:= First
(Left
).Node
;
169 while Node
/= Lst
loop
170 ENode
:= Find
(Right
, Left
.Nodes
(Node
).Element
).Node
;
172 or else Left
.Nodes
(Node
).Element
/= Right
.Nodes
(ENode
).Element
177 Node
:= Next
(Left
, Node
);
187 procedure Assign
(Target
: in out Set
; Source
: Set
) is
188 procedure Append_Element
(Source_Node
: Count_Type
);
190 procedure Append_Elements
is
191 new Tree_Operations
.Generic_Iteration
(Append_Element
);
197 procedure Append_Element
(Source_Node
: Count_Type
) is
198 SN
: Node_Type
renames Source
.Nodes
(Source_Node
);
200 procedure Set_Element
(Node
: in out Node_Type
);
201 pragma Inline
(Set_Element
);
203 function New_Node
return Count_Type
;
204 pragma Inline
(New_Node
);
206 procedure Insert_Post
is
207 new Element_Keys
.Generic_Insert_Post
(New_Node
);
209 procedure Unconditional_Insert_Sans_Hint
is
210 new Element_Keys
.Generic_Unconditional_Insert
(Insert_Post
);
212 procedure Unconditional_Insert_Avec_Hint
is
213 new Element_Keys
.Generic_Unconditional_Insert_With_Hint
215 Unconditional_Insert_Sans_Hint
);
217 procedure Allocate
is new Generic_Allocate
(Set_Element
);
223 function New_Node
return Count_Type
is
226 Allocate
(Target
, Result
);
234 procedure Set_Element
(Node
: in out Node_Type
) is
236 Node
.Element
:= SN
.Element
;
241 Target_Node
: Count_Type
;
243 -- Start of processing for Append_Element
246 Unconditional_Insert_Avec_Hint
250 Node
=> Target_Node
);
253 -- Start of processing for Assign
256 if Target
'Address = Source
'Address then
260 if Target
.Capacity
< Source
.Length
then
261 raise Constraint_Error
262 with "Target capacity is less than Source length";
265 Tree_Operations
.Clear_Tree
(Target
);
266 Append_Elements
(Source
);
273 function Ceiling
(Container
: Set
; Item
: Element_Type
) return Cursor
is
274 Node
: constant Count_Type
:= Element_Keys
.Ceiling
(Container
, Item
);
281 return (Node
=> Node
);
288 procedure Clear
(Container
: in out Set
) is
290 Tree_Operations
.Clear_Tree
(Container
);
297 function Color
(Node
: Node_Type
) return Red_Black_Trees
.Color_Type
is
308 Item
: Element_Type
) return Boolean
311 return Find
(Container
, Item
) /= No_Element
;
318 function Copy
(Source
: Set
; Capacity
: Count_Type
:= 0) return Set
is
321 Target
: Set
(Count_Type
'Max (Source
.Capacity
, Capacity
));
324 if 0 < Capacity
and then Capacity
< Source
.Capacity
then
325 raise Capacity_Error
;
328 if Length
(Source
) > 0 then
329 Target
.Length
:= Source
.Length
;
330 Target
.Root
:= Source
.Root
;
331 Target
.First
:= Source
.First
;
332 Target
.Last
:= Source
.Last
;
333 Target
.Free
:= Source
.Free
;
336 while Node
<= Source
.Capacity
loop
337 Target
.Nodes
(Node
).Element
:=
338 Source
.Nodes
(Node
).Element
;
339 Target
.Nodes
(Node
).Parent
:=
340 Source
.Nodes
(Node
).Parent
;
341 Target
.Nodes
(Node
).Left
:=
342 Source
.Nodes
(Node
).Left
;
343 Target
.Nodes
(Node
).Right
:=
344 Source
.Nodes
(Node
).Right
;
345 Target
.Nodes
(Node
).Color
:=
346 Source
.Nodes
(Node
).Color
;
347 Target
.Nodes
(Node
).Has_Element
:=
348 Source
.Nodes
(Node
).Has_Element
;
352 while Node
<= Target
.Capacity
loop
354 Formal_Ordered_Sets
.Free
(Tree
=> Target
, X
=> N
);
362 ---------------------
363 -- Current_To_Last --
364 ---------------------
366 function Current_To_Last
(Container
: Set
; Current
: Cursor
) return Set
is
367 Curs
: Cursor
:= First
(Container
);
368 C
: Set
(Container
.Capacity
) := Copy
(Container
, Container
.Capacity
);
372 if Curs
= No_Element
then
377 if Current
/= No_Element
and not Has_Element
(Container
, Current
) then
378 raise Constraint_Error
;
381 while Curs
.Node
/= Current
.Node
loop
384 Curs
:= Next
(Container
, (Node
=> Node
));
394 procedure Delete
(Container
: in out Set
; Position
: in out Cursor
) is
396 if not Has_Element
(Container
, Position
) then
397 raise Constraint_Error
with "Position cursor has no element";
400 pragma Assert
(Vet
(Container
, Position
.Node
),
401 "bad cursor in Delete");
403 Tree_Operations
.Delete_Node_Sans_Free
(Container
,
405 Formal_Ordered_Sets
.Free
(Container
, Position
.Node
);
406 Position
:= No_Element
;
409 procedure Delete
(Container
: in out Set
; Item
: Element_Type
) is
410 X
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
414 raise Constraint_Error
with "attempt to delete element not in set";
417 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
418 Formal_Ordered_Sets
.Free
(Container
, X
);
425 procedure Delete_First
(Container
: in out Set
) is
426 X
: constant Count_Type
:= Container
.First
;
429 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
430 Formal_Ordered_Sets
.Free
(Container
, X
);
438 procedure Delete_Last
(Container
: in out Set
) is
439 X
: constant Count_Type
:= Container
.Last
;
442 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
443 Formal_Ordered_Sets
.Free
(Container
, X
);
451 procedure Difference
(Target
: in out Set
; Source
: Set
) is
453 Set_Ops
.Set_Difference
(Target
, Source
);
456 function Difference
(Left
, Right
: Set
) return Set
is
458 if Left
'Address = Right
'Address then
462 if Length
(Left
) = 0 then
466 if Length
(Right
) = 0 then
470 return S
: Set
(Length
(Left
)) do
471 Assign
(S
, Set_Ops
.Set_Difference
(Left
, Right
));
479 function Element
(Container
: Set
; Position
: Cursor
) return Element_Type
is
481 if not Has_Element
(Container
, Position
) then
482 raise Constraint_Error
with "Position cursor has no element";
485 pragma Assert
(Vet
(Container
, Position
.Node
),
486 "bad cursor in Element");
488 return Container
.Nodes
(Position
.Node
).Element
;
491 -------------------------
492 -- Equivalent_Elements --
493 -------------------------
495 function Equivalent_Elements
(Left
, Right
: Element_Type
) return Boolean is
504 end Equivalent_Elements
;
506 ---------------------
507 -- Equivalent_Sets --
508 ---------------------
510 function Equivalent_Sets
(Left
, Right
: Set
) return Boolean is
511 function Is_Equivalent_Node_Node
512 (L
, R
: Node_Type
) return Boolean;
513 pragma Inline
(Is_Equivalent_Node_Node
);
515 function Is_Equivalent
is
516 new Tree_Operations
.Generic_Equal
(Is_Equivalent_Node_Node
);
518 -----------------------------
519 -- Is_Equivalent_Node_Node --
520 -----------------------------
522 function Is_Equivalent_Node_Node
(L
, R
: Node_Type
) return Boolean is
524 if L
.Element
< R
.Element
then
526 elsif R
.Element
< L
.Element
then
531 end Is_Equivalent_Node_Node
;
533 -- Start of processing for Equivalent_Sets
536 return Is_Equivalent
(Left
, Right
);
543 procedure Exclude
(Container
: in out Set
; Item
: Element_Type
) is
544 X
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
547 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
548 Formal_Ordered_Sets
.Free
(Container
, X
);
556 function Find
(Container
: Set
; Item
: Element_Type
) return Cursor
is
557 Node
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
564 return (Node
=> Node
);
571 function First
(Container
: Set
) return Cursor
is
573 if Length
(Container
) = 0 then
577 return (Node
=> Container
.First
);
584 function First_Element
(Container
: Set
) return Element_Type
is
585 Fst
: constant Count_Type
:= First
(Container
).Node
;
588 raise Constraint_Error
with "set is empty";
592 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
594 return N
(Fst
).Element
;
598 -----------------------
599 -- First_To_Previous --
600 -----------------------
602 function First_To_Previous
604 Current
: Cursor
) return Set
606 Curs
: Cursor
:= Current
;
607 C
: Set
(Container
.Capacity
) := Copy
(Container
, Container
.Capacity
);
611 if Curs
= No_Element
then
614 elsif not Has_Element
(Container
, Curs
) then
615 raise Constraint_Error
;
618 while Curs
.Node
/= 0 loop
621 Curs
:= Next
(Container
, (Node
=> Node
));
626 end First_To_Previous
;
632 function Floor
(Container
: Set
; Item
: Element_Type
) return Cursor
is
635 Node
: constant Count_Type
:= Element_Keys
.Floor
(Container
, Item
);
642 return (Node
=> Node
);
650 procedure Free
(Tree
: in out Set
; X
: Count_Type
) is
652 Tree
.Nodes
(X
).Has_Element
:= False;
653 Tree_Operations
.Free
(Tree
, X
);
656 ----------------------
657 -- Generic_Allocate --
658 ----------------------
660 procedure Generic_Allocate
661 (Tree
: in out Tree_Types
.Tree_Type
'Class;
662 Node
: out Count_Type
)
664 procedure Allocate
is
665 new Tree_Operations
.Generic_Allocate
(Set_Element
);
667 Allocate
(Tree
, Node
);
668 Tree
.Nodes
(Node
).Has_Element
:= True;
669 end Generic_Allocate
;
675 package body Generic_Keys
is
677 -----------------------
678 -- Local Subprograms --
679 -----------------------
681 function Is_Greater_Key_Node
683 Right
: Node_Type
) return Boolean;
684 pragma Inline
(Is_Greater_Key_Node
);
686 function Is_Less_Key_Node
688 Right
: Node_Type
) return Boolean;
689 pragma Inline
(Is_Less_Key_Node
);
691 --------------------------
692 -- Local Instantiations --
693 --------------------------
696 new Red_Black_Trees
.Generic_Bounded_Keys
697 (Tree_Operations
=> Tree_Operations
,
698 Key_Type
=> Key_Type
,
699 Is_Less_Key_Node
=> Is_Less_Key_Node
,
700 Is_Greater_Key_Node
=> Is_Greater_Key_Node
);
706 function Ceiling
(Container
: Set
; Key
: Key_Type
) return Cursor
is
707 Node
: constant Count_Type
:= Key_Keys
.Ceiling
(Container
, Key
);
714 return (Node
=> Node
);
721 function Contains
(Container
: Set
; Key
: Key_Type
) return Boolean is
723 return Find
(Container
, Key
) /= No_Element
;
730 procedure Delete
(Container
: in out Set
; Key
: Key_Type
) is
731 X
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
735 raise Constraint_Error
with "attempt to delete key not in set";
738 Delete_Node_Sans_Free
(Container
, X
);
739 Formal_Ordered_Sets
.Free
(Container
, X
);
746 function Element
(Container
: Set
; Key
: Key_Type
) return Element_Type
is
747 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
751 raise Constraint_Error
with "key not in set";
755 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
757 return N
(Node
).Element
;
761 ---------------------
762 -- Equivalent_Keys --
763 ---------------------
765 function Equivalent_Keys
(Left
, Right
: Key_Type
) return Boolean is
780 procedure Exclude
(Container
: in out Set
; Key
: Key_Type
) is
781 X
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
784 Delete_Node_Sans_Free
(Container
, X
);
785 Formal_Ordered_Sets
.Free
(Container
, X
);
793 function Find
(Container
: Set
; Key
: Key_Type
) return Cursor
is
794 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
796 return (if Node
= 0 then No_Element
else (Node
=> Node
));
803 function Floor
(Container
: Set
; Key
: Key_Type
) return Cursor
is
804 Node
: constant Count_Type
:= Key_Keys
.Floor
(Container
, Key
);
806 return (if Node
= 0 then No_Element
else (Node
=> Node
));
809 -------------------------
810 -- Is_Greater_Key_Node --
811 -------------------------
813 function Is_Greater_Key_Node
815 Right
: Node_Type
) return Boolean
818 return Key
(Right
.Element
) < Left
;
819 end Is_Greater_Key_Node
;
821 ----------------------
822 -- Is_Less_Key_Node --
823 ----------------------
825 function Is_Less_Key_Node
827 Right
: Node_Type
) return Boolean
830 return Left
< Key
(Right
.Element
);
831 end Is_Less_Key_Node
;
837 function Key
(Container
: Set
; Position
: Cursor
) return Key_Type
is
839 if not Has_Element
(Container
, Position
) then
840 raise Constraint_Error
with
841 "Position cursor has no element";
844 pragma Assert
(Vet
(Container
, Position
.Node
),
845 "bad cursor in Key");
848 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
850 return Key
(N
(Position
.Node
).Element
);
859 (Container
: in out Set
;
861 New_Item
: Element_Type
)
863 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
865 if not Has_Element
(Container
, (Node
=> Node
)) then
866 raise Constraint_Error
with
867 "attempt to replace key not in set";
869 Replace_Element
(Container
, Node
, New_Item
);
879 function Has_Element
(Container
: Set
; Position
: Cursor
) return Boolean is
881 if Position
.Node
= 0 then
884 return Container
.Nodes
(Position
.Node
).Has_Element
;
892 procedure Include
(Container
: in out Set
; New_Item
: Element_Type
) is
897 Insert
(Container
, New_Item
, Position
, Inserted
);
901 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
903 N
(Position
.Node
).Element
:= New_Item
;
913 (Container
: in out Set
;
914 New_Item
: Element_Type
;
915 Position
: out Cursor
;
916 Inserted
: out Boolean)
919 Insert_Sans_Hint
(Container
, New_Item
, Position
.Node
, Inserted
);
923 (Container
: in out Set
;
924 New_Item
: Element_Type
)
930 Insert
(Container
, New_Item
, Position
, Inserted
);
933 raise Constraint_Error
with
934 "attempt to insert element already in set";
938 ----------------------
939 -- Insert_Sans_Hint --
940 ----------------------
942 procedure Insert_Sans_Hint
943 (Container
: in out Set
;
944 New_Item
: Element_Type
;
945 Node
: out Count_Type
;
946 Inserted
: out Boolean)
948 procedure Set_Element
(Node
: in out Node_Type
);
950 function New_Node
return Count_Type
;
951 pragma Inline
(New_Node
);
953 procedure Insert_Post
is
954 new Element_Keys
.Generic_Insert_Post
(New_Node
);
956 procedure Conditional_Insert_Sans_Hint
is
957 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
959 procedure Allocate
is new Generic_Allocate
(Set_Element
);
965 function New_Node
return Count_Type
is
968 Allocate
(Container
, Result
);
976 procedure Set_Element
(Node
: in out Node_Type
) is
978 Node
.Element
:= New_Item
;
981 -- Start of processing for Insert_Sans_Hint
984 Conditional_Insert_Sans_Hint
989 end Insert_Sans_Hint
;
991 ----------------------
992 -- Insert_With_Hint --
993 ----------------------
995 procedure Insert_With_Hint
996 (Dst_Set
: in out Set
;
997 Dst_Hint
: Count_Type
;
998 Src_Node
: Node_Type
;
999 Dst_Node
: out Count_Type
)
1002 pragma Unreferenced
(Success
);
1004 procedure Set_Element
(Node
: in out Node_Type
);
1006 function New_Node
return Count_Type
;
1007 pragma Inline
(New_Node
);
1009 procedure Insert_Post
is
1010 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1012 procedure Insert_Sans_Hint
is
1013 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
1015 procedure Local_Insert_With_Hint
is
1016 new Element_Keys
.Generic_Conditional_Insert_With_Hint
1017 (Insert_Post
, Insert_Sans_Hint
);
1019 procedure Allocate
is new Generic_Allocate
(Set_Element
);
1025 function New_Node
return Count_Type
is
1026 Result
: Count_Type
;
1028 Allocate
(Dst_Set
, Result
);
1036 procedure Set_Element
(Node
: in out Node_Type
) is
1038 Node
.Element
:= Src_Node
.Element
;
1041 -- Start of processing for Insert_With_Hint
1044 Local_Insert_With_Hint
1050 end Insert_With_Hint
;
1056 procedure Intersection
(Target
: in out Set
; Source
: Set
) is
1058 Set_Ops
.Set_Intersection
(Target
, Source
);
1061 function Intersection
(Left
, Right
: Set
) return Set
is
1063 if Left
'Address = Right
'Address then
1067 return S
: Set
(Count_Type
'Min (Length
(Left
), Length
(Right
))) do
1068 Assign
(S
, Set_Ops
.Set_Intersection
(Left
, Right
));
1076 function Is_Empty
(Container
: Set
) return Boolean is
1078 return Length
(Container
) = 0;
1081 -----------------------------
1082 -- Is_Greater_Element_Node --
1083 -----------------------------
1085 function Is_Greater_Element_Node
1086 (Left
: Element_Type
;
1087 Right
: Node_Type
) return Boolean
1090 -- Compute e > node same as node < e
1092 return Right
.Element
< Left
;
1093 end Is_Greater_Element_Node
;
1095 --------------------------
1096 -- Is_Less_Element_Node --
1097 --------------------------
1099 function Is_Less_Element_Node
1100 (Left
: Element_Type
;
1101 Right
: Node_Type
) return Boolean
1104 return Left
< Right
.Element
;
1105 end Is_Less_Element_Node
;
1107 -----------------------
1108 -- Is_Less_Node_Node --
1109 -----------------------
1111 function Is_Less_Node_Node
(L
, R
: Node_Type
) return Boolean is
1113 return L
.Element
< R
.Element
;
1114 end Is_Less_Node_Node
;
1120 function Is_Subset
(Subset
: Set
; Of_Set
: Set
) return Boolean is
1122 return Set_Ops
.Set_Subset
(Subset
, Of_Set
=> Of_Set
);
1129 function Last
(Container
: Set
) return Cursor
is
1131 return (if Length
(Container
) = 0
1133 else (Node
=> Container
.Last
));
1140 function Last_Element
(Container
: Set
) return Element_Type
is
1142 if Last
(Container
).Node
= 0 then
1143 raise Constraint_Error
with "set is empty";
1147 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
1149 return N
(Last
(Container
).Node
).Element
;
1157 function Left_Son
(Node
: Node_Type
) return Count_Type
is
1166 function Length
(Container
: Set
) return Count_Type
is
1168 return Container
.Length
;
1175 procedure Move
(Target
: in out Set
; Source
: in out Set
) is
1176 N
: Tree_Types
.Nodes_Type
renames Source
.Nodes
;
1180 if Target
'Address = Source
'Address then
1184 if Target
.Capacity
< Length
(Source
) then
1185 raise Constraint_Error
with -- ???
1186 "Source length exceeds Target capacity";
1195 Insert
(Target
, N
(X
).Element
); -- optimize???
1197 Tree_Operations
.Delete_Node_Sans_Free
(Source
, X
);
1198 Formal_Ordered_Sets
.Free
(Source
, X
);
1206 function Next
(Container
: Set
; Position
: Cursor
) return Cursor
is
1208 if Position
= No_Element
then
1212 if not Has_Element
(Container
, Position
) then
1213 raise Constraint_Error
;
1216 pragma Assert
(Vet
(Container
, Position
.Node
),
1217 "bad cursor in Next");
1218 return (Node
=> Tree_Operations
.Next
(Container
, Position
.Node
));
1221 procedure Next
(Container
: Set
; Position
: in out Cursor
) is
1223 Position
:= Next
(Container
, Position
);
1230 function Overlap
(Left
, Right
: Set
) return Boolean is
1232 return Set_Ops
.Set_Overlap
(Left
, Right
);
1239 function Parent
(Node
: Node_Type
) return Count_Type
is
1248 function Previous
(Container
: Set
; Position
: Cursor
) return Cursor
is
1250 if Position
= No_Element
then
1254 if not Has_Element
(Container
, Position
) then
1255 raise Constraint_Error
;
1258 pragma Assert
(Vet
(Container
, Position
.Node
),
1259 "bad cursor in Previous");
1262 Node
: constant Count_Type
:=
1263 Tree_Operations
.Previous
(Container
, Position
.Node
);
1265 return (if Node
= 0 then No_Element
else (Node
=> Node
));
1269 procedure Previous
(Container
: Set
; Position
: in out Cursor
) is
1271 Position
:= Previous
(Container
, Position
);
1278 procedure Replace
(Container
: in out Set
; New_Item
: Element_Type
) is
1279 Node
: constant Count_Type
:= Element_Keys
.Find
(Container
, New_Item
);
1283 raise Constraint_Error
with
1284 "attempt to replace element not in set";
1287 Container
.Nodes
(Node
).Element
:= New_Item
;
1290 ---------------------
1291 -- Replace_Element --
1292 ---------------------
1294 procedure Replace_Element
1297 Item
: Element_Type
)
1299 pragma Assert
(Node
/= 0);
1301 function New_Node
return Count_Type
;
1302 pragma Inline
(New_Node
);
1304 procedure Local_Insert_Post
is
1305 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1307 procedure Local_Insert_Sans_Hint
is
1308 new Element_Keys
.Generic_Conditional_Insert
(Local_Insert_Post
);
1310 procedure Local_Insert_With_Hint
is
1311 new Element_Keys
.Generic_Conditional_Insert_With_Hint
1313 Local_Insert_Sans_Hint
);
1315 NN
: Tree_Types
.Nodes_Type
renames Tree
.Nodes
;
1321 function New_Node
return Count_Type
is
1322 N
: Node_Type
renames NN
(Node
);
1333 Result
: Count_Type
;
1336 -- Start of processing for Insert
1339 if Item
< NN
(Node
).Element
1340 or else NN
(Node
).Element
< Item
1345 NN
(Node
).Element
:= Item
;
1349 Hint
:= Element_Keys
.Ceiling
(Tree
, Item
);
1354 elsif Item
< NN
(Hint
).Element
then
1356 NN
(Node
).Element
:= Item
;
1361 pragma Assert
(not (NN
(Hint
).Element
< Item
));
1362 raise Program_Error
with "attempt to replace existing element";
1365 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, Node
);
1367 Local_Insert_With_Hint
1372 Inserted
=> Inserted
);
1374 pragma Assert
(Inserted
);
1375 pragma Assert
(Result
= Node
);
1376 end Replace_Element
;
1378 procedure Replace_Element
1379 (Container
: in out Set
;
1381 New_Item
: Element_Type
)
1384 if not Has_Element
(Container
, Position
) then
1385 raise Constraint_Error
with
1386 "Position cursor has no element";
1389 pragma Assert
(Vet
(Container
, Position
.Node
),
1390 "bad cursor in Replace_Element");
1392 Replace_Element
(Container
, Position
.Node
, New_Item
);
1393 end Replace_Element
;
1399 function Right_Son
(Node
: Node_Type
) return Count_Type
is
1409 (Node
: in out Node_Type
;
1410 Color
: Red_Black_Trees
.Color_Type
)
1413 Node
.Color
:= Color
;
1420 procedure Set_Left
(Node
: in out Node_Type
; Left
: Count_Type
) is
1429 procedure Set_Parent
(Node
: in out Node_Type
; Parent
: Count_Type
) is
1431 Node
.Parent
:= Parent
;
1438 procedure Set_Right
(Node
: in out Node_Type
; Right
: Count_Type
) is
1440 Node
.Right
:= Right
;
1447 function Strict_Equal
(Left
, Right
: Set
) return Boolean is
1448 LNode
: Count_Type
:= First
(Left
).Node
;
1449 RNode
: Count_Type
:= First
(Right
).Node
;
1452 if Length
(Left
) /= Length
(Right
) then
1456 while LNode
= RNode
loop
1461 if Left
.Nodes
(LNode
).Element
/= Right
.Nodes
(RNode
).Element
then
1465 LNode
:= Next
(Left
, LNode
);
1466 RNode
:= Next
(Right
, RNode
);
1472 --------------------------
1473 -- Symmetric_Difference --
1474 --------------------------
1476 procedure Symmetric_Difference
(Target
: in out Set
; Source
: Set
) is
1478 Set_Ops
.Set_Symmetric_Difference
(Target
, Source
);
1479 end Symmetric_Difference
;
1481 function Symmetric_Difference
(Left
, Right
: Set
) return Set
is
1483 if Left
'Address = Right
'Address then
1487 if Length
(Right
) = 0 then
1491 if Length
(Left
) = 0 then
1495 return S
: Set
(Length
(Left
) + Length
(Right
)) do
1496 Assign
(S
, Set_Ops
.Set_Symmetric_Difference
(Left
, Right
));
1498 end Symmetric_Difference
;
1504 function To_Set
(New_Item
: Element_Type
) return Set
is
1508 return S
: Set
(Capacity
=> 1) do
1509 Insert_Sans_Hint
(S
, New_Item
, Node
, Inserted
);
1510 pragma Assert
(Inserted
);
1518 procedure Union
(Target
: in out Set
; Source
: Set
) is
1520 Set_Ops
.Set_Union
(Target
, Source
);
1523 function Union
(Left
, Right
: Set
) return Set
is
1525 if Left
'Address = Right
'Address then
1529 if Length
(Left
) = 0 then
1533 if Length
(Right
) = 0 then
1537 return S
: Set
(Length
(Left
) + Length
(Right
)) do
1538 Assign
(S
, Source
=> Left
);
1543 end Ada
.Containers
.Formal_Ordered_Sets
;