1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.FUNCTIONAL_BASE --
9 -- Copyright (C) 2016-2018, 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 3, 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. --
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
23 -- additional permissions described in the GCC Runtime Library Exception, --
24 -- version 3.1, as published by the Free Software Foundation. --
26 -- You should have received a copy of the GNU General Public License and --
27 -- a copy of the GCC Runtime Library Exception along with this program; --
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
29 -- <http://www.gnu.org/licenses/>. --
30 ------------------------------------------------------------------------------
34 package body Ada
.Containers
.Functional_Base
with SPARK_Mode
=> Off
is
36 function To_Count
(Idx
: Extended_Index
) return Count_Type
is
38 (Extended_Index
'Pos (Idx
) -
39 Extended_Index
'Pos (Extended_Index
'First)));
41 function To_Index
(Position
: Count_Type
) return Extended_Index
is
43 (Position
+ Extended_Index
'Pos (Extended_Index
'First)));
44 -- Conversion functions between Index_Type and Count_Type
46 function Find
(C
: Container
; E
: access Element_Type
) return Count_Type
;
47 -- Search a container C for an element equal to E.all, returning the
48 -- position in the underlying array.
54 function "=" (C1
: Container
; C2
: Container
) return Boolean is
56 if C1
.Elements
'Length /= C2
.Elements
'Length then
60 for I
in C1
.Elements
'Range loop
61 if C1
.Elements
(I
).all /= C2
.Elements
(I
).all then
73 function "<=" (C1
: Container
; C2
: Container
) return Boolean is
75 for I
in C1
.Elements
'Range loop
76 if Find
(C2
, C1
.Elements
(I
)) = 0 then
91 E
: Element_Type
) return Container
93 A
: constant Element_Array_Access
:=
94 new Element_Array
'(1 .. C.Elements'Last + 1 => <>);
98 for J in 1 .. C.Elements'Last + 1 loop
99 if J /= To_Count (I) then
101 A (J) := C.Elements (P);
103 A (J) := new Element_Type'(E
);
107 return Container
'(Elements => A);
114 function Find (C : Container; E : access Element_Type) return Count_Type is
116 for I in C.Elements'Range loop
117 if C.Elements (I).all = E.all then
125 function Find (C : Container; E : Element_Type) return Extended_Index is
126 (To_Index (Find (C, E'Unrestricted_Access)));
132 function Get (C : Container; I : Index_Type) return Element_Type is
133 (C.Elements (To_Count (I)).all);
139 function Intersection (C1 : Container; C2 : Container) return Container is
140 A : constant Element_Array_Access :=
141 new Element_Array'(1 .. Num_Overlaps
(C1
, C2
) => <>);
145 for I
in C1
.Elements
'Range loop
146 if Find
(C2
, C1
.Elements
(I
)) > 0 then
148 A
(P
) := C1
.Elements
(I
);
152 return Container
'(Elements => A);
159 function Length (C : Container) return Count_Type is (C.Elements'Length);
161 ---------------------
163 ---------------------
165 function Num_Overlaps (C1 : Container; C2 : Container) return Count_Type is
169 for I in C1.Elements'Range loop
170 if Find (C2, C1.Elements (I)) > 0 then
182 function Remove (C : Container; I : Index_Type) return Container is
183 A : constant Element_Array_Access :=
184 new Element_Array'(1 .. C
.Elements
'Last - 1 => <>);
188 for J
in C
.Elements
'Range loop
189 if J
/= To_Count
(I
) then
191 A
(P
) := C
.Elements
(J
);
195 return Container
'(Elements => A);
205 E : Element_Type) return Container
207 Result : constant Container :=
208 Container'(Elements
=> new Element_Array
'(C.Elements.all));
211 Result.Elements (To_Count (I)) := new Element_Type'(E
);
219 function Union
(C1
: Container
; C2
: Container
) return Container
is
220 N
: constant Count_Type
:= Num_Overlaps
(C1
, C2
);
223 -- if C2 is completely included in C1 then return C1
225 if N
= Length
(C2
) then
229 -- else loop through C2 to find the remaining elements
232 L
: constant Count_Type
:= Length
(C1
) - N
+ Length
(C2
);
233 A
: constant Element_Array_Access
:=
235 (C1.Elements.all & (Length (C1) + 1 .. L => <>));
236 P : Count_Type := Length (C1);
239 for I in C2.Elements'Range loop
240 if Find (C1, C2.Elements (I)) = 0 then
242 A (P) := C2.Elements (I);
246 return Container'(Elements
=> A
);
250 end Ada
.Containers
.Functional_Base
;