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-2015, 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
with
45 ------------------------------
46 -- Access to Fields of Node --
47 ------------------------------
49 -- These subprograms provide functional notation for access to fields
50 -- of a node, and procedural notation for modifiying these fields.
52 function Color
(Node
: Node_Type
) return Red_Black_Trees
.Color_Type
;
53 pragma Inline
(Color
);
55 function Left_Son
(Node
: Node_Type
) return Count_Type
;
56 pragma Inline
(Left_Son
);
58 function Parent
(Node
: Node_Type
) return Count_Type
;
59 pragma Inline
(Parent
);
61 function Right_Son
(Node
: Node_Type
) return Count_Type
;
62 pragma Inline
(Right_Son
);
65 (Node
: in out Node_Type
;
66 Color
: Red_Black_Trees
.Color_Type
);
67 pragma Inline
(Set_Color
);
69 procedure Set_Left
(Node
: in out Node_Type
; Left
: Count_Type
);
70 pragma Inline
(Set_Left
);
72 procedure Set_Right
(Node
: in out Node_Type
; Right
: Count_Type
);
73 pragma Inline
(Set_Right
);
75 procedure Set_Parent
(Node
: in out Node_Type
; Parent
: Count_Type
);
76 pragma Inline
(Set_Parent
);
78 -----------------------
79 -- Local Subprograms --
80 -----------------------
85 with procedure Set_Element
(Node
: in out Node_Type
);
86 procedure Generic_Allocate
87 (Tree
: in out Tree_Types
.Tree_Type
'Class;
88 Node
: out Count_Type
);
90 procedure Free
(Tree
: in out Set
; X
: Count_Type
);
92 procedure Insert_Sans_Hint
93 (Container
: in out Set
;
94 New_Item
: Element_Type
;
95 Node
: out Count_Type
;
96 Inserted
: out Boolean);
98 procedure Insert_With_Hint
99 (Dst_Set
: in out Set
;
100 Dst_Hint
: Count_Type
;
101 Src_Node
: Node_Type
;
102 Dst_Node
: out Count_Type
);
104 function Is_Greater_Element_Node
105 (Left
: Element_Type
;
106 Right
: Node_Type
) return Boolean;
107 pragma Inline
(Is_Greater_Element_Node
);
109 function Is_Less_Element_Node
110 (Left
: Element_Type
;
111 Right
: Node_Type
) return Boolean;
112 pragma Inline
(Is_Less_Element_Node
);
114 function Is_Less_Node_Node
(L
, R
: Node_Type
) return Boolean;
115 pragma Inline
(Is_Less_Node_Node
);
117 procedure Replace_Element
120 Item
: Element_Type
);
122 --------------------------
123 -- Local Instantiations --
124 --------------------------
126 package Tree_Operations
is
127 new Red_Black_Trees
.Generic_Bounded_Operations
134 package Element_Keys
is
135 new Red_Black_Trees
.Generic_Bounded_Keys
136 (Tree_Operations
=> Tree_Operations
,
137 Key_Type
=> Element_Type
,
138 Is_Less_Key_Node
=> Is_Less_Element_Node
,
139 Is_Greater_Key_Node
=> Is_Greater_Element_Node
);
142 new Red_Black_Trees
.Generic_Bounded_Set_Operations
143 (Tree_Operations
=> Tree_Operations
,
146 Insert_With_Hint
=> Insert_With_Hint
,
147 Is_Less
=> Is_Less_Node_Node
);
153 function "=" (Left
, Right
: Set
) return Boolean is
159 if Length
(Left
) /= Length
(Right
) then
163 if Is_Empty
(Left
) then
167 Lst
:= Next
(Left
, Last
(Left
).Node
);
169 Node
:= First
(Left
).Node
;
170 while Node
/= Lst
loop
171 ENode
:= Find
(Right
, Left
.Nodes
(Node
).Element
).Node
;
173 or else Left
.Nodes
(Node
).Element
/= Right
.Nodes
(ENode
).Element
178 Node
:= Next
(Left
, Node
);
188 procedure Assign
(Target
: in out Set
; Source
: Set
) is
189 procedure Append_Element
(Source_Node
: Count_Type
);
191 procedure Append_Elements
is
192 new Tree_Operations
.Generic_Iteration
(Append_Element
);
198 procedure Append_Element
(Source_Node
: Count_Type
) is
199 SN
: Node_Type
renames Source
.Nodes
(Source_Node
);
201 procedure Set_Element
(Node
: in out Node_Type
);
202 pragma Inline
(Set_Element
);
204 function New_Node
return Count_Type
;
205 pragma Inline
(New_Node
);
207 procedure Insert_Post
is
208 new Element_Keys
.Generic_Insert_Post
(New_Node
);
210 procedure Unconditional_Insert_Sans_Hint
is
211 new Element_Keys
.Generic_Unconditional_Insert
(Insert_Post
);
213 procedure Unconditional_Insert_Avec_Hint
is
214 new Element_Keys
.Generic_Unconditional_Insert_With_Hint
216 Unconditional_Insert_Sans_Hint
);
218 procedure Allocate
is new Generic_Allocate
(Set_Element
);
224 function New_Node
return Count_Type
is
227 Allocate
(Target
, Result
);
235 procedure Set_Element
(Node
: in out Node_Type
) is
237 Node
.Element
:= SN
.Element
;
242 Target_Node
: Count_Type
;
244 -- Start of processing for Append_Element
247 Unconditional_Insert_Avec_Hint
251 Node
=> Target_Node
);
254 -- Start of processing for Assign
257 if Target
'Address = Source
'Address then
261 if Target
.Capacity
< Source
.Length
then
262 raise Constraint_Error
263 with "Target capacity is less than Source length";
266 Tree_Operations
.Clear_Tree
(Target
);
267 Append_Elements
(Source
);
274 function Ceiling
(Container
: Set
; Item
: Element_Type
) return Cursor
is
275 Node
: constant Count_Type
:= Element_Keys
.Ceiling
(Container
, Item
);
282 return (Node
=> Node
);
289 procedure Clear
(Container
: in out Set
) is
291 Tree_Operations
.Clear_Tree
(Container
);
298 function Color
(Node
: Node_Type
) return Red_Black_Trees
.Color_Type
is
309 Item
: Element_Type
) return Boolean
312 return Find
(Container
, Item
) /= No_Element
;
319 function Copy
(Source
: Set
; Capacity
: Count_Type
:= 0) return Set
is
322 Target
: Set
(Count_Type
'Max (Source
.Capacity
, Capacity
));
325 if 0 < Capacity
and then Capacity
< Source
.Capacity
then
326 raise Capacity_Error
;
329 if Length
(Source
) > 0 then
330 Target
.Length
:= Source
.Length
;
331 Target
.Root
:= Source
.Root
;
332 Target
.First
:= Source
.First
;
333 Target
.Last
:= Source
.Last
;
334 Target
.Free
:= Source
.Free
;
337 while Node
<= Source
.Capacity
loop
338 Target
.Nodes
(Node
).Element
:=
339 Source
.Nodes
(Node
).Element
;
340 Target
.Nodes
(Node
).Parent
:=
341 Source
.Nodes
(Node
).Parent
;
342 Target
.Nodes
(Node
).Left
:=
343 Source
.Nodes
(Node
).Left
;
344 Target
.Nodes
(Node
).Right
:=
345 Source
.Nodes
(Node
).Right
;
346 Target
.Nodes
(Node
).Color
:=
347 Source
.Nodes
(Node
).Color
;
348 Target
.Nodes
(Node
).Has_Element
:=
349 Source
.Nodes
(Node
).Has_Element
;
353 while Node
<= Target
.Capacity
loop
355 Formal_Ordered_Sets
.Free
(Tree
=> Target
, X
=> N
);
363 ---------------------
364 -- Current_To_Last --
365 ---------------------
367 function Current_To_Last
(Container
: Set
; Current
: Cursor
) return Set
is
368 Curs
: Cursor
:= First
(Container
);
369 C
: Set
(Container
.Capacity
) := Copy
(Container
, Container
.Capacity
);
373 if Curs
= No_Element
then
378 if Current
/= No_Element
and not Has_Element
(Container
, Current
) then
379 raise Constraint_Error
;
382 while Curs
.Node
/= Current
.Node
loop
385 Curs
:= Next
(Container
, (Node
=> Node
));
395 procedure Delete
(Container
: in out Set
; Position
: in out Cursor
) is
397 if not Has_Element
(Container
, Position
) then
398 raise Constraint_Error
with "Position cursor has no element";
401 pragma Assert
(Vet
(Container
, Position
.Node
),
402 "bad cursor in Delete");
404 Tree_Operations
.Delete_Node_Sans_Free
(Container
,
406 Formal_Ordered_Sets
.Free
(Container
, Position
.Node
);
407 Position
:= No_Element
;
410 procedure Delete
(Container
: in out Set
; Item
: Element_Type
) is
411 X
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
415 raise Constraint_Error
with "attempt to delete element not in set";
418 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
419 Formal_Ordered_Sets
.Free
(Container
, X
);
426 procedure Delete_First
(Container
: in out Set
) is
427 X
: constant Count_Type
:= Container
.First
;
430 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
431 Formal_Ordered_Sets
.Free
(Container
, X
);
439 procedure Delete_Last
(Container
: in out Set
) is
440 X
: constant Count_Type
:= Container
.Last
;
443 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
444 Formal_Ordered_Sets
.Free
(Container
, X
);
452 procedure Difference
(Target
: in out Set
; Source
: Set
) is
454 Set_Ops
.Set_Difference
(Target
, Source
);
457 function Difference
(Left
, Right
: Set
) return Set
is
459 if Left
'Address = Right
'Address then
463 if Length
(Left
) = 0 then
467 if Length
(Right
) = 0 then
471 return S
: Set
(Length
(Left
)) do
472 Assign
(S
, Set_Ops
.Set_Difference
(Left
, Right
));
480 function Element
(Container
: Set
; Position
: Cursor
) return Element_Type
is
482 if not Has_Element
(Container
, Position
) then
483 raise Constraint_Error
with "Position cursor has no element";
486 pragma Assert
(Vet
(Container
, Position
.Node
),
487 "bad cursor in Element");
489 return Container
.Nodes
(Position
.Node
).Element
;
492 -------------------------
493 -- Equivalent_Elements --
494 -------------------------
496 function Equivalent_Elements
(Left
, Right
: Element_Type
) return Boolean is
505 end Equivalent_Elements
;
507 ---------------------
508 -- Equivalent_Sets --
509 ---------------------
511 function Equivalent_Sets
(Left
, Right
: Set
) return Boolean is
512 function Is_Equivalent_Node_Node
513 (L
, R
: Node_Type
) return Boolean;
514 pragma Inline
(Is_Equivalent_Node_Node
);
516 function Is_Equivalent
is
517 new Tree_Operations
.Generic_Equal
(Is_Equivalent_Node_Node
);
519 -----------------------------
520 -- Is_Equivalent_Node_Node --
521 -----------------------------
523 function Is_Equivalent_Node_Node
(L
, R
: Node_Type
) return Boolean is
525 if L
.Element
< R
.Element
then
527 elsif R
.Element
< L
.Element
then
532 end Is_Equivalent_Node_Node
;
534 -- Start of processing for Equivalent_Sets
537 return Is_Equivalent
(Left
, Right
);
544 procedure Exclude
(Container
: in out Set
; Item
: Element_Type
) is
545 X
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
548 Tree_Operations
.Delete_Node_Sans_Free
(Container
, X
);
549 Formal_Ordered_Sets
.Free
(Container
, X
);
557 function Find
(Container
: Set
; Item
: Element_Type
) return Cursor
is
558 Node
: constant Count_Type
:= Element_Keys
.Find
(Container
, Item
);
565 return (Node
=> Node
);
572 function First
(Container
: Set
) return Cursor
is
574 if Length
(Container
) = 0 then
578 return (Node
=> Container
.First
);
585 function First_Element
(Container
: Set
) return Element_Type
is
586 Fst
: constant Count_Type
:= First
(Container
).Node
;
589 raise Constraint_Error
with "set is empty";
593 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
595 return N
(Fst
).Element
;
599 -----------------------
600 -- First_To_Previous --
601 -----------------------
603 function First_To_Previous
605 Current
: Cursor
) return Set
607 Curs
: Cursor
:= Current
;
608 C
: Set
(Container
.Capacity
) := Copy
(Container
, Container
.Capacity
);
612 if Curs
= No_Element
then
615 elsif not Has_Element
(Container
, Curs
) then
616 raise Constraint_Error
;
619 while Curs
.Node
/= 0 loop
622 Curs
:= Next
(Container
, (Node
=> Node
));
627 end First_To_Previous
;
633 function Floor
(Container
: Set
; Item
: Element_Type
) return Cursor
is
636 Node
: constant Count_Type
:= Element_Keys
.Floor
(Container
, Item
);
643 return (Node
=> Node
);
651 procedure Free
(Tree
: in out Set
; X
: Count_Type
) is
653 Tree
.Nodes
(X
).Has_Element
:= False;
654 Tree_Operations
.Free
(Tree
, X
);
657 ----------------------
658 -- Generic_Allocate --
659 ----------------------
661 procedure Generic_Allocate
662 (Tree
: in out Tree_Types
.Tree_Type
'Class;
663 Node
: out Count_Type
)
665 procedure Allocate
is
666 new Tree_Operations
.Generic_Allocate
(Set_Element
);
668 Allocate
(Tree
, Node
);
669 Tree
.Nodes
(Node
).Has_Element
:= True;
670 end Generic_Allocate
;
676 package body Generic_Keys
with SPARK_Mode
=> Off
is
678 -----------------------
679 -- Local Subprograms --
680 -----------------------
682 function Is_Greater_Key_Node
684 Right
: Node_Type
) return Boolean;
685 pragma Inline
(Is_Greater_Key_Node
);
687 function Is_Less_Key_Node
689 Right
: Node_Type
) return Boolean;
690 pragma Inline
(Is_Less_Key_Node
);
692 --------------------------
693 -- Local Instantiations --
694 --------------------------
697 new Red_Black_Trees
.Generic_Bounded_Keys
698 (Tree_Operations
=> Tree_Operations
,
699 Key_Type
=> Key_Type
,
700 Is_Less_Key_Node
=> Is_Less_Key_Node
,
701 Is_Greater_Key_Node
=> Is_Greater_Key_Node
);
707 function Ceiling
(Container
: Set
; Key
: Key_Type
) return Cursor
is
708 Node
: constant Count_Type
:= Key_Keys
.Ceiling
(Container
, Key
);
715 return (Node
=> Node
);
722 function Contains
(Container
: Set
; Key
: Key_Type
) return Boolean is
724 return Find
(Container
, Key
) /= No_Element
;
731 procedure Delete
(Container
: in out Set
; Key
: Key_Type
) is
732 X
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
736 raise Constraint_Error
with "attempt to delete key not in set";
739 Delete_Node_Sans_Free
(Container
, X
);
740 Formal_Ordered_Sets
.Free
(Container
, X
);
747 function Element
(Container
: Set
; Key
: Key_Type
) return Element_Type
is
748 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
752 raise Constraint_Error
with "key not in set";
756 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
758 return N
(Node
).Element
;
762 ---------------------
763 -- Equivalent_Keys --
764 ---------------------
766 function Equivalent_Keys
(Left
, Right
: Key_Type
) return Boolean is
781 procedure Exclude
(Container
: in out Set
; Key
: Key_Type
) is
782 X
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
785 Delete_Node_Sans_Free
(Container
, X
);
786 Formal_Ordered_Sets
.Free
(Container
, X
);
794 function Find
(Container
: Set
; Key
: Key_Type
) return Cursor
is
795 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
797 return (if Node
= 0 then No_Element
else (Node
=> Node
));
804 function Floor
(Container
: Set
; Key
: Key_Type
) return Cursor
is
805 Node
: constant Count_Type
:= Key_Keys
.Floor
(Container
, Key
);
807 return (if Node
= 0 then No_Element
else (Node
=> Node
));
810 -------------------------
811 -- Is_Greater_Key_Node --
812 -------------------------
814 function Is_Greater_Key_Node
816 Right
: Node_Type
) return Boolean
819 return Key
(Right
.Element
) < Left
;
820 end Is_Greater_Key_Node
;
822 ----------------------
823 -- Is_Less_Key_Node --
824 ----------------------
826 function Is_Less_Key_Node
828 Right
: Node_Type
) return Boolean
831 return Left
< Key
(Right
.Element
);
832 end Is_Less_Key_Node
;
838 function Key
(Container
: Set
; Position
: Cursor
) return Key_Type
is
840 if not Has_Element
(Container
, Position
) then
841 raise Constraint_Error
with
842 "Position cursor has no element";
845 pragma Assert
(Vet
(Container
, Position
.Node
),
846 "bad cursor in Key");
849 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
851 return Key
(N
(Position
.Node
).Element
);
860 (Container
: in out Set
;
862 New_Item
: Element_Type
)
864 Node
: constant Count_Type
:= Key_Keys
.Find
(Container
, Key
);
866 if not Has_Element
(Container
, (Node
=> Node
)) then
867 raise Constraint_Error
with
868 "attempt to replace key not in set";
870 Replace_Element
(Container
, Node
, New_Item
);
880 function Has_Element
(Container
: Set
; Position
: Cursor
) return Boolean is
882 if Position
.Node
= 0 then
885 return Container
.Nodes
(Position
.Node
).Has_Element
;
893 procedure Include
(Container
: in out Set
; New_Item
: Element_Type
) is
898 Insert
(Container
, New_Item
, Position
, Inserted
);
902 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
904 N
(Position
.Node
).Element
:= New_Item
;
914 (Container
: in out Set
;
915 New_Item
: Element_Type
;
916 Position
: out Cursor
;
917 Inserted
: out Boolean)
920 Insert_Sans_Hint
(Container
, New_Item
, Position
.Node
, Inserted
);
924 (Container
: in out Set
;
925 New_Item
: Element_Type
)
931 Insert
(Container
, New_Item
, Position
, Inserted
);
934 raise Constraint_Error
with
935 "attempt to insert element already in set";
939 ----------------------
940 -- Insert_Sans_Hint --
941 ----------------------
943 procedure Insert_Sans_Hint
944 (Container
: in out Set
;
945 New_Item
: Element_Type
;
946 Node
: out Count_Type
;
947 Inserted
: out Boolean)
949 procedure Set_Element
(Node
: in out Node_Type
);
951 function New_Node
return Count_Type
;
952 pragma Inline
(New_Node
);
954 procedure Insert_Post
is
955 new Element_Keys
.Generic_Insert_Post
(New_Node
);
957 procedure Conditional_Insert_Sans_Hint
is
958 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
960 procedure Allocate
is new Generic_Allocate
(Set_Element
);
966 function New_Node
return Count_Type
is
969 Allocate
(Container
, Result
);
977 procedure Set_Element
(Node
: in out Node_Type
) is
979 Node
.Element
:= New_Item
;
982 -- Start of processing for Insert_Sans_Hint
985 Conditional_Insert_Sans_Hint
990 end Insert_Sans_Hint
;
992 ----------------------
993 -- Insert_With_Hint --
994 ----------------------
996 procedure Insert_With_Hint
997 (Dst_Set
: in out Set
;
998 Dst_Hint
: Count_Type
;
999 Src_Node
: Node_Type
;
1000 Dst_Node
: out Count_Type
)
1003 pragma Unreferenced
(Success
);
1005 procedure Set_Element
(Node
: in out Node_Type
);
1007 function New_Node
return Count_Type
;
1008 pragma Inline
(New_Node
);
1010 procedure Insert_Post
is
1011 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1013 procedure Insert_Sans_Hint
is
1014 new Element_Keys
.Generic_Conditional_Insert
(Insert_Post
);
1016 procedure Local_Insert_With_Hint
is
1017 new Element_Keys
.Generic_Conditional_Insert_With_Hint
1018 (Insert_Post
, Insert_Sans_Hint
);
1020 procedure Allocate
is new Generic_Allocate
(Set_Element
);
1026 function New_Node
return Count_Type
is
1027 Result
: Count_Type
;
1029 Allocate
(Dst_Set
, Result
);
1037 procedure Set_Element
(Node
: in out Node_Type
) is
1039 Node
.Element
:= Src_Node
.Element
;
1042 -- Start of processing for Insert_With_Hint
1045 Local_Insert_With_Hint
1051 end Insert_With_Hint
;
1057 procedure Intersection
(Target
: in out Set
; Source
: Set
) is
1059 Set_Ops
.Set_Intersection
(Target
, Source
);
1062 function Intersection
(Left
, Right
: Set
) return Set
is
1064 if Left
'Address = Right
'Address then
1068 return S
: Set
(Count_Type
'Min (Length
(Left
), Length
(Right
))) do
1069 Assign
(S
, Set_Ops
.Set_Intersection
(Left
, Right
));
1077 function Is_Empty
(Container
: Set
) return Boolean is
1079 return Length
(Container
) = 0;
1082 -----------------------------
1083 -- Is_Greater_Element_Node --
1084 -----------------------------
1086 function Is_Greater_Element_Node
1087 (Left
: Element_Type
;
1088 Right
: Node_Type
) return Boolean
1091 -- Compute e > node same as node < e
1093 return Right
.Element
< Left
;
1094 end Is_Greater_Element_Node
;
1096 --------------------------
1097 -- Is_Less_Element_Node --
1098 --------------------------
1100 function Is_Less_Element_Node
1101 (Left
: Element_Type
;
1102 Right
: Node_Type
) return Boolean
1105 return Left
< Right
.Element
;
1106 end Is_Less_Element_Node
;
1108 -----------------------
1109 -- Is_Less_Node_Node --
1110 -----------------------
1112 function Is_Less_Node_Node
(L
, R
: Node_Type
) return Boolean is
1114 return L
.Element
< R
.Element
;
1115 end Is_Less_Node_Node
;
1121 function Is_Subset
(Subset
: Set
; Of_Set
: Set
) return Boolean is
1123 return Set_Ops
.Set_Subset
(Subset
, Of_Set
=> Of_Set
);
1130 function Last
(Container
: Set
) return Cursor
is
1132 return (if Length
(Container
) = 0
1134 else (Node
=> Container
.Last
));
1141 function Last_Element
(Container
: Set
) return Element_Type
is
1143 if Last
(Container
).Node
= 0 then
1144 raise Constraint_Error
with "set is empty";
1148 N
: Tree_Types
.Nodes_Type
renames Container
.Nodes
;
1150 return N
(Last
(Container
).Node
).Element
;
1158 function Left_Son
(Node
: Node_Type
) return Count_Type
is
1167 function Length
(Container
: Set
) return Count_Type
is
1169 return Container
.Length
;
1176 procedure Move
(Target
: in out Set
; Source
: in out Set
) is
1177 N
: Tree_Types
.Nodes_Type
renames Source
.Nodes
;
1181 if Target
'Address = Source
'Address then
1185 if Target
.Capacity
< Length
(Source
) then
1186 raise Constraint_Error
with -- ???
1187 "Source length exceeds Target capacity";
1196 Insert
(Target
, N
(X
).Element
); -- optimize???
1198 Tree_Operations
.Delete_Node_Sans_Free
(Source
, X
);
1199 Formal_Ordered_Sets
.Free
(Source
, X
);
1207 function Next
(Container
: Set
; Position
: Cursor
) return Cursor
is
1209 if Position
= No_Element
then
1213 if not Has_Element
(Container
, Position
) then
1214 raise Constraint_Error
;
1217 pragma Assert
(Vet
(Container
, Position
.Node
),
1218 "bad cursor in Next");
1219 return (Node
=> Tree_Operations
.Next
(Container
, Position
.Node
));
1222 procedure Next
(Container
: Set
; Position
: in out Cursor
) is
1224 Position
:= Next
(Container
, Position
);
1231 function Overlap
(Left
, Right
: Set
) return Boolean is
1233 return Set_Ops
.Set_Overlap
(Left
, Right
);
1240 function Parent
(Node
: Node_Type
) return Count_Type
is
1249 function Previous
(Container
: Set
; Position
: Cursor
) return Cursor
is
1251 if Position
= No_Element
then
1255 if not Has_Element
(Container
, Position
) then
1256 raise Constraint_Error
;
1259 pragma Assert
(Vet
(Container
, Position
.Node
),
1260 "bad cursor in Previous");
1263 Node
: constant Count_Type
:=
1264 Tree_Operations
.Previous
(Container
, Position
.Node
);
1266 return (if Node
= 0 then No_Element
else (Node
=> Node
));
1270 procedure Previous
(Container
: Set
; Position
: in out Cursor
) is
1272 Position
:= Previous
(Container
, Position
);
1279 procedure Replace
(Container
: in out Set
; New_Item
: Element_Type
) is
1280 Node
: constant Count_Type
:= Element_Keys
.Find
(Container
, New_Item
);
1284 raise Constraint_Error
with
1285 "attempt to replace element not in set";
1288 Container
.Nodes
(Node
).Element
:= New_Item
;
1291 ---------------------
1292 -- Replace_Element --
1293 ---------------------
1295 procedure Replace_Element
1298 Item
: Element_Type
)
1300 pragma Assert
(Node
/= 0);
1302 function New_Node
return Count_Type
;
1303 pragma Inline
(New_Node
);
1305 procedure Local_Insert_Post
is
1306 new Element_Keys
.Generic_Insert_Post
(New_Node
);
1308 procedure Local_Insert_Sans_Hint
is
1309 new Element_Keys
.Generic_Conditional_Insert
(Local_Insert_Post
);
1311 procedure Local_Insert_With_Hint
is
1312 new Element_Keys
.Generic_Conditional_Insert_With_Hint
1314 Local_Insert_Sans_Hint
);
1316 NN
: Tree_Types
.Nodes_Type
renames Tree
.Nodes
;
1322 function New_Node
return Count_Type
is
1323 N
: Node_Type
renames NN
(Node
);
1334 Result
: Count_Type
;
1337 -- Start of processing for Insert
1340 if Item
< NN
(Node
).Element
1341 or else NN
(Node
).Element
< Item
1346 NN
(Node
).Element
:= Item
;
1350 Hint
:= Element_Keys
.Ceiling
(Tree
, Item
);
1355 elsif Item
< NN
(Hint
).Element
then
1357 NN
(Node
).Element
:= Item
;
1362 pragma Assert
(not (NN
(Hint
).Element
< Item
));
1363 raise Program_Error
with "attempt to replace existing element";
1366 Tree_Operations
.Delete_Node_Sans_Free
(Tree
, Node
);
1368 Local_Insert_With_Hint
1373 Inserted
=> Inserted
);
1375 pragma Assert
(Inserted
);
1376 pragma Assert
(Result
= Node
);
1377 end Replace_Element
;
1379 procedure Replace_Element
1380 (Container
: in out Set
;
1382 New_Item
: Element_Type
)
1385 if not Has_Element
(Container
, Position
) then
1386 raise Constraint_Error
with
1387 "Position cursor has no element";
1390 pragma Assert
(Vet
(Container
, Position
.Node
),
1391 "bad cursor in Replace_Element");
1393 Replace_Element
(Container
, Position
.Node
, New_Item
);
1394 end Replace_Element
;
1400 function Right_Son
(Node
: Node_Type
) return Count_Type
is
1410 (Node
: in out Node_Type
;
1411 Color
: Red_Black_Trees
.Color_Type
)
1414 Node
.Color
:= Color
;
1421 procedure Set_Left
(Node
: in out Node_Type
; Left
: Count_Type
) is
1430 procedure Set_Parent
(Node
: in out Node_Type
; Parent
: Count_Type
) is
1432 Node
.Parent
:= Parent
;
1439 procedure Set_Right
(Node
: in out Node_Type
; Right
: Count_Type
) is
1441 Node
.Right
:= Right
;
1448 function Strict_Equal
(Left
, Right
: Set
) return Boolean is
1449 LNode
: Count_Type
:= First
(Left
).Node
;
1450 RNode
: Count_Type
:= First
(Right
).Node
;
1453 if Length
(Left
) /= Length
(Right
) then
1457 while LNode
= RNode
loop
1462 if Left
.Nodes
(LNode
).Element
/= Right
.Nodes
(RNode
).Element
then
1466 LNode
:= Next
(Left
, LNode
);
1467 RNode
:= Next
(Right
, RNode
);
1473 --------------------------
1474 -- Symmetric_Difference --
1475 --------------------------
1477 procedure Symmetric_Difference
(Target
: in out Set
; Source
: Set
) is
1479 Set_Ops
.Set_Symmetric_Difference
(Target
, Source
);
1480 end Symmetric_Difference
;
1482 function Symmetric_Difference
(Left
, Right
: Set
) return Set
is
1484 if Left
'Address = Right
'Address then
1488 if Length
(Right
) = 0 then
1492 if Length
(Left
) = 0 then
1496 return S
: Set
(Length
(Left
) + Length
(Right
)) do
1497 Assign
(S
, Set_Ops
.Set_Symmetric_Difference
(Left
, Right
));
1499 end Symmetric_Difference
;
1505 function To_Set
(New_Item
: Element_Type
) return Set
is
1509 return S
: Set
(Capacity
=> 1) do
1510 Insert_Sans_Hint
(S
, New_Item
, Node
, Inserted
);
1511 pragma Assert
(Inserted
);
1519 procedure Union
(Target
: in out Set
; Source
: Set
) is
1521 Set_Ops
.Set_Union
(Target
, Source
);
1524 function Union
(Left
, Right
: Set
) return Set
is
1526 if Left
'Address = Right
'Address then
1530 if Length
(Left
) = 0 then
1534 if Length
(Right
) = 0 then
1538 return S
: Set
(Length
(Left
) + Length
(Right
)) do
1539 Assign
(S
, Source
=> Left
);
1544 end Ada
.Containers
.Formal_Ordered_Sets
;