annotate gcc/ada/libgnat/a-cfinve.ads @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- ADA.CONTAINERS.FORMAL_INDEFINITE_VECTORS --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- S p e c --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2014-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- This specification is derived from the Ada Reference Manual for use with --
kono
parents:
diff changeset
12 -- GNAT. The copyright notice above, and the license provisions that follow --
kono
parents:
diff changeset
13 -- apply solely to the contents of the part following the private keyword. --
kono
parents:
diff changeset
14 -- --
kono
parents:
diff changeset
15 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
16 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
17 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
20 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
23 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
24 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
25 -- --
kono
parents:
diff changeset
26 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
27 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
29 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- Similar to Ada.Containers.Formal_Vectors. The main difference is that
kono
parents:
diff changeset
33 -- Element_Type may be indefinite (but not an unconstrained array).
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 with Ada.Containers.Bounded_Holders;
kono
parents:
diff changeset
36 with Ada.Containers.Functional_Vectors;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 generic
kono
parents:
diff changeset
39 type Index_Type is range <>;
kono
parents:
diff changeset
40 type Element_Type (<>) is private;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
41 with function "=" (Left, Right : Element_Type) return Boolean is <>;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
42 Max_Size_In_Storage_Elements : Natural;
111
kono
parents:
diff changeset
43 -- Maximum size of Vector elements in bytes. This has the same meaning as
kono
parents:
diff changeset
44 -- in Ada.Containers.Bounded_Holders, with the same restrictions. Note that
kono
parents:
diff changeset
45 -- setting this too small can lead to erroneous execution; see comments in
kono
parents:
diff changeset
46 -- Ada.Containers.Bounded_Holders. If Element_Type is class-wide, it is the
kono
parents:
diff changeset
47 -- responsibility of clients to calculate the maximum size of all types in
kono
parents:
diff changeset
48 -- the class.
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 Bounded : Boolean := True;
kono
parents:
diff changeset
51 -- If True, the containers are bounded; the initial capacity is the maximum
kono
parents:
diff changeset
52 -- size, and heap allocation will be avoided. If False, the containers can
kono
parents:
diff changeset
53 -- grow via heap allocation.
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 package Ada.Containers.Formal_Indefinite_Vectors with
kono
parents:
diff changeset
56 SPARK_Mode => On
kono
parents:
diff changeset
57 is
kono
parents:
diff changeset
58 pragma Annotate (CodePeer, Skip_Analysis);
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 subtype Extended_Index is Index_Type'Base
kono
parents:
diff changeset
61 range Index_Type'First - 1 ..
kono
parents:
diff changeset
62 Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 No_Index : constant Extended_Index := Extended_Index'First;
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 Last_Count : constant Count_Type :=
kono
parents:
diff changeset
67 (if Index_Type'Last < Index_Type'First then
kono
parents:
diff changeset
68 0
kono
parents:
diff changeset
69 elsif Index_Type'Last < -1
kono
parents:
diff changeset
70 or else Index_Type'Pos (Index_Type'First) >
kono
parents:
diff changeset
71 Index_Type'Pos (Index_Type'Last) - Count_Type'Last
kono
parents:
diff changeset
72 then
kono
parents:
diff changeset
73 Index_Type'Pos (Index_Type'Last) -
kono
parents:
diff changeset
74 Index_Type'Pos (Index_Type'First) + 1
kono
parents:
diff changeset
75 else
kono
parents:
diff changeset
76 Count_Type'Last);
kono
parents:
diff changeset
77 -- Maximal capacity of any vector. It is the minimum of the size of the
kono
parents:
diff changeset
78 -- index range and the last possible Count_Type.
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 subtype Capacity_Range is Count_Type range 0 .. Last_Count;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 type Vector (Capacity : Capacity_Range) is limited private with
kono
parents:
diff changeset
83 Default_Initial_Condition => Is_Empty (Vector);
kono
parents:
diff changeset
84 -- In the bounded case, Capacity is the capacity of the container, which
kono
parents:
diff changeset
85 -- never changes. In the unbounded case, Capacity is the initial capacity
kono
parents:
diff changeset
86 -- of the container, and operations such as Reserve_Capacity and Append can
kono
parents:
diff changeset
87 -- increase the capacity. The capacity never shrinks, except in the case of
kono
parents:
diff changeset
88 -- Clear.
kono
parents:
diff changeset
89 --
kono
parents:
diff changeset
90 -- Note that all objects of type Vector are constrained, including in the
kono
parents:
diff changeset
91 -- unbounded case; you can't assign from one object to another if the
kono
parents:
diff changeset
92 -- Capacity is different.
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 function Length (Container : Vector) return Capacity_Range with
kono
parents:
diff changeset
95 Global => null,
kono
parents:
diff changeset
96 Post => Length'Result <= Capacity (Container);
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 pragma Unevaluated_Use_Of_Old (Allow);
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 package Formal_Model with Ghost is
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 package M is new Ada.Containers.Functional_Vectors
kono
parents:
diff changeset
103 (Index_Type => Index_Type,
kono
parents:
diff changeset
104 Element_Type => Element_Type);
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 function "="
kono
parents:
diff changeset
107 (Left : M.Sequence;
kono
parents:
diff changeset
108 Right : M.Sequence) return Boolean renames M."=";
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 function "<"
kono
parents:
diff changeset
111 (Left : M.Sequence;
kono
parents:
diff changeset
112 Right : M.Sequence) return Boolean renames M."<";
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 function "<="
kono
parents:
diff changeset
115 (Left : M.Sequence;
kono
parents:
diff changeset
116 Right : M.Sequence) return Boolean renames M."<=";
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 function M_Elements_In_Union
kono
parents:
diff changeset
119 (Container : M.Sequence;
kono
parents:
diff changeset
120 Left : M.Sequence;
kono
parents:
diff changeset
121 Right : M.Sequence) return Boolean
kono
parents:
diff changeset
122 -- The elements of Container are contained in either Left or Right
kono
parents:
diff changeset
123 with
kono
parents:
diff changeset
124 Global => null,
kono
parents:
diff changeset
125 Post =>
kono
parents:
diff changeset
126 M_Elements_In_Union'Result =
kono
parents:
diff changeset
127 (for all I in Index_Type'First .. M.Last (Container) =>
kono
parents:
diff changeset
128 (for some J in Index_Type'First .. M.Last (Left) =>
kono
parents:
diff changeset
129 Element (Container, I) = Element (Left, J))
kono
parents:
diff changeset
130 or (for some J in Index_Type'First .. M.Last (Right) =>
kono
parents:
diff changeset
131 Element (Container, I) = Element (Right, J)));
kono
parents:
diff changeset
132 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_In_Union);
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 function M_Elements_Included
kono
parents:
diff changeset
135 (Left : M.Sequence;
kono
parents:
diff changeset
136 L_Fst : Index_Type := Index_Type'First;
kono
parents:
diff changeset
137 L_Lst : Extended_Index;
kono
parents:
diff changeset
138 Right : M.Sequence;
kono
parents:
diff changeset
139 R_Fst : Index_Type := Index_Type'First;
kono
parents:
diff changeset
140 R_Lst : Extended_Index) return Boolean
kono
parents:
diff changeset
141 -- The elements of the slice from L_Fst to L_Lst in Left are contained
kono
parents:
diff changeset
142 -- in the slide from R_Fst to R_Lst in Right.
kono
parents:
diff changeset
143 with
kono
parents:
diff changeset
144 Global => null,
kono
parents:
diff changeset
145 Pre => L_Lst <= M.Last (Left) and R_Lst <= M.Last (Right),
kono
parents:
diff changeset
146 Post =>
kono
parents:
diff changeset
147 M_Elements_Included'Result =
kono
parents:
diff changeset
148 (for all I in L_Fst .. L_Lst =>
kono
parents:
diff changeset
149 (for some J in R_Fst .. R_Lst =>
kono
parents:
diff changeset
150 Element (Left, I) = Element (Right, J)));
kono
parents:
diff changeset
151 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Included);
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 function M_Elements_Reversed
kono
parents:
diff changeset
154 (Left : M.Sequence;
kono
parents:
diff changeset
155 Right : M.Sequence) return Boolean
kono
parents:
diff changeset
156 -- Right is Left in reverse order
kono
parents:
diff changeset
157 with
kono
parents:
diff changeset
158 Global => null,
kono
parents:
diff changeset
159 Post =>
kono
parents:
diff changeset
160 M_Elements_Reversed'Result =
kono
parents:
diff changeset
161 (M.Length (Left) = M.Length (Right)
kono
parents:
diff changeset
162 and (for all I in Index_Type'First .. M.Last (Left) =>
kono
parents:
diff changeset
163 Element (Left, I) =
kono
parents:
diff changeset
164 Element (Right, M.Last (Left) - I + 1))
kono
parents:
diff changeset
165 and (for all I in Index_Type'First .. M.Last (Right) =>
kono
parents:
diff changeset
166 Element (Right, I) =
kono
parents:
diff changeset
167 Element (Left, M.Last (Left) - I + 1)));
kono
parents:
diff changeset
168 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Reversed);
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 function M_Elements_Swapped
kono
parents:
diff changeset
171 (Left : M.Sequence;
kono
parents:
diff changeset
172 Right : M.Sequence;
kono
parents:
diff changeset
173 X : Index_Type;
kono
parents:
diff changeset
174 Y : Index_Type) return Boolean
kono
parents:
diff changeset
175 -- Elements stored at X and Y are reversed in Left and Right
kono
parents:
diff changeset
176 with
kono
parents:
diff changeset
177 Global => null,
kono
parents:
diff changeset
178 Pre => X <= M.Last (Left) and Y <= M.Last (Left),
kono
parents:
diff changeset
179 Post =>
kono
parents:
diff changeset
180 M_Elements_Swapped'Result =
kono
parents:
diff changeset
181 (M.Length (Left) = M.Length (Right)
kono
parents:
diff changeset
182 and Element (Left, X) = Element (Right, Y)
kono
parents:
diff changeset
183 and Element (Left, Y) = Element (Right, X)
kono
parents:
diff changeset
184 and M.Equal_Except (Left, Right, X, Y));
kono
parents:
diff changeset
185 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Swapped);
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 function Model (Container : Vector) return M.Sequence with
kono
parents:
diff changeset
188 -- The high-level model of a vector is a sequence of elements. The
kono
parents:
diff changeset
189 -- sequence really is similar to the vector itself. However, it is not
kono
parents:
diff changeset
190 -- limited which allows usage of 'Old and 'Loop_Entry attributes.
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 Ghost,
kono
parents:
diff changeset
193 Global => null,
kono
parents:
diff changeset
194 Post => M.Length (Model'Result) = Length (Container);
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 function Element
kono
parents:
diff changeset
197 (S : M.Sequence;
kono
parents:
diff changeset
198 I : Index_Type) return Element_Type renames M.Get;
kono
parents:
diff changeset
199 -- To improve readability of contracts, we rename the function used to
kono
parents:
diff changeset
200 -- access an element in the model to Element.
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 end Formal_Model;
kono
parents:
diff changeset
203 use Formal_Model;
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 function Empty_Vector return Vector with
kono
parents:
diff changeset
206 Global => null,
kono
parents:
diff changeset
207 Post => Length (Empty_Vector'Result) = 0;
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 function "=" (Left, Right : Vector) return Boolean with
kono
parents:
diff changeset
210 Global => null,
kono
parents:
diff changeset
211 Post => "="'Result = (Model (Left) = Model (Right));
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 function To_Vector
kono
parents:
diff changeset
214 (New_Item : Element_Type;
kono
parents:
diff changeset
215 Length : Capacity_Range) return Vector
kono
parents:
diff changeset
216 with
kono
parents:
diff changeset
217 Global => null,
kono
parents:
diff changeset
218 Post =>
kono
parents:
diff changeset
219 Formal_Indefinite_Vectors.Length (To_Vector'Result) = Length
kono
parents:
diff changeset
220 and M.Constant_Range
kono
parents:
diff changeset
221 (Container => Model (To_Vector'Result),
kono
parents:
diff changeset
222 Fst => Index_Type'First,
kono
parents:
diff changeset
223 Lst => Last_Index (To_Vector'Result),
kono
parents:
diff changeset
224 Item => New_Item);
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 function Capacity (Container : Vector) return Capacity_Range with
kono
parents:
diff changeset
227 Global => null,
kono
parents:
diff changeset
228 Post =>
kono
parents:
diff changeset
229 Capacity'Result =
kono
parents:
diff changeset
230 (if Bounded then
kono
parents:
diff changeset
231 Container.Capacity
kono
parents:
diff changeset
232 else
kono
parents:
diff changeset
233 Capacity_Range'Last);
kono
parents:
diff changeset
234 pragma Annotate (GNATprove, Inline_For_Proof, Capacity);
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 procedure Reserve_Capacity
kono
parents:
diff changeset
237 (Container : in out Vector;
kono
parents:
diff changeset
238 Capacity : Capacity_Range)
kono
parents:
diff changeset
239 with
kono
parents:
diff changeset
240 Global => null,
kono
parents:
diff changeset
241 Pre => (if Bounded then Capacity <= Container.Capacity),
kono
parents:
diff changeset
242 Post => Model (Container) = Model (Container)'Old;
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 function Is_Empty (Container : Vector) return Boolean with
kono
parents:
diff changeset
245 Global => null,
kono
parents:
diff changeset
246 Post => Is_Empty'Result = (Length (Container) = 0);
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 procedure Clear (Container : in out Vector) with
kono
parents:
diff changeset
249 Global => null,
kono
parents:
diff changeset
250 Post => Length (Container) = 0;
kono
parents:
diff changeset
251 -- Note that this reclaims storage in the unbounded case. You need to call
kono
parents:
diff changeset
252 -- this before a container goes out of scope in order to avoid storage
kono
parents:
diff changeset
253 -- leaks. In addition, "X := ..." can leak unless you Clear(X) first.
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 procedure Assign (Target : in out Vector; Source : Vector) with
kono
parents:
diff changeset
256 Global => null,
kono
parents:
diff changeset
257 Pre => (if Bounded then Length (Source) <= Target.Capacity),
kono
parents:
diff changeset
258 Post => Model (Target) = Model (Source);
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 function Copy
kono
parents:
diff changeset
261 (Source : Vector;
kono
parents:
diff changeset
262 Capacity : Capacity_Range := 0) return Vector
kono
parents:
diff changeset
263 with
kono
parents:
diff changeset
264 Global => null,
kono
parents:
diff changeset
265 Pre => (if Bounded then (Capacity = 0 or Length (Source) <= Capacity)),
kono
parents:
diff changeset
266 Post =>
kono
parents:
diff changeset
267 Model (Copy'Result) = Model (Source)
kono
parents:
diff changeset
268 and (if Capacity = 0 then
kono
parents:
diff changeset
269 Copy'Result.Capacity = Length (Source)
kono
parents:
diff changeset
270 else
kono
parents:
diff changeset
271 Copy'Result.Capacity = Capacity);
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 procedure Move (Target : in out Vector; Source : in out Vector)
kono
parents:
diff changeset
274 with
kono
parents:
diff changeset
275 Global => null,
kono
parents:
diff changeset
276 Pre => (if Bounded then Length (Source) <= Capacity (Target)),
kono
parents:
diff changeset
277 Post => Model (Target) = Model (Source)'Old and Length (Source) = 0;
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 function Element
kono
parents:
diff changeset
280 (Container : Vector;
kono
parents:
diff changeset
281 Index : Index_Type) return Element_Type
kono
parents:
diff changeset
282 with
kono
parents:
diff changeset
283 Global => null,
kono
parents:
diff changeset
284 Pre => Index in First_Index (Container) .. Last_Index (Container),
kono
parents:
diff changeset
285 Post => Element'Result = Element (Model (Container), Index);
kono
parents:
diff changeset
286 pragma Annotate (GNATprove, Inline_For_Proof, Element);
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 procedure Replace_Element
kono
parents:
diff changeset
289 (Container : in out Vector;
kono
parents:
diff changeset
290 Index : Index_Type;
kono
parents:
diff changeset
291 New_Item : Element_Type)
kono
parents:
diff changeset
292 with
kono
parents:
diff changeset
293 Global => null,
kono
parents:
diff changeset
294 Pre => Index in First_Index (Container) .. Last_Index (Container),
kono
parents:
diff changeset
295 Post =>
kono
parents:
diff changeset
296 Length (Container) = Length (Container)'Old
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 -- Container now has New_Item at index Index
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 and Element (Model (Container), Index) = New_Item
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 -- All other elements are preserved
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 and M.Equal_Except
kono
parents:
diff changeset
305 (Left => Model (Container)'Old,
kono
parents:
diff changeset
306 Right => Model (Container),
kono
parents:
diff changeset
307 Position => Index);
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 procedure Insert
kono
parents:
diff changeset
310 (Container : in out Vector;
kono
parents:
diff changeset
311 Before : Extended_Index;
kono
parents:
diff changeset
312 New_Item : Vector)
kono
parents:
diff changeset
313 with
kono
parents:
diff changeset
314 Global => null,
kono
parents:
diff changeset
315 Pre =>
kono
parents:
diff changeset
316 Length (Container) <= Capacity (Container) - Length (New_Item)
kono
parents:
diff changeset
317 and (Before in Index_Type'First .. Last_Index (Container)
kono
parents:
diff changeset
318 or (Before /= No_Index
kono
parents:
diff changeset
319 and then Before - 1 = Last_Index (Container))),
kono
parents:
diff changeset
320 Post =>
kono
parents:
diff changeset
321 Length (Container) = Length (Container)'Old + Length (New_Item)
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 -- Elements located before Before in Container are preserved
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 and M.Range_Equal
kono
parents:
diff changeset
326 (Left => Model (Container)'Old,
kono
parents:
diff changeset
327 Right => Model (Container),
kono
parents:
diff changeset
328 Fst => Index_Type'First,
kono
parents:
diff changeset
329 Lst => Before - 1)
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 -- Elements of New_Item are inserted at position Before
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 and (if Length (New_Item) > 0 then
kono
parents:
diff changeset
334 M.Range_Shifted
kono
parents:
diff changeset
335 (Left => Model (New_Item),
kono
parents:
diff changeset
336 Right => Model (Container),
kono
parents:
diff changeset
337 Fst => Index_Type'First,
kono
parents:
diff changeset
338 Lst => Last_Index (New_Item),
kono
parents:
diff changeset
339 Offset => Count_Type (Before - Index_Type'First)))
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 -- Elements located after Before in Container are shifted
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 and M.Range_Shifted
kono
parents:
diff changeset
344 (Left => Model (Container)'Old,
kono
parents:
diff changeset
345 Right => Model (Container),
kono
parents:
diff changeset
346 Fst => Before,
kono
parents:
diff changeset
347 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
348 Offset => Length (New_Item));
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 procedure Insert
kono
parents:
diff changeset
351 (Container : in out Vector;
kono
parents:
diff changeset
352 Before : Extended_Index;
kono
parents:
diff changeset
353 New_Item : Element_Type)
kono
parents:
diff changeset
354 with
kono
parents:
diff changeset
355 Global => null,
kono
parents:
diff changeset
356 Pre =>
kono
parents:
diff changeset
357 Length (Container) < Capacity (Container)
kono
parents:
diff changeset
358 and then (Before in Index_Type'First .. Last_Index (Container) + 1),
kono
parents:
diff changeset
359 Post =>
kono
parents:
diff changeset
360 Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 -- Elements located before Before in Container are preserved
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 and M.Range_Equal
kono
parents:
diff changeset
365 (Left => Model (Container)'Old,
kono
parents:
diff changeset
366 Right => Model (Container),
kono
parents:
diff changeset
367 Fst => Index_Type'First,
kono
parents:
diff changeset
368 Lst => Before - 1)
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 -- Container now has New_Item at index Before
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 and Element (Model (Container), Before) = New_Item
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 -- Elements located after Before in Container are shifted by 1
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 and M.Range_Shifted
kono
parents:
diff changeset
377 (Left => Model (Container)'Old,
kono
parents:
diff changeset
378 Right => Model (Container),
kono
parents:
diff changeset
379 Fst => Before,
kono
parents:
diff changeset
380 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
381 Offset => 1);
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 procedure Insert
kono
parents:
diff changeset
384 (Container : in out Vector;
kono
parents:
diff changeset
385 Before : Extended_Index;
kono
parents:
diff changeset
386 New_Item : Element_Type;
kono
parents:
diff changeset
387 Count : Count_Type)
kono
parents:
diff changeset
388 with
kono
parents:
diff changeset
389 Global => null,
kono
parents:
diff changeset
390 Pre =>
kono
parents:
diff changeset
391 Length (Container) <= Capacity (Container) - Count
kono
parents:
diff changeset
392 and (Before in Index_Type'First .. Last_Index (Container)
kono
parents:
diff changeset
393 or (Before /= No_Index
kono
parents:
diff changeset
394 and then Before - 1 = Last_Index (Container))),
kono
parents:
diff changeset
395 Post =>
kono
parents:
diff changeset
396 Length (Container) = Length (Container)'Old + Count
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 -- Elements located before Before in Container are preserved
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 and M.Range_Equal
kono
parents:
diff changeset
401 (Left => Model (Container)'Old,
kono
parents:
diff changeset
402 Right => Model (Container),
kono
parents:
diff changeset
403 Fst => Index_Type'First,
kono
parents:
diff changeset
404 Lst => Before - 1)
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 -- New_Item is inserted Count times at position Before
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 and (if Count > 0 then
kono
parents:
diff changeset
409 M.Constant_Range
kono
parents:
diff changeset
410 (Container => Model (Container),
kono
parents:
diff changeset
411 Fst => Before,
kono
parents:
diff changeset
412 Lst => Before + Index_Type'Base (Count - 1),
kono
parents:
diff changeset
413 Item => New_Item))
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 -- Elements located after Before in Container are shifted
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 and M.Range_Shifted
kono
parents:
diff changeset
418 (Left => Model (Container)'Old,
kono
parents:
diff changeset
419 Right => Model (Container),
kono
parents:
diff changeset
420 Fst => Before,
kono
parents:
diff changeset
421 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
422 Offset => Count);
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 procedure Prepend (Container : in out Vector; New_Item : Vector) with
kono
parents:
diff changeset
425 Global => null,
kono
parents:
diff changeset
426 Pre => Length (Container) <= Capacity (Container) - Length (New_Item),
kono
parents:
diff changeset
427 Post =>
kono
parents:
diff changeset
428 Length (Container) = Length (Container)'Old + Length (New_Item)
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 -- Elements of New_Item are inserted at the beginning of Container
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 and M.Range_Equal
kono
parents:
diff changeset
433 (Left => Model (New_Item),
kono
parents:
diff changeset
434 Right => Model (Container),
kono
parents:
diff changeset
435 Fst => Index_Type'First,
kono
parents:
diff changeset
436 Lst => Last_Index (New_Item))
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 -- Elements of Container are shifted
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 and M.Range_Shifted
kono
parents:
diff changeset
441 (Left => Model (Container)'Old,
kono
parents:
diff changeset
442 Right => Model (Container),
kono
parents:
diff changeset
443 Fst => Index_Type'First,
kono
parents:
diff changeset
444 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
445 Offset => Length (New_Item));
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 procedure Prepend (Container : in out Vector; New_Item : Element_Type) with
kono
parents:
diff changeset
448 Global => null,
kono
parents:
diff changeset
449 Pre => Length (Container) < Capacity (Container),
kono
parents:
diff changeset
450 Post =>
kono
parents:
diff changeset
451 Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 -- Container now has New_Item at Index_Type'First
kono
parents:
diff changeset
454
kono
parents:
diff changeset
455 and Element (Model (Container), Index_Type'First) = New_Item
kono
parents:
diff changeset
456
kono
parents:
diff changeset
457 -- Elements of Container are shifted by 1
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 and M.Range_Shifted
kono
parents:
diff changeset
460 (Left => Model (Container)'Old,
kono
parents:
diff changeset
461 Right => Model (Container),
kono
parents:
diff changeset
462 Fst => Index_Type'First,
kono
parents:
diff changeset
463 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
464 Offset => 1);
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 procedure Prepend
kono
parents:
diff changeset
467 (Container : in out Vector;
kono
parents:
diff changeset
468 New_Item : Element_Type;
kono
parents:
diff changeset
469 Count : Count_Type)
kono
parents:
diff changeset
470 with
kono
parents:
diff changeset
471 Global => null,
kono
parents:
diff changeset
472 Pre => Length (Container) <= Capacity (Container) - Count,
kono
parents:
diff changeset
473 Post =>
kono
parents:
diff changeset
474 Length (Container) = Length (Container)'Old + Count
kono
parents:
diff changeset
475
kono
parents:
diff changeset
476 -- New_Item is inserted Count times at the beginning of Container
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 and M.Constant_Range
kono
parents:
diff changeset
479 (Container => Model (Container),
kono
parents:
diff changeset
480 Fst => Index_Type'First,
kono
parents:
diff changeset
481 Lst => Index_Type'First + Index_Type'Base (Count - 1),
kono
parents:
diff changeset
482 Item => New_Item)
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 -- Elements of Container are shifted
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 and M.Range_Shifted
kono
parents:
diff changeset
487 (Left => Model (Container)'Old,
kono
parents:
diff changeset
488 Right => Model (Container),
kono
parents:
diff changeset
489 Fst => Index_Type'First,
kono
parents:
diff changeset
490 Lst => Last_Index (Container)'Old,
kono
parents:
diff changeset
491 Offset => Count);
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 procedure Append (Container : in out Vector; New_Item : Vector) with
kono
parents:
diff changeset
494 Global => null,
kono
parents:
diff changeset
495 Pre =>
kono
parents:
diff changeset
496 Length (Container) <= Capacity (Container) - Length (New_Item),
kono
parents:
diff changeset
497 Post =>
kono
parents:
diff changeset
498 Length (Container) = Length (Container)'Old + Length (New_Item)
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 -- The elements of Container are preserved
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 and Model (Container)'Old <= Model (Container)
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 -- Elements of New_Item are inserted at the end of Container
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 and (if Length (New_Item) > 0 then
kono
parents:
diff changeset
507 M.Range_Shifted
kono
parents:
diff changeset
508 (Left => Model (New_Item),
kono
parents:
diff changeset
509 Right => Model (Container),
kono
parents:
diff changeset
510 Fst => Index_Type'First,
kono
parents:
diff changeset
511 Lst => Last_Index (New_Item),
kono
parents:
diff changeset
512 Offset =>
kono
parents:
diff changeset
513 Count_Type
kono
parents:
diff changeset
514 (Last_Index (Container)'Old - Index_Type'First + 1)));
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 procedure Append (Container : in out Vector; New_Item : Element_Type) with
kono
parents:
diff changeset
517 Global => null,
kono
parents:
diff changeset
518 Pre => Length (Container) < Capacity (Container),
kono
parents:
diff changeset
519 Post =>
kono
parents:
diff changeset
520 Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 -- Elements of Container are preserved
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 and Model (Container)'Old < Model (Container)
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 -- Container now has New_Item at the end of Container
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 and Element
kono
parents:
diff changeset
529 (Model (Container), Last_Index (Container)'Old + 1) = New_Item;
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 procedure Append
kono
parents:
diff changeset
532 (Container : in out Vector;
kono
parents:
diff changeset
533 New_Item : Element_Type;
kono
parents:
diff changeset
534 Count : Count_Type)
kono
parents:
diff changeset
535 with
kono
parents:
diff changeset
536 Global => null,
kono
parents:
diff changeset
537 Pre => Length (Container) <= Capacity (Container) - Count,
kono
parents:
diff changeset
538 Post =>
kono
parents:
diff changeset
539 Length (Container) = Length (Container)'Old + Count
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 -- Elements of Container are preserved
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 and Model (Container)'Old <= Model (Container)
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 -- New_Item is inserted Count times at the end of Container
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 and (if Count > 0 then
kono
parents:
diff changeset
548 M.Constant_Range
kono
parents:
diff changeset
549 (Container => Model (Container),
kono
parents:
diff changeset
550 Fst => Last_Index (Container)'Old + 1,
kono
parents:
diff changeset
551 Lst =>
kono
parents:
diff changeset
552 Last_Index (Container)'Old + Index_Type'Base (Count),
kono
parents:
diff changeset
553 Item => New_Item));
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 procedure Delete (Container : in out Vector; Index : Extended_Index) with
kono
parents:
diff changeset
556 Global => null,
kono
parents:
diff changeset
557 Pre => Index in First_Index (Container) .. Last_Index (Container),
kono
parents:
diff changeset
558 Post =>
kono
parents:
diff changeset
559 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 -- Elements located before Index in Container are preserved
kono
parents:
diff changeset
562
kono
parents:
diff changeset
563 and M.Range_Equal
kono
parents:
diff changeset
564 (Left => Model (Container)'Old,
kono
parents:
diff changeset
565 Right => Model (Container),
kono
parents:
diff changeset
566 Fst => Index_Type'First,
kono
parents:
diff changeset
567 Lst => Index - 1)
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 -- Elements located after Index in Container are shifted by 1
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 and M.Range_Shifted
kono
parents:
diff changeset
572 (Left => Model (Container),
kono
parents:
diff changeset
573 Right => Model (Container)'Old,
kono
parents:
diff changeset
574 Fst => Index,
kono
parents:
diff changeset
575 Lst => Last_Index (Container),
kono
parents:
diff changeset
576 Offset => 1);
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 procedure Delete
kono
parents:
diff changeset
579 (Container : in out Vector;
kono
parents:
diff changeset
580 Index : Extended_Index;
kono
parents:
diff changeset
581 Count : Count_Type)
kono
parents:
diff changeset
582 with
kono
parents:
diff changeset
583 Global => null,
kono
parents:
diff changeset
584 Pre =>
kono
parents:
diff changeset
585 Index in First_Index (Container) .. Last_Index (Container),
kono
parents:
diff changeset
586 Post =>
kono
parents:
diff changeset
587 Length (Container) in
kono
parents:
diff changeset
588 Length (Container)'Old - Count .. Length (Container)'Old
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 -- The elements of Container located before Index are preserved.
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 and M.Range_Equal
kono
parents:
diff changeset
593 (Left => Model (Container)'Old,
kono
parents:
diff changeset
594 Right => Model (Container),
kono
parents:
diff changeset
595 Fst => Index_Type'First,
kono
parents:
diff changeset
596 Lst => Index - 1),
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 Contract_Cases =>
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 -- All the elements after Position have been erased
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 (Length (Container) - Count <= Count_Type (Index - Index_Type'First) =>
kono
parents:
diff changeset
603 Length (Container) = Count_Type (Index - Index_Type'First),
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 others =>
kono
parents:
diff changeset
606 Length (Container) = Length (Container)'Old - Count
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 -- Other elements are shifted by Count
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 and M.Range_Shifted
kono
parents:
diff changeset
611 (Left => Model (Container),
kono
parents:
diff changeset
612 Right => Model (Container)'Old,
kono
parents:
diff changeset
613 Fst => Index,
kono
parents:
diff changeset
614 Lst => Last_Index (Container),
kono
parents:
diff changeset
615 Offset => Count));
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 procedure Delete_First (Container : in out Vector) with
kono
parents:
diff changeset
618 Global => null,
kono
parents:
diff changeset
619 Pre => Length (Container) > 0,
kono
parents:
diff changeset
620 Post =>
kono
parents:
diff changeset
621 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 -- Elements of Container are shifted by 1
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 and M.Range_Shifted
kono
parents:
diff changeset
626 (Left => Model (Container),
kono
parents:
diff changeset
627 Right => Model (Container)'Old,
kono
parents:
diff changeset
628 Fst => Index_Type'First,
kono
parents:
diff changeset
629 Lst => Last_Index (Container),
kono
parents:
diff changeset
630 Offset => 1);
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 procedure Delete_First (Container : in out Vector; Count : Count_Type) with
kono
parents:
diff changeset
633 Global => null,
kono
parents:
diff changeset
634 Contract_Cases =>
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 -- All the elements of Container have been erased
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 (Length (Container) <= Count => Length (Container) = 0,
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 others =>
kono
parents:
diff changeset
641 Length (Container) = Length (Container)'Old - Count
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 -- Elements of Container are shifted by Count
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 and M.Range_Shifted
kono
parents:
diff changeset
646 (Left => Model (Container),
kono
parents:
diff changeset
647 Right => Model (Container)'Old,
kono
parents:
diff changeset
648 Fst => Index_Type'First,
kono
parents:
diff changeset
649 Lst => Last_Index (Container),
kono
parents:
diff changeset
650 Offset => Count));
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 procedure Delete_Last (Container : in out Vector) with
kono
parents:
diff changeset
653 Global => null,
kono
parents:
diff changeset
654 Pre => Length (Container) > 0,
kono
parents:
diff changeset
655 Post =>
kono
parents:
diff changeset
656 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 -- Elements of Container are preserved
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 and Model (Container) < Model (Container)'Old;
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 procedure Delete_Last (Container : in out Vector; Count : Count_Type) with
kono
parents:
diff changeset
663 Global => null,
kono
parents:
diff changeset
664 Contract_Cases =>
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 -- All the elements after Position have been erased
kono
parents:
diff changeset
667
kono
parents:
diff changeset
668 (Length (Container) <= Count => Length (Container) = 0,
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 others =>
kono
parents:
diff changeset
671 Length (Container) = Length (Container)'Old - Count
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 -- The elements of Container are preserved
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 and Model (Container) <= Model (Container)'Old);
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677 procedure Reverse_Elements (Container : in out Vector) with
kono
parents:
diff changeset
678 Global => null,
kono
parents:
diff changeset
679 Post => M_Elements_Reversed (Model (Container)'Old, Model (Container));
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 procedure Swap
kono
parents:
diff changeset
682 (Container : in out Vector;
kono
parents:
diff changeset
683 I : Index_Type;
kono
parents:
diff changeset
684 J : Index_Type)
kono
parents:
diff changeset
685 with
kono
parents:
diff changeset
686 Global => null,
kono
parents:
diff changeset
687 Pre =>
kono
parents:
diff changeset
688 I in First_Index (Container) .. Last_Index (Container)
kono
parents:
diff changeset
689 and then J in First_Index (Container) .. Last_Index (Container),
kono
parents:
diff changeset
690 Post =>
kono
parents:
diff changeset
691 M_Elements_Swapped (Model (Container)'Old, Model (Container), I, J);
kono
parents:
diff changeset
692
kono
parents:
diff changeset
693 function First_Index (Container : Vector) return Index_Type with
kono
parents:
diff changeset
694 Global => null,
kono
parents:
diff changeset
695 Post => First_Index'Result = Index_Type'First;
kono
parents:
diff changeset
696 pragma Annotate (GNATprove, Inline_For_Proof, First_Index);
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 function First_Element (Container : Vector) return Element_Type with
kono
parents:
diff changeset
699 Global => null,
kono
parents:
diff changeset
700 Pre => not Is_Empty (Container),
kono
parents:
diff changeset
701 Post =>
kono
parents:
diff changeset
702 First_Element'Result = Element (Model (Container), Index_Type'First);
kono
parents:
diff changeset
703 pragma Annotate (GNATprove, Inline_For_Proof, First_Element);
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 function Last_Index (Container : Vector) return Extended_Index with
kono
parents:
diff changeset
706 Global => null,
kono
parents:
diff changeset
707 Post => Last_Index'Result = M.Last (Model (Container));
kono
parents:
diff changeset
708 pragma Annotate (GNATprove, Inline_For_Proof, Last_Index);
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 function Last_Element (Container : Vector) return Element_Type with
kono
parents:
diff changeset
711 Global => null,
kono
parents:
diff changeset
712 Pre => not Is_Empty (Container),
kono
parents:
diff changeset
713 Post =>
kono
parents:
diff changeset
714 Last_Element'Result =
kono
parents:
diff changeset
715 Element (Model (Container), Last_Index (Container));
kono
parents:
diff changeset
716 pragma Annotate (GNATprove, Inline_For_Proof, Last_Element);
kono
parents:
diff changeset
717
kono
parents:
diff changeset
718 function Find_Index
kono
parents:
diff changeset
719 (Container : Vector;
kono
parents:
diff changeset
720 Item : Element_Type;
kono
parents:
diff changeset
721 Index : Index_Type := Index_Type'First) return Extended_Index
kono
parents:
diff changeset
722 with
kono
parents:
diff changeset
723 Global => null,
kono
parents:
diff changeset
724 Contract_Cases =>
kono
parents:
diff changeset
725
kono
parents:
diff changeset
726 -- If Item is not contained in Container after Index, Find_Index
kono
parents:
diff changeset
727 -- returns No_Index.
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 (Index > Last_Index (Container)
kono
parents:
diff changeset
730 or else not M.Contains
kono
parents:
diff changeset
731 (Container => Model (Container),
kono
parents:
diff changeset
732 Fst => Index,
kono
parents:
diff changeset
733 Lst => Last_Index (Container),
kono
parents:
diff changeset
734 Item => Item)
kono
parents:
diff changeset
735 =>
kono
parents:
diff changeset
736 Find_Index'Result = No_Index,
kono
parents:
diff changeset
737
kono
parents:
diff changeset
738 -- Otherwise, Find_Index returns a valid index greater than Index
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 others =>
kono
parents:
diff changeset
741 Find_Index'Result in Index .. Last_Index (Container)
kono
parents:
diff changeset
742
kono
parents:
diff changeset
743 -- The element at this index in Container is Item
kono
parents:
diff changeset
744
kono
parents:
diff changeset
745 and Element (Model (Container), Find_Index'Result) = Item
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 -- It is the first occurrence of Item after Index in Container
kono
parents:
diff changeset
748
kono
parents:
diff changeset
749 and not M.Contains
kono
parents:
diff changeset
750 (Container => Model (Container),
kono
parents:
diff changeset
751 Fst => Index,
kono
parents:
diff changeset
752 Lst => Find_Index'Result - 1,
kono
parents:
diff changeset
753 Item => Item));
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 function Reverse_Find_Index
kono
parents:
diff changeset
756 (Container : Vector;
kono
parents:
diff changeset
757 Item : Element_Type;
kono
parents:
diff changeset
758 Index : Index_Type := Index_Type'Last) return Extended_Index
kono
parents:
diff changeset
759 with
kono
parents:
diff changeset
760 Global => null,
kono
parents:
diff changeset
761 Contract_Cases =>
kono
parents:
diff changeset
762
kono
parents:
diff changeset
763 -- If Item is not contained in Container before Index,
kono
parents:
diff changeset
764 -- Reverse_Find_Index returns No_Index.
kono
parents:
diff changeset
765
kono
parents:
diff changeset
766 (not M.Contains
kono
parents:
diff changeset
767 (Container => Model (Container),
kono
parents:
diff changeset
768 Fst => Index_Type'First,
kono
parents:
diff changeset
769 Lst => (if Index <= Last_Index (Container) then Index
kono
parents:
diff changeset
770 else Last_Index (Container)),
kono
parents:
diff changeset
771 Item => Item)
kono
parents:
diff changeset
772 =>
kono
parents:
diff changeset
773 Reverse_Find_Index'Result = No_Index,
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 -- Otherwise, Reverse_Find_Index returns a valid index smaller than
kono
parents:
diff changeset
776 -- Index
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 others =>
kono
parents:
diff changeset
779 Reverse_Find_Index'Result in Index_Type'First .. Index
kono
parents:
diff changeset
780 and Reverse_Find_Index'Result <= Last_Index (Container)
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782 -- The element at this index in Container is Item
kono
parents:
diff changeset
783
kono
parents:
diff changeset
784 and Element (Model (Container), Reverse_Find_Index'Result) = Item
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 -- It is the last occurrence of Item before Index in Container
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 and not M.Contains
kono
parents:
diff changeset
789 (Container => Model (Container),
kono
parents:
diff changeset
790 Fst => Reverse_Find_Index'Result + 1,
kono
parents:
diff changeset
791 Lst =>
kono
parents:
diff changeset
792 (if Index <= Last_Index (Container) then
kono
parents:
diff changeset
793 Index
kono
parents:
diff changeset
794 else
kono
parents:
diff changeset
795 Last_Index (Container)),
kono
parents:
diff changeset
796 Item => Item));
kono
parents:
diff changeset
797
kono
parents:
diff changeset
798 function Contains
kono
parents:
diff changeset
799 (Container : Vector;
kono
parents:
diff changeset
800 Item : Element_Type) return Boolean
kono
parents:
diff changeset
801 with
kono
parents:
diff changeset
802 Global => null,
kono
parents:
diff changeset
803 Post =>
kono
parents:
diff changeset
804 Contains'Result =
kono
parents:
diff changeset
805 M.Contains
kono
parents:
diff changeset
806 (Container => Model (Container),
kono
parents:
diff changeset
807 Fst => Index_Type'First,
kono
parents:
diff changeset
808 Lst => Last_Index (Container),
kono
parents:
diff changeset
809 Item => Item);
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 function Has_Element
kono
parents:
diff changeset
812 (Container : Vector;
kono
parents:
diff changeset
813 Position : Extended_Index) return Boolean
kono
parents:
diff changeset
814 with
kono
parents:
diff changeset
815 Global => null,
kono
parents:
diff changeset
816 Post =>
kono
parents:
diff changeset
817 Has_Element'Result =
kono
parents:
diff changeset
818 (Position in Index_Type'First .. Last_Index (Container));
kono
parents:
diff changeset
819 pragma Annotate (GNATprove, Inline_For_Proof, Has_Element);
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 generic
kono
parents:
diff changeset
822 with function "<" (Left, Right : Element_Type) return Boolean is <>;
kono
parents:
diff changeset
823 package Generic_Sorting with SPARK_Mode is
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 package Formal_Model with Ghost is
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 function M_Elements_Sorted (Container : M.Sequence) return Boolean
kono
parents:
diff changeset
828 with
kono
parents:
diff changeset
829 Global => null,
kono
parents:
diff changeset
830 Post =>
kono
parents:
diff changeset
831 M_Elements_Sorted'Result =
kono
parents:
diff changeset
832 (for all I in Index_Type'First .. M.Last (Container) =>
kono
parents:
diff changeset
833 (for all J in I .. M.Last (Container) =>
kono
parents:
diff changeset
834 Element (Container, I) = Element (Container, J)
kono
parents:
diff changeset
835 or Element (Container, I) < Element (Container, J)));
kono
parents:
diff changeset
836 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Sorted);
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 end Formal_Model;
kono
parents:
diff changeset
839 use Formal_Model;
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 function Is_Sorted (Container : Vector) return Boolean with
kono
parents:
diff changeset
842 Global => null,
kono
parents:
diff changeset
843 Post => Is_Sorted'Result = M_Elements_Sorted (Model (Container));
kono
parents:
diff changeset
844
kono
parents:
diff changeset
845 procedure Sort (Container : in out Vector) with
kono
parents:
diff changeset
846 Global => null,
kono
parents:
diff changeset
847 Post =>
kono
parents:
diff changeset
848 Length (Container) = Length (Container)'Old
kono
parents:
diff changeset
849 and M_Elements_Sorted (Model (Container))
kono
parents:
diff changeset
850 and M_Elements_Included
kono
parents:
diff changeset
851 (Left => Model (Container)'Old,
kono
parents:
diff changeset
852 L_Lst => Last_Index (Container),
kono
parents:
diff changeset
853 Right => Model (Container),
kono
parents:
diff changeset
854 R_Lst => Last_Index (Container))
kono
parents:
diff changeset
855 and M_Elements_Included
kono
parents:
diff changeset
856 (Left => Model (Container),
kono
parents:
diff changeset
857 L_Lst => Last_Index (Container),
kono
parents:
diff changeset
858 Right => Model (Container)'Old,
kono
parents:
diff changeset
859 R_Lst => Last_Index (Container));
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 procedure Merge (Target : in out Vector; Source : in out Vector) with
kono
parents:
diff changeset
862 -- Target and Source should not be aliased
kono
parents:
diff changeset
863 Global => null,
kono
parents:
diff changeset
864 Pre => Length (Source) <= Capacity (Target) - Length (Target),
kono
parents:
diff changeset
865 Post =>
kono
parents:
diff changeset
866 Length (Target) = Length (Target)'Old + Length (Source)'Old
kono
parents:
diff changeset
867 and Length (Source) = 0
kono
parents:
diff changeset
868 and (if M_Elements_Sorted (Model (Target)'Old)
kono
parents:
diff changeset
869 and M_Elements_Sorted (Model (Source)'Old)
kono
parents:
diff changeset
870 then
kono
parents:
diff changeset
871 M_Elements_Sorted (Model (Target)))
kono
parents:
diff changeset
872 and M_Elements_Included
kono
parents:
diff changeset
873 (Left => Model (Target)'Old,
kono
parents:
diff changeset
874 L_Lst => Last_Index (Target)'Old,
kono
parents:
diff changeset
875 Right => Model (Target),
kono
parents:
diff changeset
876 R_Lst => Last_Index (Target))
kono
parents:
diff changeset
877 and M_Elements_Included
kono
parents:
diff changeset
878 (Left => Model (Source)'Old,
kono
parents:
diff changeset
879 L_Lst => Last_Index (Source)'Old,
kono
parents:
diff changeset
880 Right => Model (Target),
kono
parents:
diff changeset
881 R_Lst => Last_Index (Target))
kono
parents:
diff changeset
882 and M_Elements_In_Union
kono
parents:
diff changeset
883 (Model (Target),
kono
parents:
diff changeset
884 Model (Source)'Old,
kono
parents:
diff changeset
885 Model (Target)'Old);
kono
parents:
diff changeset
886 end Generic_Sorting;
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 private
kono
parents:
diff changeset
889 pragma SPARK_Mode (Off);
kono
parents:
diff changeset
890
kono
parents:
diff changeset
891 pragma Inline (First_Index);
kono
parents:
diff changeset
892 pragma Inline (Last_Index);
kono
parents:
diff changeset
893 pragma Inline (Element);
kono
parents:
diff changeset
894 pragma Inline (First_Element);
kono
parents:
diff changeset
895 pragma Inline (Last_Element);
kono
parents:
diff changeset
896 pragma Inline (Replace_Element);
kono
parents:
diff changeset
897 pragma Inline (Contains);
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 -- The implementation method is to instantiate Bounded_Holders to get a
kono
parents:
diff changeset
900 -- definite type for Element_Type.
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 package Holders is new Bounded_Holders
kono
parents:
diff changeset
903 (Element_Type, Max_Size_In_Storage_Elements, "=");
kono
parents:
diff changeset
904 use Holders;
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 subtype Array_Index is Capacity_Range range 1 .. Capacity_Range'Last;
kono
parents:
diff changeset
907 type Elements_Array is array (Array_Index range <>) of Holder;
kono
parents:
diff changeset
908 function "=" (L, R : Elements_Array) return Boolean is abstract;
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 type Elements_Array_Ptr is access all Elements_Array;
kono
parents:
diff changeset
911
kono
parents:
diff changeset
912 type Vector (Capacity : Capacity_Range) is limited record
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 -- In the bounded case, the elements are stored in Elements. In the
kono
parents:
diff changeset
915 -- unbounded case, the elements are initially stored in Elements, until
kono
parents:
diff changeset
916 -- we run out of room, then we switch to Elements_Ptr.
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 Last : Extended_Index := No_Index;
kono
parents:
diff changeset
919 Elements_Ptr : Elements_Array_Ptr := null;
kono
parents:
diff changeset
920 Elements : aliased Elements_Array (1 .. Capacity);
kono
parents:
diff changeset
921 end record;
kono
parents:
diff changeset
922
kono
parents:
diff changeset
923 -- The primary reason Vector is limited is that in the unbounded case, once
kono
parents:
diff changeset
924 -- Elements_Ptr is in use, assignment statements won't work. "X := Y;" will
kono
parents:
diff changeset
925 -- cause X and Y to share state; that is, X.Elements_Ptr = Y.Elements_Ptr,
kono
parents:
diff changeset
926 -- so for example "Append (X, ...);" will modify BOTH X and Y. That would
kono
parents:
diff changeset
927 -- allow SPARK to "prove" things that are false. We could fix that by
kono
parents:
diff changeset
928 -- making Vector a controlled type, and override Adjust to make a deep
kono
parents:
diff changeset
929 -- copy, but finalization is not allowed in SPARK.
kono
parents:
diff changeset
930 --
kono
parents:
diff changeset
931 -- Note that (unfortunately) this means that 'Old and 'Loop_Entry are not
kono
parents:
diff changeset
932 -- allowed on Vectors.
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 function Empty_Vector return Vector is
kono
parents:
diff changeset
935 ((Capacity => 0, others => <>));
kono
parents:
diff changeset
936
kono
parents:
diff changeset
937 end Ada.Containers.Formal_Indefinite_Vectors;