annotate gcc/ada/libgnat/a-cobove.adb @ 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 -- A D A . C O N T A I N E R S . B O U N D E D _ V E C T O R S --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2004-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- This unit was originally developed by Matthew J Heaney. --
kono
parents:
diff changeset
28 ------------------------------------------------------------------------------
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 with Ada.Containers.Generic_Array_Sort;
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 with System; use type System.Address;
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 package body Ada.Containers.Bounded_Vectors is
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 pragma Warnings (Off, "variable ""Busy*"" is not referenced");
kono
parents:
diff changeset
37 pragma Warnings (Off, "variable ""Lock*"" is not referenced");
kono
parents:
diff changeset
38 -- See comment in Ada.Containers.Helpers
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 -----------------------
kono
parents:
diff changeset
41 -- Local Subprograms --
kono
parents:
diff changeset
42 -----------------------
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 function To_Array_Index (Index : Index_Type'Base) return Count_Type'Base;
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 ---------
kono
parents:
diff changeset
47 -- "&" --
kono
parents:
diff changeset
48 ---------
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 function "&" (Left, Right : Vector) return Vector is
kono
parents:
diff changeset
51 LN : constant Count_Type := Length (Left);
kono
parents:
diff changeset
52 RN : constant Count_Type := Length (Right);
kono
parents:
diff changeset
53 N : Count_Type'Base; -- length of result
kono
parents:
diff changeset
54 J : Count_Type'Base; -- for computing intermediate index values
kono
parents:
diff changeset
55 Last : Index_Type'Base; -- Last index of result
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 begin
kono
parents:
diff changeset
58 -- We decide that the capacity of the result is the sum of the lengths
kono
parents:
diff changeset
59 -- of the vector parameters. We could decide to make it larger, but we
kono
parents:
diff changeset
60 -- have no basis for knowing how much larger, so we just allocate the
kono
parents:
diff changeset
61 -- minimum amount of storage.
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 -- Here we handle the easy cases first, when one of the vector
kono
parents:
diff changeset
64 -- parameters is empty. (We say "easy" because there's nothing to
kono
parents:
diff changeset
65 -- compute, that can potentially overflow.)
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 if LN = 0 then
kono
parents:
diff changeset
68 if RN = 0 then
kono
parents:
diff changeset
69 return Empty_Vector;
kono
parents:
diff changeset
70 end if;
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 return Vector'(Capacity => RN,
kono
parents:
diff changeset
73 Elements => Right.Elements (1 .. RN),
kono
parents:
diff changeset
74 Last => Right.Last,
kono
parents:
diff changeset
75 others => <>);
kono
parents:
diff changeset
76 end if;
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 if RN = 0 then
kono
parents:
diff changeset
79 return Vector'(Capacity => LN,
kono
parents:
diff changeset
80 Elements => Left.Elements (1 .. LN),
kono
parents:
diff changeset
81 Last => Left.Last,
kono
parents:
diff changeset
82 others => <>);
kono
parents:
diff changeset
83 end if;
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 -- Neither of the vector parameters is empty, so must compute the length
kono
parents:
diff changeset
86 -- of the result vector and its last index. (This is the harder case,
kono
parents:
diff changeset
87 -- because our computations must avoid overflow.)
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 -- There are two constraints we need to satisfy. The first constraint is
kono
parents:
diff changeset
90 -- that a container cannot have more than Count_Type'Last elements, so
kono
parents:
diff changeset
91 -- we must check the sum of the combined lengths. Note that we cannot
kono
parents:
diff changeset
92 -- simply add the lengths, because of the possibility of overflow.
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 if Checks and then LN > Count_Type'Last - RN then
kono
parents:
diff changeset
95 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
96 end if;
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 -- It is now safe to compute the length of the new vector, without fear
kono
parents:
diff changeset
99 -- of overflow.
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 N := LN + RN;
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 -- The second constraint is that the new Last index value cannot
kono
parents:
diff changeset
104 -- exceed Index_Type'Last. We use the wider of Index_Type'Base and
kono
parents:
diff changeset
105 -- Count_Type'Base as the type for intermediate values.
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 -- We perform a two-part test. First we determine whether the
kono
parents:
diff changeset
110 -- computed Last value lies in the base range of the type, and then
kono
parents:
diff changeset
111 -- determine whether it lies in the range of the index (sub)type.
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 -- Last must satisfy this relation:
kono
parents:
diff changeset
114 -- First + Length - 1 <= Last
kono
parents:
diff changeset
115 -- We regroup terms:
kono
parents:
diff changeset
116 -- First - 1 <= Last - Length
kono
parents:
diff changeset
117 -- Which can rewrite as:
kono
parents:
diff changeset
118 -- No_Index <= Last - Length
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 if Checks and then
kono
parents:
diff changeset
121 Index_Type'Base'Last - Index_Type'Base (N) < No_Index
kono
parents:
diff changeset
122 then
kono
parents:
diff changeset
123 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
124 end if;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 -- We now know that the computed value of Last is within the base
kono
parents:
diff changeset
127 -- range of the type, so it is safe to compute its value:
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 Last := No_Index + Index_Type'Base (N);
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 -- Finally we test whether the value is within the range of the
kono
parents:
diff changeset
132 -- generic actual index subtype:
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 if Checks and then Last > Index_Type'Last then
kono
parents:
diff changeset
135 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
136 end if;
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 elsif Index_Type'First <= 0 then
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 -- Here we can compute Last directly, in the normal way. We know that
kono
parents:
diff changeset
141 -- No_Index is less than 0, so there is no danger of overflow when
kono
parents:
diff changeset
142 -- adding the (positive) value of length.
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 J := Count_Type'Base (No_Index) + N; -- Last
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 if Checks and then J > Count_Type'Base (Index_Type'Last) then
kono
parents:
diff changeset
147 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
148 end if;
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 -- We know that the computed value (having type Count_Type) of Last
kono
parents:
diff changeset
151 -- is within the range of the generic actual index subtype, so it is
kono
parents:
diff changeset
152 -- safe to convert to Index_Type:
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 Last := Index_Type'Base (J);
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 else
kono
parents:
diff changeset
157 -- Here Index_Type'First (and Index_Type'Last) is positive, so we
kono
parents:
diff changeset
158 -- must test the length indirectly (by working backwards from the
kono
parents:
diff changeset
159 -- largest possible value of Last), in order to prevent overflow.
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 J := Count_Type'Base (Index_Type'Last) - N; -- No_Index
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 if Checks and then J < Count_Type'Base (No_Index) then
kono
parents:
diff changeset
164 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
165 end if;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 -- We have determined that the result length would not create a Last
kono
parents:
diff changeset
168 -- index value outside of the range of Index_Type, so we can now
kono
parents:
diff changeset
169 -- safely compute its value.
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 Last := Index_Type'Base (Count_Type'Base (No_Index) + N);
kono
parents:
diff changeset
172 end if;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 declare
kono
parents:
diff changeset
175 LE : Elements_Array renames Left.Elements (1 .. LN);
kono
parents:
diff changeset
176 RE : Elements_Array renames Right.Elements (1 .. RN);
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 begin
kono
parents:
diff changeset
179 return Vector'(Capacity => N,
kono
parents:
diff changeset
180 Elements => LE & RE,
kono
parents:
diff changeset
181 Last => Last,
kono
parents:
diff changeset
182 others => <>);
kono
parents:
diff changeset
183 end;
kono
parents:
diff changeset
184 end "&";
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 function "&" (Left : Vector; Right : Element_Type) return Vector is
kono
parents:
diff changeset
187 LN : constant Count_Type := Length (Left);
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 begin
kono
parents:
diff changeset
190 -- We decide that the capacity of the result is the sum of the lengths
kono
parents:
diff changeset
191 -- of the parameters. We could decide to make it larger, but we have no
kono
parents:
diff changeset
192 -- basis for knowing how much larger, so we just allocate the minimum
kono
parents:
diff changeset
193 -- amount of storage.
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 -- We must compute the length of the result vector and its last index,
kono
parents:
diff changeset
196 -- but in such a way that overflow is avoided. We must satisfy two
kono
parents:
diff changeset
197 -- constraints: the new length cannot exceed Count_Type'Last, and the
kono
parents:
diff changeset
198 -- new Last index cannot exceed Index_Type'Last.
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 if Checks and then LN = Count_Type'Last then
kono
parents:
diff changeset
201 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
202 end if;
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 if Checks and then Left.Last >= Index_Type'Last then
kono
parents:
diff changeset
205 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
206 end if;
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 return Vector'(Capacity => LN + 1,
kono
parents:
diff changeset
209 Elements => Left.Elements (1 .. LN) & Right,
kono
parents:
diff changeset
210 Last => Left.Last + 1,
kono
parents:
diff changeset
211 others => <>);
kono
parents:
diff changeset
212 end "&";
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 function "&" (Left : Element_Type; Right : Vector) return Vector is
kono
parents:
diff changeset
215 RN : constant Count_Type := Length (Right);
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 begin
kono
parents:
diff changeset
218 -- We decide that the capacity of the result is the sum of the lengths
kono
parents:
diff changeset
219 -- of the parameters. We could decide to make it larger, but we have no
kono
parents:
diff changeset
220 -- basis for knowing how much larger, so we just allocate the minimum
kono
parents:
diff changeset
221 -- amount of storage.
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 -- We compute the length of the result vector and its last index, but in
kono
parents:
diff changeset
224 -- such a way that overflow is avoided. We must satisfy two constraints:
kono
parents:
diff changeset
225 -- the new length cannot exceed Count_Type'Last, and the new Last index
kono
parents:
diff changeset
226 -- cannot exceed Index_Type'Last.
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 if Checks and then RN = Count_Type'Last then
kono
parents:
diff changeset
229 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
230 end if;
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 if Checks and then Right.Last >= Index_Type'Last then
kono
parents:
diff changeset
233 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
234 end if;
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 return Vector'(Capacity => 1 + RN,
kono
parents:
diff changeset
237 Elements => Left & Right.Elements (1 .. RN),
kono
parents:
diff changeset
238 Last => Right.Last + 1,
kono
parents:
diff changeset
239 others => <>);
kono
parents:
diff changeset
240 end "&";
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 function "&" (Left, Right : Element_Type) return Vector is
kono
parents:
diff changeset
243 begin
kono
parents:
diff changeset
244 -- We decide that the capacity of the result is the sum of the lengths
kono
parents:
diff changeset
245 -- of the parameters. We could decide to make it larger, but we have no
kono
parents:
diff changeset
246 -- basis for knowing how much larger, so we just allocate the minimum
kono
parents:
diff changeset
247 -- amount of storage.
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 -- We must compute the length of the result vector and its last index,
kono
parents:
diff changeset
250 -- but in such a way that overflow is avoided. We must satisfy two
kono
parents:
diff changeset
251 -- constraints: the new length cannot exceed Count_Type'Last (here, we
kono
parents:
diff changeset
252 -- know that that condition is satisfied), and the new Last index cannot
kono
parents:
diff changeset
253 -- exceed Index_Type'Last.
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 if Checks and then Index_Type'First >= Index_Type'Last then
kono
parents:
diff changeset
256 raise Constraint_Error with "new length is out of range";
kono
parents:
diff changeset
257 end if;
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 return Vector'(Capacity => 2,
kono
parents:
diff changeset
260 Elements => (Left, Right),
kono
parents:
diff changeset
261 Last => Index_Type'First + 1,
kono
parents:
diff changeset
262 others => <>);
kono
parents:
diff changeset
263 end "&";
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 ---------
kono
parents:
diff changeset
266 -- "=" --
kono
parents:
diff changeset
267 ---------
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 overriding function "=" (Left, Right : Vector) return Boolean is
kono
parents:
diff changeset
270 begin
kono
parents:
diff changeset
271 if Left.Last /= Right.Last then
kono
parents:
diff changeset
272 return False;
kono
parents:
diff changeset
273 end if;
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 if Left.Length = 0 then
kono
parents:
diff changeset
276 return True;
kono
parents:
diff changeset
277 end if;
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 declare
kono
parents:
diff changeset
280 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
281 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 Lock_Left : With_Lock (Left.TC'Unrestricted_Access);
kono
parents:
diff changeset
284 Lock_Right : With_Lock (Right.TC'Unrestricted_Access);
kono
parents:
diff changeset
285 begin
kono
parents:
diff changeset
286 for J in Count_Type range 1 .. Left.Length loop
kono
parents:
diff changeset
287 if Left.Elements (J) /= Right.Elements (J) then
kono
parents:
diff changeset
288 return False;
kono
parents:
diff changeset
289 end if;
kono
parents:
diff changeset
290 end loop;
kono
parents:
diff changeset
291 end;
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 return True;
kono
parents:
diff changeset
294 end "=";
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 ------------
kono
parents:
diff changeset
297 -- Assign --
kono
parents:
diff changeset
298 ------------
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 procedure Assign (Target : in out Vector; Source : Vector) is
kono
parents:
diff changeset
301 begin
kono
parents:
diff changeset
302 if Target'Address = Source'Address then
kono
parents:
diff changeset
303 return;
kono
parents:
diff changeset
304 end if;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 if Checks and then Target.Capacity < Source.Length then
kono
parents:
diff changeset
307 raise Capacity_Error -- ???
kono
parents:
diff changeset
308 with "Target capacity is less than Source length";
kono
parents:
diff changeset
309 end if;
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 Target.Clear;
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 Target.Elements (1 .. Source.Length) :=
kono
parents:
diff changeset
314 Source.Elements (1 .. Source.Length);
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 Target.Last := Source.Last;
kono
parents:
diff changeset
317 end Assign;
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 ------------
kono
parents:
diff changeset
320 -- Append --
kono
parents:
diff changeset
321 ------------
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 procedure Append (Container : in out Vector; New_Item : Vector) is
kono
parents:
diff changeset
324 begin
kono
parents:
diff changeset
325 if New_Item.Is_Empty then
kono
parents:
diff changeset
326 return;
kono
parents:
diff changeset
327 end if;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 if Checks and then Container.Last >= Index_Type'Last then
kono
parents:
diff changeset
330 raise Constraint_Error with "vector is already at its maximum length";
kono
parents:
diff changeset
331 end if;
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 Container.Insert (Container.Last + 1, New_Item);
kono
parents:
diff changeset
334 end Append;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 procedure Append
kono
parents:
diff changeset
337 (Container : in out Vector;
kono
parents:
diff changeset
338 New_Item : Element_Type;
kono
parents:
diff changeset
339 Count : Count_Type := 1)
kono
parents:
diff changeset
340 is
kono
parents:
diff changeset
341 begin
kono
parents:
diff changeset
342 if Count = 0 then
kono
parents:
diff changeset
343 return;
kono
parents:
diff changeset
344 end if;
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 if Checks and then Container.Last >= Index_Type'Last then
kono
parents:
diff changeset
347 raise Constraint_Error with "vector is already at its maximum length";
kono
parents:
diff changeset
348 end if;
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 Container.Insert (Container.Last + 1, New_Item, Count);
kono
parents:
diff changeset
351 end Append;
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 --------------
kono
parents:
diff changeset
354 -- Capacity --
kono
parents:
diff changeset
355 --------------
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 function Capacity (Container : Vector) return Count_Type is
kono
parents:
diff changeset
358 begin
kono
parents:
diff changeset
359 return Container.Elements'Length;
kono
parents:
diff changeset
360 end Capacity;
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 -----------
kono
parents:
diff changeset
363 -- Clear --
kono
parents:
diff changeset
364 -----------
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 procedure Clear (Container : in out Vector) is
kono
parents:
diff changeset
367 begin
kono
parents:
diff changeset
368 TC_Check (Container.TC);
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 Container.Last := No_Index;
kono
parents:
diff changeset
371 end Clear;
kono
parents:
diff changeset
372
kono
parents:
diff changeset
373 ------------------------
kono
parents:
diff changeset
374 -- Constant_Reference --
kono
parents:
diff changeset
375 ------------------------
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 function Constant_Reference
kono
parents:
diff changeset
378 (Container : aliased Vector;
kono
parents:
diff changeset
379 Position : Cursor) return Constant_Reference_Type
kono
parents:
diff changeset
380 is
kono
parents:
diff changeset
381 begin
kono
parents:
diff changeset
382 if Checks and then Position.Container = null then
kono
parents:
diff changeset
383 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
384 end if;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
387 then
kono
parents:
diff changeset
388 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
389 end if;
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 if Checks and then Position.Index > Position.Container.Last then
kono
parents:
diff changeset
392 raise Constraint_Error with "Position cursor is out of range";
kono
parents:
diff changeset
393 end if;
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 declare
kono
parents:
diff changeset
396 A : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
397 J : constant Count_Type := To_Array_Index (Position.Index);
kono
parents:
diff changeset
398 TC : constant Tamper_Counts_Access :=
kono
parents:
diff changeset
399 Container.TC'Unrestricted_Access;
kono
parents:
diff changeset
400 begin
kono
parents:
diff changeset
401 return R : constant Constant_Reference_Type :=
kono
parents:
diff changeset
402 (Element => A (J)'Access,
kono
parents:
diff changeset
403 Control => (Controlled with TC))
kono
parents:
diff changeset
404 do
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
405 Busy (TC.all);
111
kono
parents:
diff changeset
406 end return;
kono
parents:
diff changeset
407 end;
kono
parents:
diff changeset
408 end Constant_Reference;
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 function Constant_Reference
kono
parents:
diff changeset
411 (Container : aliased Vector;
kono
parents:
diff changeset
412 Index : Index_Type) return Constant_Reference_Type
kono
parents:
diff changeset
413 is
kono
parents:
diff changeset
414 begin
kono
parents:
diff changeset
415 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
416 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
417 end if;
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 declare
kono
parents:
diff changeset
420 A : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
421 J : constant Count_Type := To_Array_Index (Index);
kono
parents:
diff changeset
422 TC : constant Tamper_Counts_Access :=
kono
parents:
diff changeset
423 Container.TC'Unrestricted_Access;
kono
parents:
diff changeset
424 begin
kono
parents:
diff changeset
425 return R : constant Constant_Reference_Type :=
kono
parents:
diff changeset
426 (Element => A (J)'Access,
kono
parents:
diff changeset
427 Control => (Controlled with TC))
kono
parents:
diff changeset
428 do
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
429 Busy (TC.all);
111
kono
parents:
diff changeset
430 end return;
kono
parents:
diff changeset
431 end;
kono
parents:
diff changeset
432 end Constant_Reference;
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 --------------
kono
parents:
diff changeset
435 -- Contains --
kono
parents:
diff changeset
436 --------------
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 function Contains
kono
parents:
diff changeset
439 (Container : Vector;
kono
parents:
diff changeset
440 Item : Element_Type) return Boolean
kono
parents:
diff changeset
441 is
kono
parents:
diff changeset
442 begin
kono
parents:
diff changeset
443 return Find_Index (Container, Item) /= No_Index;
kono
parents:
diff changeset
444 end Contains;
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 ----------
kono
parents:
diff changeset
447 -- Copy --
kono
parents:
diff changeset
448 ----------
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 function Copy
kono
parents:
diff changeset
451 (Source : Vector;
kono
parents:
diff changeset
452 Capacity : Count_Type := 0) return Vector
kono
parents:
diff changeset
453 is
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
454 C : constant Count_Type :=
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
455 (if Capacity = 0 then Source.Length
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
456 else Capacity);
111
kono
parents:
diff changeset
457 begin
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 if Checks and then C < Source.Length then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 raise Capacity_Error with "Capacity too small";
111
kono
parents:
diff changeset
460 end if;
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 return Target : Vector (C) do
kono
parents:
diff changeset
463 Target.Elements (1 .. Source.Length) :=
kono
parents:
diff changeset
464 Source.Elements (1 .. Source.Length);
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 Target.Last := Source.Last;
kono
parents:
diff changeset
467 end return;
kono
parents:
diff changeset
468 end Copy;
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 ------------
kono
parents:
diff changeset
471 -- Delete --
kono
parents:
diff changeset
472 ------------
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 procedure Delete
kono
parents:
diff changeset
475 (Container : in out Vector;
kono
parents:
diff changeset
476 Index : Extended_Index;
kono
parents:
diff changeset
477 Count : Count_Type := 1)
kono
parents:
diff changeset
478 is
kono
parents:
diff changeset
479 Old_Last : constant Index_Type'Base := Container.Last;
kono
parents:
diff changeset
480 Old_Len : constant Count_Type := Container.Length;
kono
parents:
diff changeset
481 New_Last : Index_Type'Base;
kono
parents:
diff changeset
482 Count2 : Count_Type'Base; -- count of items from Index to Old_Last
kono
parents:
diff changeset
483 Off : Count_Type'Base; -- Index expressed as offset from IT'First
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 begin
kono
parents:
diff changeset
486 -- Delete removes items from the vector, the number of which is the
kono
parents:
diff changeset
487 -- minimum of the specified Count and the items (if any) that exist from
kono
parents:
diff changeset
488 -- Index to Container.Last. There are no constraints on the specified
kono
parents:
diff changeset
489 -- value of Count (it can be larger than what's available at this
kono
parents:
diff changeset
490 -- position in the vector, for example), but there are constraints on
kono
parents:
diff changeset
491 -- the allowed values of the Index.
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 -- As a precondition on the generic actual Index_Type, the base type
kono
parents:
diff changeset
494 -- must include Index_Type'Pred (Index_Type'First); this is the value
kono
parents:
diff changeset
495 -- that Container.Last assumes when the vector is empty. However, we do
kono
parents:
diff changeset
496 -- not allow that as the value for Index when specifying which items
kono
parents:
diff changeset
497 -- should be deleted, so we must manually check. (That the user is
kono
parents:
diff changeset
498 -- allowed to specify the value at all here is a consequence of the
kono
parents:
diff changeset
499 -- declaration of the Extended_Index subtype, which includes the values
kono
parents:
diff changeset
500 -- in the base range that immediately precede and immediately follow the
kono
parents:
diff changeset
501 -- values in the Index_Type.)
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 if Checks and then Index < Index_Type'First then
kono
parents:
diff changeset
504 raise Constraint_Error with "Index is out of range (too small)";
kono
parents:
diff changeset
505 end if;
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 -- We do allow a value greater than Container.Last to be specified as
kono
parents:
diff changeset
508 -- the Index, but only if it's immediately greater. This allows the
kono
parents:
diff changeset
509 -- corner case of deleting no items from the back end of the vector to
kono
parents:
diff changeset
510 -- be treated as a no-op. (It is assumed that specifying an index value
kono
parents:
diff changeset
511 -- greater than Last + 1 indicates some deeper flaw in the caller's
kono
parents:
diff changeset
512 -- algorithm, so that case is treated as a proper error.)
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 if Index > Old_Last then
kono
parents:
diff changeset
515 if Checks and then Index > Old_Last + 1 then
kono
parents:
diff changeset
516 raise Constraint_Error with "Index is out of range (too large)";
kono
parents:
diff changeset
517 end if;
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 return;
kono
parents:
diff changeset
520 end if;
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 -- Here and elsewhere we treat deleting 0 items from the container as a
kono
parents:
diff changeset
523 -- no-op, even when the container is busy, so we simply return.
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 if Count = 0 then
kono
parents:
diff changeset
526 return;
kono
parents:
diff changeset
527 end if;
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 -- The tampering bits exist to prevent an item from being deleted (or
kono
parents:
diff changeset
530 -- otherwise harmfully manipulated) while it is being visited. Query,
kono
parents:
diff changeset
531 -- Update, and Iterate increment the busy count on entry, and decrement
kono
parents:
diff changeset
532 -- the count on exit. Delete checks the count to determine whether it is
kono
parents:
diff changeset
533 -- being called while the associated callback procedure is executing.
kono
parents:
diff changeset
534
kono
parents:
diff changeset
535 TC_Check (Container.TC);
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 -- We first calculate what's available for deletion starting at
kono
parents:
diff changeset
538 -- Index. Here and elsewhere we use the wider of Index_Type'Base and
kono
parents:
diff changeset
539 -- Count_Type'Base as the type for intermediate values. (See function
kono
parents:
diff changeset
540 -- Length for more information.)
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 if Count_Type'Base'Last >= Index_Type'Pos (Index_Type'Base'Last) then
kono
parents:
diff changeset
543 Count2 := Count_Type'Base (Old_Last) - Count_Type'Base (Index) + 1;
kono
parents:
diff changeset
544 else
kono
parents:
diff changeset
545 Count2 := Count_Type'Base (Old_Last - Index + 1);
kono
parents:
diff changeset
546 end if;
kono
parents:
diff changeset
547
kono
parents:
diff changeset
548 -- If more elements are requested (Count) for deletion than are
kono
parents:
diff changeset
549 -- available (Count2) for deletion beginning at Index, then everything
kono
parents:
diff changeset
550 -- from Index is deleted. There are no elements to slide down, and so
kono
parents:
diff changeset
551 -- all we need to do is set the value of Container.Last.
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 if Count >= Count2 then
kono
parents:
diff changeset
554 Container.Last := Index - 1;
kono
parents:
diff changeset
555 return;
kono
parents:
diff changeset
556 end if;
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 -- There are some elements aren't being deleted (the requested count was
kono
parents:
diff changeset
559 -- less than the available count), so we must slide them down to
kono
parents:
diff changeset
560 -- Index. We first calculate the index values of the respective array
kono
parents:
diff changeset
561 -- slices, using the wider of Index_Type'Base and Count_Type'Base as the
kono
parents:
diff changeset
562 -- type for intermediate calculations.
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
565 Off := Count_Type'Base (Index - Index_Type'First);
kono
parents:
diff changeset
566 New_Last := Old_Last - Index_Type'Base (Count);
kono
parents:
diff changeset
567 else
kono
parents:
diff changeset
568 Off := Count_Type'Base (Index) - Count_Type'Base (Index_Type'First);
kono
parents:
diff changeset
569 New_Last := Index_Type'Base (Count_Type'Base (Old_Last) - Count);
kono
parents:
diff changeset
570 end if;
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 -- The array index values for each slice have already been determined,
kono
parents:
diff changeset
573 -- so we just slide down to Index the elements that weren't deleted.
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 declare
kono
parents:
diff changeset
576 EA : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
577 Idx : constant Count_Type := EA'First + Off;
kono
parents:
diff changeset
578 begin
kono
parents:
diff changeset
579 EA (Idx .. Old_Len - Count) := EA (Idx + Count .. Old_Len);
kono
parents:
diff changeset
580 Container.Last := New_Last;
kono
parents:
diff changeset
581 end;
kono
parents:
diff changeset
582 end Delete;
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 procedure Delete
kono
parents:
diff changeset
585 (Container : in out Vector;
kono
parents:
diff changeset
586 Position : in out Cursor;
kono
parents:
diff changeset
587 Count : Count_Type := 1)
kono
parents:
diff changeset
588 is
kono
parents:
diff changeset
589 pragma Warnings (Off, Position);
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 begin
kono
parents:
diff changeset
592 if Checks and then Position.Container = null then
kono
parents:
diff changeset
593 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
594 end if;
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
597 then
kono
parents:
diff changeset
598 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
599 end if;
kono
parents:
diff changeset
600
kono
parents:
diff changeset
601 if Checks and then Position.Index > Container.Last then
kono
parents:
diff changeset
602 raise Program_Error with "Position index is out of range";
kono
parents:
diff changeset
603 end if;
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 Delete (Container, Position.Index, Count);
kono
parents:
diff changeset
606 Position := No_Element;
kono
parents:
diff changeset
607 end Delete;
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 ------------------
kono
parents:
diff changeset
610 -- Delete_First --
kono
parents:
diff changeset
611 ------------------
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 procedure Delete_First
kono
parents:
diff changeset
614 (Container : in out Vector;
kono
parents:
diff changeset
615 Count : Count_Type := 1)
kono
parents:
diff changeset
616 is
kono
parents:
diff changeset
617 begin
kono
parents:
diff changeset
618 if Count = 0 then
kono
parents:
diff changeset
619 return;
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 elsif Count >= Length (Container) then
kono
parents:
diff changeset
622 Clear (Container);
kono
parents:
diff changeset
623 return;
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 else
kono
parents:
diff changeset
626 Delete (Container, Index_Type'First, Count);
kono
parents:
diff changeset
627 end if;
kono
parents:
diff changeset
628 end Delete_First;
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 -----------------
kono
parents:
diff changeset
631 -- Delete_Last --
kono
parents:
diff changeset
632 -----------------
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 procedure Delete_Last
kono
parents:
diff changeset
635 (Container : in out Vector;
kono
parents:
diff changeset
636 Count : Count_Type := 1)
kono
parents:
diff changeset
637 is
kono
parents:
diff changeset
638 begin
kono
parents:
diff changeset
639 -- It is not permitted to delete items while the container is busy (for
kono
parents:
diff changeset
640 -- example, we're in the middle of a passive iteration). However, we
kono
parents:
diff changeset
641 -- always treat deleting 0 items as a no-op, even when we're busy, so we
kono
parents:
diff changeset
642 -- simply return without checking.
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 if Count = 0 then
kono
parents:
diff changeset
645 return;
kono
parents:
diff changeset
646 end if;
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 -- The tampering bits exist to prevent an item from being deleted (or
kono
parents:
diff changeset
649 -- otherwise harmfully manipulated) while it is being visited. Query,
kono
parents:
diff changeset
650 -- Update, and Iterate increment the busy count on entry, and decrement
kono
parents:
diff changeset
651 -- the count on exit. Delete_Last checks the count to determine whether
kono
parents:
diff changeset
652 -- it is being called while the associated callback procedure is
kono
parents:
diff changeset
653 -- executing.
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 TC_Check (Container.TC);
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 -- There is no restriction on how large Count can be when deleting
kono
parents:
diff changeset
658 -- items. If it is equal or greater than the current length, then this
kono
parents:
diff changeset
659 -- is equivalent to clearing the vector. (In particular, there's no need
kono
parents:
diff changeset
660 -- for us to actually calculate the new value for Last.)
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 -- If the requested count is less than the current length, then we must
kono
parents:
diff changeset
663 -- calculate the new value for Last. For the type we use the widest of
kono
parents:
diff changeset
664 -- Index_Type'Base and Count_Type'Base for the intermediate values of
kono
parents:
diff changeset
665 -- our calculation. (See the comments in Length for more information.)
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 if Count >= Container.Length then
kono
parents:
diff changeset
668 Container.Last := No_Index;
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 elsif Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
671 Container.Last := Container.Last - Index_Type'Base (Count);
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 else
kono
parents:
diff changeset
674 Container.Last :=
kono
parents:
diff changeset
675 Index_Type'Base (Count_Type'Base (Container.Last) - Count);
kono
parents:
diff changeset
676 end if;
kono
parents:
diff changeset
677 end Delete_Last;
kono
parents:
diff changeset
678
kono
parents:
diff changeset
679 -------------
kono
parents:
diff changeset
680 -- Element --
kono
parents:
diff changeset
681 -------------
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 function Element
kono
parents:
diff changeset
684 (Container : Vector;
kono
parents:
diff changeset
685 Index : Index_Type) return Element_Type
kono
parents:
diff changeset
686 is
kono
parents:
diff changeset
687 begin
kono
parents:
diff changeset
688 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
689 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
690 else
kono
parents:
diff changeset
691 return Container.Elements (To_Array_Index (Index));
kono
parents:
diff changeset
692 end if;
kono
parents:
diff changeset
693 end Element;
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 function Element (Position : Cursor) return Element_Type is
kono
parents:
diff changeset
696 begin
kono
parents:
diff changeset
697 if Checks and then Position.Container = null then
kono
parents:
diff changeset
698 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
699 else
kono
parents:
diff changeset
700 return Position.Container.Element (Position.Index);
kono
parents:
diff changeset
701 end if;
kono
parents:
diff changeset
702 end Element;
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 --------------
kono
parents:
diff changeset
705 -- Finalize --
kono
parents:
diff changeset
706 --------------
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 procedure Finalize (Object : in out Iterator) is
kono
parents:
diff changeset
709 begin
kono
parents:
diff changeset
710 Unbusy (Object.Container.TC);
kono
parents:
diff changeset
711 end Finalize;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 ----------
kono
parents:
diff changeset
714 -- Find --
kono
parents:
diff changeset
715 ----------
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 function Find
kono
parents:
diff changeset
718 (Container : Vector;
kono
parents:
diff changeset
719 Item : Element_Type;
kono
parents:
diff changeset
720 Position : Cursor := No_Element) return Cursor
kono
parents:
diff changeset
721 is
kono
parents:
diff changeset
722 begin
kono
parents:
diff changeset
723 if Position.Container /= null then
kono
parents:
diff changeset
724 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
725 then
kono
parents:
diff changeset
726 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
727 end if;
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 if Checks and then Position.Index > Container.Last then
kono
parents:
diff changeset
730 raise Program_Error with "Position index is out of range";
kono
parents:
diff changeset
731 end if;
kono
parents:
diff changeset
732 end if;
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
735 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 declare
kono
parents:
diff changeset
738 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
739 begin
kono
parents:
diff changeset
740 for J in Position.Index .. Container.Last loop
kono
parents:
diff changeset
741 if Container.Elements (To_Array_Index (J)) = Item then
kono
parents:
diff changeset
742 return Cursor'(Container'Unrestricted_Access, J);
kono
parents:
diff changeset
743 end if;
kono
parents:
diff changeset
744 end loop;
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 return No_Element;
kono
parents:
diff changeset
747 end;
kono
parents:
diff changeset
748 end Find;
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 ----------------
kono
parents:
diff changeset
751 -- Find_Index --
kono
parents:
diff changeset
752 ----------------
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 function Find_Index
kono
parents:
diff changeset
755 (Container : Vector;
kono
parents:
diff changeset
756 Item : Element_Type;
kono
parents:
diff changeset
757 Index : Index_Type := Index_Type'First) return Extended_Index
kono
parents:
diff changeset
758 is
kono
parents:
diff changeset
759 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
760 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
761
kono
parents:
diff changeset
762 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
763 begin
kono
parents:
diff changeset
764 for Indx in Index .. Container.Last loop
kono
parents:
diff changeset
765 if Container.Elements (To_Array_Index (Indx)) = Item then
kono
parents:
diff changeset
766 return Indx;
kono
parents:
diff changeset
767 end if;
kono
parents:
diff changeset
768 end loop;
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 return No_Index;
kono
parents:
diff changeset
771 end Find_Index;
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 -----------
kono
parents:
diff changeset
774 -- First --
kono
parents:
diff changeset
775 -----------
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 function First (Container : Vector) return Cursor is
kono
parents:
diff changeset
778 begin
kono
parents:
diff changeset
779 if Is_Empty (Container) then
kono
parents:
diff changeset
780 return No_Element;
kono
parents:
diff changeset
781 else
kono
parents:
diff changeset
782 return (Container'Unrestricted_Access, Index_Type'First);
kono
parents:
diff changeset
783 end if;
kono
parents:
diff changeset
784 end First;
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 function First (Object : Iterator) return Cursor is
kono
parents:
diff changeset
787 begin
kono
parents:
diff changeset
788 -- The value of the iterator object's Index component influences the
kono
parents:
diff changeset
789 -- behavior of the First (and Last) selector function.
kono
parents:
diff changeset
790
kono
parents:
diff changeset
791 -- When the Index component is No_Index, this means the iterator
kono
parents:
diff changeset
792 -- object was constructed without a start expression, in which case the
kono
parents:
diff changeset
793 -- (forward) iteration starts from the (logical) beginning of the entire
kono
parents:
diff changeset
794 -- sequence of items (corresponding to Container.First, for a forward
kono
parents:
diff changeset
795 -- iterator).
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 -- Otherwise, this is iteration over a partial sequence of items.
kono
parents:
diff changeset
798 -- When the Index component isn't No_Index, the iterator object was
kono
parents:
diff changeset
799 -- constructed with a start expression, that specifies the position
kono
parents:
diff changeset
800 -- from which the (forward) partial iteration begins.
kono
parents:
diff changeset
801
kono
parents:
diff changeset
802 if Object.Index = No_Index then
kono
parents:
diff changeset
803 return First (Object.Container.all);
kono
parents:
diff changeset
804 else
kono
parents:
diff changeset
805 return Cursor'(Object.Container, Object.Index);
kono
parents:
diff changeset
806 end if;
kono
parents:
diff changeset
807 end First;
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 -------------------
kono
parents:
diff changeset
810 -- First_Element --
kono
parents:
diff changeset
811 -------------------
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 function First_Element (Container : Vector) return Element_Type is
kono
parents:
diff changeset
814 begin
kono
parents:
diff changeset
815 if Checks and then Container.Last = No_Index then
kono
parents:
diff changeset
816 raise Constraint_Error with "Container is empty";
kono
parents:
diff changeset
817 end if;
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 return Container.Elements (To_Array_Index (Index_Type'First));
kono
parents:
diff changeset
820 end First_Element;
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 -----------------
kono
parents:
diff changeset
823 -- First_Index --
kono
parents:
diff changeset
824 -----------------
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 function First_Index (Container : Vector) return Index_Type is
kono
parents:
diff changeset
827 pragma Unreferenced (Container);
kono
parents:
diff changeset
828 begin
kono
parents:
diff changeset
829 return Index_Type'First;
kono
parents:
diff changeset
830 end First_Index;
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 ---------------------
kono
parents:
diff changeset
833 -- Generic_Sorting --
kono
parents:
diff changeset
834 ---------------------
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 package body Generic_Sorting is
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 ---------------
kono
parents:
diff changeset
839 -- Is_Sorted --
kono
parents:
diff changeset
840 ---------------
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 function Is_Sorted (Container : Vector) return Boolean is
kono
parents:
diff changeset
843 begin
kono
parents:
diff changeset
844 if Container.Last <= Index_Type'First then
kono
parents:
diff changeset
845 return True;
kono
parents:
diff changeset
846 end if;
kono
parents:
diff changeset
847
kono
parents:
diff changeset
848 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
849 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
850
kono
parents:
diff changeset
851 declare
kono
parents:
diff changeset
852 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
853 EA : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
854 begin
kono
parents:
diff changeset
855 for J in 1 .. Container.Length - 1 loop
kono
parents:
diff changeset
856 if EA (J + 1) < EA (J) then
kono
parents:
diff changeset
857 return False;
kono
parents:
diff changeset
858 end if;
kono
parents:
diff changeset
859 end loop;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 return True;
kono
parents:
diff changeset
862 end;
kono
parents:
diff changeset
863 end Is_Sorted;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 -----------
kono
parents:
diff changeset
866 -- Merge --
kono
parents:
diff changeset
867 -----------
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 procedure Merge (Target, Source : in out Vector) is
kono
parents:
diff changeset
870 I, J : Count_Type;
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 begin
kono
parents:
diff changeset
873 -- The semantics of Merge changed slightly per AI05-0021. It was
kono
parents:
diff changeset
874 -- originally the case that if Target and Source denoted the same
kono
parents:
diff changeset
875 -- container object, then the GNAT implementation of Merge did
kono
parents:
diff changeset
876 -- nothing. However, it was argued that RM05 did not precisely
kono
parents:
diff changeset
877 -- specify the semantics for this corner case. The decision of the
kono
parents:
diff changeset
878 -- ARG was that if Target and Source denote the same non-empty
kono
parents:
diff changeset
879 -- container object, then Program_Error is raised.
kono
parents:
diff changeset
880
kono
parents:
diff changeset
881 if Source.Is_Empty then
kono
parents:
diff changeset
882 return;
kono
parents:
diff changeset
883 end if;
kono
parents:
diff changeset
884
kono
parents:
diff changeset
885 if Checks and then Target'Address = Source'Address then
kono
parents:
diff changeset
886 raise Program_Error with
kono
parents:
diff changeset
887 "Target and Source denote same non-empty container";
kono
parents:
diff changeset
888 end if;
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 if Target.Is_Empty then
kono
parents:
diff changeset
891 Move (Target => Target, Source => Source);
kono
parents:
diff changeset
892 return;
kono
parents:
diff changeset
893 end if;
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 TC_Check (Source.TC);
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 I := Target.Length;
kono
parents:
diff changeset
898 Target.Set_Length (I + Source.Length);
kono
parents:
diff changeset
899
kono
parents:
diff changeset
900 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
901 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903 declare
kono
parents:
diff changeset
904 TA : Elements_Array renames Target.Elements;
kono
parents:
diff changeset
905 SA : Elements_Array renames Source.Elements;
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907 Lock_Target : With_Lock (Target.TC'Unchecked_Access);
kono
parents:
diff changeset
908 Lock_Source : With_Lock (Source.TC'Unchecked_Access);
kono
parents:
diff changeset
909 begin
kono
parents:
diff changeset
910 J := Target.Length;
kono
parents:
diff changeset
911 while not Source.Is_Empty loop
kono
parents:
diff changeset
912 pragma Assert (Source.Length <= 1
kono
parents:
diff changeset
913 or else not (SA (Source.Length) < SA (Source.Length - 1)));
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 if I = 0 then
kono
parents:
diff changeset
916 TA (1 .. J) := SA (1 .. Source.Length);
kono
parents:
diff changeset
917 Source.Last := No_Index;
kono
parents:
diff changeset
918 exit;
kono
parents:
diff changeset
919 end if;
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 pragma Assert (I <= 1
kono
parents:
diff changeset
922 or else not (TA (I) < TA (I - 1)));
kono
parents:
diff changeset
923
kono
parents:
diff changeset
924 if SA (Source.Length) < TA (I) then
kono
parents:
diff changeset
925 TA (J) := TA (I);
kono
parents:
diff changeset
926 I := I - 1;
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 else
kono
parents:
diff changeset
929 TA (J) := SA (Source.Length);
kono
parents:
diff changeset
930 Source.Last := Source.Last - 1;
kono
parents:
diff changeset
931 end if;
kono
parents:
diff changeset
932
kono
parents:
diff changeset
933 J := J - 1;
kono
parents:
diff changeset
934 end loop;
kono
parents:
diff changeset
935 end;
kono
parents:
diff changeset
936 end Merge;
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 ----------
kono
parents:
diff changeset
939 -- Sort --
kono
parents:
diff changeset
940 ----------
kono
parents:
diff changeset
941
kono
parents:
diff changeset
942 procedure Sort (Container : in out Vector) is
kono
parents:
diff changeset
943 procedure Sort is
kono
parents:
diff changeset
944 new Generic_Array_Sort
kono
parents:
diff changeset
945 (Index_Type => Count_Type,
kono
parents:
diff changeset
946 Element_Type => Element_Type,
kono
parents:
diff changeset
947 Array_Type => Elements_Array,
kono
parents:
diff changeset
948 "<" => "<");
kono
parents:
diff changeset
949
kono
parents:
diff changeset
950 begin
kono
parents:
diff changeset
951 if Container.Last <= Index_Type'First then
kono
parents:
diff changeset
952 return;
kono
parents:
diff changeset
953 end if;
kono
parents:
diff changeset
954
kono
parents:
diff changeset
955 -- The exception behavior for the vector container must match that
kono
parents:
diff changeset
956 -- for the list container, so we check for cursor tampering here
kono
parents:
diff changeset
957 -- (which will catch more things) instead of for element tampering
kono
parents:
diff changeset
958 -- (which will catch fewer things). It's true that the elements of
kono
parents:
diff changeset
959 -- this vector container could be safely moved around while (say) an
kono
parents:
diff changeset
960 -- iteration is taking place (iteration only increments the busy
kono
parents:
diff changeset
961 -- counter), and so technically all we would need here is a test for
kono
parents:
diff changeset
962 -- element tampering (indicated by the lock counter), that's simply
kono
parents:
diff changeset
963 -- an artifact of our array-based implementation. Logically Sort
kono
parents:
diff changeset
964 -- requires a check for cursor tampering.
kono
parents:
diff changeset
965
kono
parents:
diff changeset
966 TC_Check (Container.TC);
kono
parents:
diff changeset
967
kono
parents:
diff changeset
968 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
969 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 declare
kono
parents:
diff changeset
972 Lock : With_Lock (Container.TC'Unchecked_Access);
kono
parents:
diff changeset
973 begin
kono
parents:
diff changeset
974 Sort (Container.Elements (1 .. Container.Length));
kono
parents:
diff changeset
975 end;
kono
parents:
diff changeset
976 end Sort;
kono
parents:
diff changeset
977
kono
parents:
diff changeset
978 end Generic_Sorting;
kono
parents:
diff changeset
979
kono
parents:
diff changeset
980 ------------------------
kono
parents:
diff changeset
981 -- Get_Element_Access --
kono
parents:
diff changeset
982 ------------------------
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 function Get_Element_Access
kono
parents:
diff changeset
985 (Position : Cursor) return not null Element_Access is
kono
parents:
diff changeset
986 begin
kono
parents:
diff changeset
987 return Position.Container.Elements
kono
parents:
diff changeset
988 (To_Array_Index (Position.Index))'Access;
kono
parents:
diff changeset
989 end Get_Element_Access;
kono
parents:
diff changeset
990
kono
parents:
diff changeset
991 -----------------
kono
parents:
diff changeset
992 -- Has_Element --
kono
parents:
diff changeset
993 -----------------
kono
parents:
diff changeset
994
kono
parents:
diff changeset
995 function Has_Element (Position : Cursor) return Boolean is
kono
parents:
diff changeset
996 begin
kono
parents:
diff changeset
997 if Position.Container = null then
kono
parents:
diff changeset
998 return False;
kono
parents:
diff changeset
999 end if;
kono
parents:
diff changeset
1000
kono
parents:
diff changeset
1001 return Position.Index <= Position.Container.Last;
kono
parents:
diff changeset
1002 end Has_Element;
kono
parents:
diff changeset
1003
kono
parents:
diff changeset
1004 ------------
kono
parents:
diff changeset
1005 -- Insert --
kono
parents:
diff changeset
1006 ------------
kono
parents:
diff changeset
1007
kono
parents:
diff changeset
1008 procedure Insert
kono
parents:
diff changeset
1009 (Container : in out Vector;
kono
parents:
diff changeset
1010 Before : Extended_Index;
kono
parents:
diff changeset
1011 New_Item : Element_Type;
kono
parents:
diff changeset
1012 Count : Count_Type := 1)
kono
parents:
diff changeset
1013 is
kono
parents:
diff changeset
1014 EA : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
1015 Old_Length : constant Count_Type := Container.Length;
kono
parents:
diff changeset
1016
kono
parents:
diff changeset
1017 Max_Length : Count_Type'Base; -- determined from range of Index_Type
kono
parents:
diff changeset
1018 New_Length : Count_Type'Base; -- sum of current length and Count
kono
parents:
diff changeset
1019
kono
parents:
diff changeset
1020 Index : Index_Type'Base; -- scratch for intermediate values
kono
parents:
diff changeset
1021 J : Count_Type'Base; -- scratch
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 begin
kono
parents:
diff changeset
1024 -- As a precondition on the generic actual Index_Type, the base type
kono
parents:
diff changeset
1025 -- must include Index_Type'Pred (Index_Type'First); this is the value
kono
parents:
diff changeset
1026 -- that Container.Last assumes when the vector is empty. However, we do
kono
parents:
diff changeset
1027 -- not allow that as the value for Index when specifying where the new
kono
parents:
diff changeset
1028 -- items should be inserted, so we must manually check. (That the user
kono
parents:
diff changeset
1029 -- is allowed to specify the value at all here is a consequence of the
kono
parents:
diff changeset
1030 -- declaration of the Extended_Index subtype, which includes the values
kono
parents:
diff changeset
1031 -- in the base range that immediately precede and immediately follow the
kono
parents:
diff changeset
1032 -- values in the Index_Type.)
kono
parents:
diff changeset
1033
kono
parents:
diff changeset
1034 if Checks and then Before < Index_Type'First then
kono
parents:
diff changeset
1035 raise Constraint_Error with
kono
parents:
diff changeset
1036 "Before index is out of range (too small)";
kono
parents:
diff changeset
1037 end if;
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 -- We do allow a value greater than Container.Last to be specified as
kono
parents:
diff changeset
1040 -- the Index, but only if it's immediately greater. This allows for the
kono
parents:
diff changeset
1041 -- case of appending items to the back end of the vector. (It is assumed
kono
parents:
diff changeset
1042 -- that specifying an index value greater than Last + 1 indicates some
kono
parents:
diff changeset
1043 -- deeper flaw in the caller's algorithm, so that case is treated as a
kono
parents:
diff changeset
1044 -- proper error.)
kono
parents:
diff changeset
1045
kono
parents:
diff changeset
1046 if Checks and then Before > Container.Last
kono
parents:
diff changeset
1047 and then Before > Container.Last + 1
kono
parents:
diff changeset
1048 then
kono
parents:
diff changeset
1049 raise Constraint_Error with
kono
parents:
diff changeset
1050 "Before index is out of range (too large)";
kono
parents:
diff changeset
1051 end if;
kono
parents:
diff changeset
1052
kono
parents:
diff changeset
1053 -- We treat inserting 0 items into the container as a no-op, even when
kono
parents:
diff changeset
1054 -- the container is busy, so we simply return.
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 if Count = 0 then
kono
parents:
diff changeset
1057 return;
kono
parents:
diff changeset
1058 end if;
kono
parents:
diff changeset
1059
kono
parents:
diff changeset
1060 -- There are two constraints we need to satisfy. The first constraint is
kono
parents:
diff changeset
1061 -- that a container cannot have more than Count_Type'Last elements, so
kono
parents:
diff changeset
1062 -- we must check the sum of the current length and the insertion
kono
parents:
diff changeset
1063 -- count. Note that we cannot simply add these values, because of the
kono
parents:
diff changeset
1064 -- possibility of overflow.
kono
parents:
diff changeset
1065
kono
parents:
diff changeset
1066 if Checks and then Old_Length > Count_Type'Last - Count then
kono
parents:
diff changeset
1067 raise Constraint_Error with "Count is out of range";
kono
parents:
diff changeset
1068 end if;
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 -- It is now safe compute the length of the new vector, without fear of
kono
parents:
diff changeset
1071 -- overflow.
kono
parents:
diff changeset
1072
kono
parents:
diff changeset
1073 New_Length := Old_Length + Count;
kono
parents:
diff changeset
1074
kono
parents:
diff changeset
1075 -- The second constraint is that the new Last index value cannot exceed
kono
parents:
diff changeset
1076 -- Index_Type'Last. In each branch below, we calculate the maximum
kono
parents:
diff changeset
1077 -- length (computed from the range of values in Index_Type), and then
kono
parents:
diff changeset
1078 -- compare the new length to the maximum length. If the new length is
kono
parents:
diff changeset
1079 -- acceptable, then we compute the new last index from that.
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
1082
kono
parents:
diff changeset
1083 -- We have to handle the case when there might be more values in the
kono
parents:
diff changeset
1084 -- range of Index_Type than in the range of Count_Type.
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 if Index_Type'First <= 0 then
kono
parents:
diff changeset
1087
kono
parents:
diff changeset
1088 -- We know that No_Index (the same as Index_Type'First - 1) is
kono
parents:
diff changeset
1089 -- less than 0, so it is safe to compute the following sum without
kono
parents:
diff changeset
1090 -- fear of overflow.
kono
parents:
diff changeset
1091
kono
parents:
diff changeset
1092 Index := No_Index + Index_Type'Base (Count_Type'Last);
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 if Index <= Index_Type'Last then
kono
parents:
diff changeset
1095
kono
parents:
diff changeset
1096 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1097 -- many values as in Count_Type, so Count_Type'Last is the
kono
parents:
diff changeset
1098 -- maximum number of items that are allowed.
kono
parents:
diff changeset
1099
kono
parents:
diff changeset
1100 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1101
kono
parents:
diff changeset
1102 else
kono
parents:
diff changeset
1103 -- The range of Index_Type has fewer values than in Count_Type,
kono
parents:
diff changeset
1104 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1105 -- the Index_Type.
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 Max_Length := Count_Type'Base (Index_Type'Last - No_Index);
kono
parents:
diff changeset
1108 end if;
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 else
kono
parents:
diff changeset
1111 -- No_Index is equal or greater than 0, so we can safely compute
kono
parents:
diff changeset
1112 -- the difference without fear of overflow (which we would have to
kono
parents:
diff changeset
1113 -- worry about if No_Index were less than 0, but that case is
kono
parents:
diff changeset
1114 -- handled above).
kono
parents:
diff changeset
1115
kono
parents:
diff changeset
1116 if Index_Type'Last - No_Index >=
kono
parents:
diff changeset
1117 Count_Type'Pos (Count_Type'Last)
kono
parents:
diff changeset
1118 then
kono
parents:
diff changeset
1119 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1120 -- many values as in Count_Type, so Count_Type'Last is the
kono
parents:
diff changeset
1121 -- maximum number of items that are allowed.
kono
parents:
diff changeset
1122
kono
parents:
diff changeset
1123 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1124
kono
parents:
diff changeset
1125 else
kono
parents:
diff changeset
1126 -- The range of Index_Type has fewer values than in Count_Type,
kono
parents:
diff changeset
1127 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1128 -- the Index_Type.
kono
parents:
diff changeset
1129
kono
parents:
diff changeset
1130 Max_Length := Count_Type'Base (Index_Type'Last - No_Index);
kono
parents:
diff changeset
1131 end if;
kono
parents:
diff changeset
1132 end if;
kono
parents:
diff changeset
1133
kono
parents:
diff changeset
1134 elsif Index_Type'First <= 0 then
kono
parents:
diff changeset
1135
kono
parents:
diff changeset
1136 -- We know that No_Index (the same as Index_Type'First - 1) is less
kono
parents:
diff changeset
1137 -- than 0, so it is safe to compute the following sum without fear of
kono
parents:
diff changeset
1138 -- overflow.
kono
parents:
diff changeset
1139
kono
parents:
diff changeset
1140 J := Count_Type'Base (No_Index) + Count_Type'Last;
kono
parents:
diff changeset
1141
kono
parents:
diff changeset
1142 if J <= Count_Type'Base (Index_Type'Last) then
kono
parents:
diff changeset
1143
kono
parents:
diff changeset
1144 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1145 -- many values as in Count_Type, so Count_Type'Last is the maximum
kono
parents:
diff changeset
1146 -- number of items that are allowed.
kono
parents:
diff changeset
1147
kono
parents:
diff changeset
1148 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1149
kono
parents:
diff changeset
1150 else
kono
parents:
diff changeset
1151 -- The range of Index_Type has fewer values than Count_Type does,
kono
parents:
diff changeset
1152 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1153 -- the Index_Type.
kono
parents:
diff changeset
1154
kono
parents:
diff changeset
1155 Max_Length :=
kono
parents:
diff changeset
1156 Count_Type'Base (Index_Type'Last) - Count_Type'Base (No_Index);
kono
parents:
diff changeset
1157 end if;
kono
parents:
diff changeset
1158
kono
parents:
diff changeset
1159 else
kono
parents:
diff changeset
1160 -- No_Index is equal or greater than 0, so we can safely compute the
kono
parents:
diff changeset
1161 -- difference without fear of overflow (which we would have to worry
kono
parents:
diff changeset
1162 -- about if No_Index were less than 0, but that case is handled
kono
parents:
diff changeset
1163 -- above).
kono
parents:
diff changeset
1164
kono
parents:
diff changeset
1165 Max_Length :=
kono
parents:
diff changeset
1166 Count_Type'Base (Index_Type'Last) - Count_Type'Base (No_Index);
kono
parents:
diff changeset
1167 end if;
kono
parents:
diff changeset
1168
kono
parents:
diff changeset
1169 -- We have just computed the maximum length (number of items). We must
kono
parents:
diff changeset
1170 -- now compare the requested length to the maximum length, as we do not
kono
parents:
diff changeset
1171 -- allow a vector expand beyond the maximum (because that would create
kono
parents:
diff changeset
1172 -- an internal array with a last index value greater than
kono
parents:
diff changeset
1173 -- Index_Type'Last, with no way to index those elements).
kono
parents:
diff changeset
1174
kono
parents:
diff changeset
1175 if Checks and then New_Length > Max_Length then
kono
parents:
diff changeset
1176 raise Constraint_Error with "Count is out of range";
kono
parents:
diff changeset
1177 end if;
kono
parents:
diff changeset
1178
kono
parents:
diff changeset
1179 -- The tampering bits exist to prevent an item from being harmfully
kono
parents:
diff changeset
1180 -- manipulated while it is being visited. Query, Update, and Iterate
kono
parents:
diff changeset
1181 -- increment the busy count on entry, and decrement the count on
kono
parents:
diff changeset
1182 -- exit. Insert checks the count to determine whether it is being called
kono
parents:
diff changeset
1183 -- while the associated callback procedure is executing.
kono
parents:
diff changeset
1184
kono
parents:
diff changeset
1185 TC_Check (Container.TC);
kono
parents:
diff changeset
1186
kono
parents:
diff changeset
1187 if Checks and then New_Length > Container.Capacity then
kono
parents:
diff changeset
1188 raise Capacity_Error with "New length is larger than capacity";
kono
parents:
diff changeset
1189 end if;
kono
parents:
diff changeset
1190
kono
parents:
diff changeset
1191 J := To_Array_Index (Before);
kono
parents:
diff changeset
1192
kono
parents:
diff changeset
1193 if Before > Container.Last then
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 -- The new items are being appended to the vector, so no
kono
parents:
diff changeset
1196 -- sliding of existing elements is required.
kono
parents:
diff changeset
1197
kono
parents:
diff changeset
1198 EA (J .. New_Length) := (others => New_Item);
kono
parents:
diff changeset
1199
kono
parents:
diff changeset
1200 else
kono
parents:
diff changeset
1201 -- The new items are being inserted before some existing
kono
parents:
diff changeset
1202 -- elements, so we must slide the existing elements up to their
kono
parents:
diff changeset
1203 -- new home.
kono
parents:
diff changeset
1204
kono
parents:
diff changeset
1205 EA (J + Count .. New_Length) := EA (J .. Old_Length);
kono
parents:
diff changeset
1206 EA (J .. J + Count - 1) := (others => New_Item);
kono
parents:
diff changeset
1207 end if;
kono
parents:
diff changeset
1208
kono
parents:
diff changeset
1209 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
1210 Container.Last := No_Index + Index_Type'Base (New_Length);
kono
parents:
diff changeset
1211
kono
parents:
diff changeset
1212 else
kono
parents:
diff changeset
1213 Container.Last :=
kono
parents:
diff changeset
1214 Index_Type'Base (Count_Type'Base (No_Index) + New_Length);
kono
parents:
diff changeset
1215 end if;
kono
parents:
diff changeset
1216 end Insert;
kono
parents:
diff changeset
1217
kono
parents:
diff changeset
1218 procedure Insert
kono
parents:
diff changeset
1219 (Container : in out Vector;
kono
parents:
diff changeset
1220 Before : Extended_Index;
kono
parents:
diff changeset
1221 New_Item : Vector)
kono
parents:
diff changeset
1222 is
kono
parents:
diff changeset
1223 N : constant Count_Type := Length (New_Item);
kono
parents:
diff changeset
1224 B : Count_Type; -- index Before converted to Count_Type
kono
parents:
diff changeset
1225
kono
parents:
diff changeset
1226 begin
kono
parents:
diff changeset
1227 -- Use Insert_Space to create the "hole" (the destination slice) into
kono
parents:
diff changeset
1228 -- which we copy the source items.
kono
parents:
diff changeset
1229
kono
parents:
diff changeset
1230 Insert_Space (Container, Before, Count => N);
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 if N = 0 then
kono
parents:
diff changeset
1233 -- There's nothing else to do here (vetting of parameters was
kono
parents:
diff changeset
1234 -- performed already in Insert_Space), so we simply return.
kono
parents:
diff changeset
1235
kono
parents:
diff changeset
1236 return;
kono
parents:
diff changeset
1237 end if;
kono
parents:
diff changeset
1238
kono
parents:
diff changeset
1239 B := To_Array_Index (Before);
kono
parents:
diff changeset
1240
kono
parents:
diff changeset
1241 if Container'Address /= New_Item'Address then
kono
parents:
diff changeset
1242 -- This is the simple case. New_Item denotes an object different
kono
parents:
diff changeset
1243 -- from Container, so there's nothing special we need to do to copy
kono
parents:
diff changeset
1244 -- the source items to their destination, because all of the source
kono
parents:
diff changeset
1245 -- items are contiguous.
kono
parents:
diff changeset
1246
kono
parents:
diff changeset
1247 Container.Elements (B .. B + N - 1) := New_Item.Elements (1 .. N);
kono
parents:
diff changeset
1248 return;
kono
parents:
diff changeset
1249 end if;
kono
parents:
diff changeset
1250
kono
parents:
diff changeset
1251 -- We refer to array index value Before + N - 1 as J. This is the last
kono
parents:
diff changeset
1252 -- index value of the destination slice.
kono
parents:
diff changeset
1253
kono
parents:
diff changeset
1254 -- New_Item denotes the same object as Container, so an insertion has
kono
parents:
diff changeset
1255 -- potentially split the source items. The destination is always the
kono
parents:
diff changeset
1256 -- range [Before, J], but the source is [Index_Type'First, Before) and
kono
parents:
diff changeset
1257 -- (J, Container.Last]. We perform the copy in two steps, using each of
kono
parents:
diff changeset
1258 -- the two slices of the source items.
kono
parents:
diff changeset
1259
kono
parents:
diff changeset
1260 declare
kono
parents:
diff changeset
1261 subtype Src_Index_Subtype is Count_Type'Base range 1 .. B - 1;
kono
parents:
diff changeset
1262
kono
parents:
diff changeset
1263 Src : Elements_Array renames Container.Elements (Src_Index_Subtype);
kono
parents:
diff changeset
1264
kono
parents:
diff changeset
1265 begin
kono
parents:
diff changeset
1266 -- We first copy the source items that precede the space we
kono
parents:
diff changeset
1267 -- inserted. (If Before equals Index_Type'First, then this first
kono
parents:
diff changeset
1268 -- source slice will be empty, which is harmless.)
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 Container.Elements (B .. B + Src'Length - 1) := Src;
kono
parents:
diff changeset
1271 end;
kono
parents:
diff changeset
1272
kono
parents:
diff changeset
1273 declare
kono
parents:
diff changeset
1274 subtype Src_Index_Subtype is Count_Type'Base range
kono
parents:
diff changeset
1275 B + N .. Container.Length;
kono
parents:
diff changeset
1276
kono
parents:
diff changeset
1277 Src : Elements_Array renames Container.Elements (Src_Index_Subtype);
kono
parents:
diff changeset
1278
kono
parents:
diff changeset
1279 begin
kono
parents:
diff changeset
1280 -- We next copy the source items that follow the space we inserted.
kono
parents:
diff changeset
1281
kono
parents:
diff changeset
1282 Container.Elements (B + N - Src'Length .. B + N - 1) := Src;
kono
parents:
diff changeset
1283 end;
kono
parents:
diff changeset
1284 end Insert;
kono
parents:
diff changeset
1285
kono
parents:
diff changeset
1286 procedure Insert
kono
parents:
diff changeset
1287 (Container : in out Vector;
kono
parents:
diff changeset
1288 Before : Cursor;
kono
parents:
diff changeset
1289 New_Item : Vector)
kono
parents:
diff changeset
1290 is
kono
parents:
diff changeset
1291 Index : Index_Type'Base;
kono
parents:
diff changeset
1292
kono
parents:
diff changeset
1293 begin
kono
parents:
diff changeset
1294 if Checks and then Before.Container /= null
kono
parents:
diff changeset
1295 and then Before.Container /= Container'Unchecked_Access
kono
parents:
diff changeset
1296 then
kono
parents:
diff changeset
1297 raise Program_Error with "Before cursor denotes wrong container";
kono
parents:
diff changeset
1298 end if;
kono
parents:
diff changeset
1299
kono
parents:
diff changeset
1300 if Is_Empty (New_Item) then
kono
parents:
diff changeset
1301 return;
kono
parents:
diff changeset
1302 end if;
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 if Before.Container = null
kono
parents:
diff changeset
1305 or else Before.Index > Container.Last
kono
parents:
diff changeset
1306 then
kono
parents:
diff changeset
1307 if Checks and then Container.Last = Index_Type'Last then
kono
parents:
diff changeset
1308 raise Constraint_Error with
kono
parents:
diff changeset
1309 "vector is already at its maximum length";
kono
parents:
diff changeset
1310 end if;
kono
parents:
diff changeset
1311
kono
parents:
diff changeset
1312 Index := Container.Last + 1;
kono
parents:
diff changeset
1313
kono
parents:
diff changeset
1314 else
kono
parents:
diff changeset
1315 Index := Before.Index;
kono
parents:
diff changeset
1316 end if;
kono
parents:
diff changeset
1317
kono
parents:
diff changeset
1318 Insert (Container, Index, New_Item);
kono
parents:
diff changeset
1319 end Insert;
kono
parents:
diff changeset
1320
kono
parents:
diff changeset
1321 procedure Insert
kono
parents:
diff changeset
1322 (Container : in out Vector;
kono
parents:
diff changeset
1323 Before : Cursor;
kono
parents:
diff changeset
1324 New_Item : Vector;
kono
parents:
diff changeset
1325 Position : out Cursor)
kono
parents:
diff changeset
1326 is
kono
parents:
diff changeset
1327 Index : Index_Type'Base;
kono
parents:
diff changeset
1328
kono
parents:
diff changeset
1329 begin
kono
parents:
diff changeset
1330 if Checks and then Before.Container /= null
kono
parents:
diff changeset
1331 and then Before.Container /= Container'Unchecked_Access
kono
parents:
diff changeset
1332 then
kono
parents:
diff changeset
1333 raise Program_Error with "Before cursor denotes wrong container";
kono
parents:
diff changeset
1334 end if;
kono
parents:
diff changeset
1335
kono
parents:
diff changeset
1336 if Is_Empty (New_Item) then
kono
parents:
diff changeset
1337 if Before.Container = null
kono
parents:
diff changeset
1338 or else Before.Index > Container.Last
kono
parents:
diff changeset
1339 then
kono
parents:
diff changeset
1340 Position := No_Element;
kono
parents:
diff changeset
1341 else
kono
parents:
diff changeset
1342 Position := (Container'Unchecked_Access, Before.Index);
kono
parents:
diff changeset
1343 end if;
kono
parents:
diff changeset
1344
kono
parents:
diff changeset
1345 return;
kono
parents:
diff changeset
1346 end if;
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 if Before.Container = null
kono
parents:
diff changeset
1349 or else Before.Index > Container.Last
kono
parents:
diff changeset
1350 then
kono
parents:
diff changeset
1351 if Checks and then Container.Last = Index_Type'Last then
kono
parents:
diff changeset
1352 raise Constraint_Error with
kono
parents:
diff changeset
1353 "vector is already at its maximum length";
kono
parents:
diff changeset
1354 end if;
kono
parents:
diff changeset
1355
kono
parents:
diff changeset
1356 Index := Container.Last + 1;
kono
parents:
diff changeset
1357
kono
parents:
diff changeset
1358 else
kono
parents:
diff changeset
1359 Index := Before.Index;
kono
parents:
diff changeset
1360 end if;
kono
parents:
diff changeset
1361
kono
parents:
diff changeset
1362 Insert (Container, Index, New_Item);
kono
parents:
diff changeset
1363
kono
parents:
diff changeset
1364 Position := Cursor'(Container'Unchecked_Access, Index);
kono
parents:
diff changeset
1365 end Insert;
kono
parents:
diff changeset
1366
kono
parents:
diff changeset
1367 procedure Insert
kono
parents:
diff changeset
1368 (Container : in out Vector;
kono
parents:
diff changeset
1369 Before : Cursor;
kono
parents:
diff changeset
1370 New_Item : Element_Type;
kono
parents:
diff changeset
1371 Count : Count_Type := 1)
kono
parents:
diff changeset
1372 is
kono
parents:
diff changeset
1373 Index : Index_Type'Base;
kono
parents:
diff changeset
1374
kono
parents:
diff changeset
1375 begin
kono
parents:
diff changeset
1376 if Checks and then Before.Container /= null
kono
parents:
diff changeset
1377 and then Before.Container /= Container'Unchecked_Access
kono
parents:
diff changeset
1378 then
kono
parents:
diff changeset
1379 raise Program_Error with "Before cursor denotes wrong container";
kono
parents:
diff changeset
1380 end if;
kono
parents:
diff changeset
1381
kono
parents:
diff changeset
1382 if Count = 0 then
kono
parents:
diff changeset
1383 return;
kono
parents:
diff changeset
1384 end if;
kono
parents:
diff changeset
1385
kono
parents:
diff changeset
1386 if Before.Container = null
kono
parents:
diff changeset
1387 or else Before.Index > Container.Last
kono
parents:
diff changeset
1388 then
kono
parents:
diff changeset
1389 if Checks and then Container.Last = Index_Type'Last then
kono
parents:
diff changeset
1390 raise Constraint_Error with
kono
parents:
diff changeset
1391 "vector is already at its maximum length";
kono
parents:
diff changeset
1392 end if;
kono
parents:
diff changeset
1393
kono
parents:
diff changeset
1394 Index := Container.Last + 1;
kono
parents:
diff changeset
1395
kono
parents:
diff changeset
1396 else
kono
parents:
diff changeset
1397 Index := Before.Index;
kono
parents:
diff changeset
1398 end if;
kono
parents:
diff changeset
1399
kono
parents:
diff changeset
1400 Insert (Container, Index, New_Item, Count);
kono
parents:
diff changeset
1401 end Insert;
kono
parents:
diff changeset
1402
kono
parents:
diff changeset
1403 procedure Insert
kono
parents:
diff changeset
1404 (Container : in out Vector;
kono
parents:
diff changeset
1405 Before : Cursor;
kono
parents:
diff changeset
1406 New_Item : Element_Type;
kono
parents:
diff changeset
1407 Position : out Cursor;
kono
parents:
diff changeset
1408 Count : Count_Type := 1)
kono
parents:
diff changeset
1409 is
kono
parents:
diff changeset
1410 Index : Index_Type'Base;
kono
parents:
diff changeset
1411
kono
parents:
diff changeset
1412 begin
kono
parents:
diff changeset
1413 if Checks and then Before.Container /= null
kono
parents:
diff changeset
1414 and then Before.Container /= Container'Unchecked_Access
kono
parents:
diff changeset
1415 then
kono
parents:
diff changeset
1416 raise Program_Error with "Before cursor denotes wrong container";
kono
parents:
diff changeset
1417 end if;
kono
parents:
diff changeset
1418
kono
parents:
diff changeset
1419 if Count = 0 then
kono
parents:
diff changeset
1420 if Before.Container = null
kono
parents:
diff changeset
1421 or else Before.Index > Container.Last
kono
parents:
diff changeset
1422 then
kono
parents:
diff changeset
1423 Position := No_Element;
kono
parents:
diff changeset
1424 else
kono
parents:
diff changeset
1425 Position := (Container'Unchecked_Access, Before.Index);
kono
parents:
diff changeset
1426 end if;
kono
parents:
diff changeset
1427
kono
parents:
diff changeset
1428 return;
kono
parents:
diff changeset
1429 end if;
kono
parents:
diff changeset
1430
kono
parents:
diff changeset
1431 if Before.Container = null
kono
parents:
diff changeset
1432 or else Before.Index > Container.Last
kono
parents:
diff changeset
1433 then
kono
parents:
diff changeset
1434 if Checks and then Container.Last = Index_Type'Last then
kono
parents:
diff changeset
1435 raise Constraint_Error with
kono
parents:
diff changeset
1436 "vector is already at its maximum length";
kono
parents:
diff changeset
1437 end if;
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 Index := Container.Last + 1;
kono
parents:
diff changeset
1440
kono
parents:
diff changeset
1441 else
kono
parents:
diff changeset
1442 Index := Before.Index;
kono
parents:
diff changeset
1443 end if;
kono
parents:
diff changeset
1444
kono
parents:
diff changeset
1445 Insert (Container, Index, New_Item, Count);
kono
parents:
diff changeset
1446
kono
parents:
diff changeset
1447 Position := Cursor'(Container'Unchecked_Access, Index);
kono
parents:
diff changeset
1448 end Insert;
kono
parents:
diff changeset
1449
kono
parents:
diff changeset
1450 procedure Insert
kono
parents:
diff changeset
1451 (Container : in out Vector;
kono
parents:
diff changeset
1452 Before : Extended_Index;
kono
parents:
diff changeset
1453 Count : Count_Type := 1)
kono
parents:
diff changeset
1454 is
kono
parents:
diff changeset
1455 New_Item : Element_Type; -- Default-initialized value
kono
parents:
diff changeset
1456 pragma Warnings (Off, New_Item);
kono
parents:
diff changeset
1457
kono
parents:
diff changeset
1458 begin
kono
parents:
diff changeset
1459 Insert (Container, Before, New_Item, Count);
kono
parents:
diff changeset
1460 end Insert;
kono
parents:
diff changeset
1461
kono
parents:
diff changeset
1462 procedure Insert
kono
parents:
diff changeset
1463 (Container : in out Vector;
kono
parents:
diff changeset
1464 Before : Cursor;
kono
parents:
diff changeset
1465 Position : out Cursor;
kono
parents:
diff changeset
1466 Count : Count_Type := 1)
kono
parents:
diff changeset
1467 is
kono
parents:
diff changeset
1468 New_Item : Element_Type; -- Default-initialized value
kono
parents:
diff changeset
1469 pragma Warnings (Off, New_Item);
kono
parents:
diff changeset
1470
kono
parents:
diff changeset
1471 begin
kono
parents:
diff changeset
1472 Insert (Container, Before, New_Item, Position, Count);
kono
parents:
diff changeset
1473 end Insert;
kono
parents:
diff changeset
1474
kono
parents:
diff changeset
1475 ------------------
kono
parents:
diff changeset
1476 -- Insert_Space --
kono
parents:
diff changeset
1477 ------------------
kono
parents:
diff changeset
1478
kono
parents:
diff changeset
1479 procedure Insert_Space
kono
parents:
diff changeset
1480 (Container : in out Vector;
kono
parents:
diff changeset
1481 Before : Extended_Index;
kono
parents:
diff changeset
1482 Count : Count_Type := 1)
kono
parents:
diff changeset
1483 is
kono
parents:
diff changeset
1484 EA : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
1485 Old_Length : constant Count_Type := Container.Length;
kono
parents:
diff changeset
1486
kono
parents:
diff changeset
1487 Max_Length : Count_Type'Base; -- determined from range of Index_Type
kono
parents:
diff changeset
1488 New_Length : Count_Type'Base; -- sum of current length and Count
kono
parents:
diff changeset
1489
kono
parents:
diff changeset
1490 Index : Index_Type'Base; -- scratch for intermediate values
kono
parents:
diff changeset
1491 J : Count_Type'Base; -- scratch
kono
parents:
diff changeset
1492
kono
parents:
diff changeset
1493 begin
kono
parents:
diff changeset
1494 -- As a precondition on the generic actual Index_Type, the base type
kono
parents:
diff changeset
1495 -- must include Index_Type'Pred (Index_Type'First); this is the value
kono
parents:
diff changeset
1496 -- that Container.Last assumes when the vector is empty. However, we do
kono
parents:
diff changeset
1497 -- not allow that as the value for Index when specifying where the new
kono
parents:
diff changeset
1498 -- items should be inserted, so we must manually check. (That the user
kono
parents:
diff changeset
1499 -- is allowed to specify the value at all here is a consequence of the
kono
parents:
diff changeset
1500 -- declaration of the Extended_Index subtype, which includes the values
kono
parents:
diff changeset
1501 -- in the base range that immediately precede and immediately follow the
kono
parents:
diff changeset
1502 -- values in the Index_Type.)
kono
parents:
diff changeset
1503
kono
parents:
diff changeset
1504 if Checks and then Before < Index_Type'First then
kono
parents:
diff changeset
1505 raise Constraint_Error with
kono
parents:
diff changeset
1506 "Before index is out of range (too small)";
kono
parents:
diff changeset
1507 end if;
kono
parents:
diff changeset
1508
kono
parents:
diff changeset
1509 -- We do allow a value greater than Container.Last to be specified as
kono
parents:
diff changeset
1510 -- the Index, but only if it's immediately greater. This allows for the
kono
parents:
diff changeset
1511 -- case of appending items to the back end of the vector. (It is assumed
kono
parents:
diff changeset
1512 -- that specifying an index value greater than Last + 1 indicates some
kono
parents:
diff changeset
1513 -- deeper flaw in the caller's algorithm, so that case is treated as a
kono
parents:
diff changeset
1514 -- proper error.)
kono
parents:
diff changeset
1515
kono
parents:
diff changeset
1516 if Checks and then Before > Container.Last
kono
parents:
diff changeset
1517 and then Before > Container.Last + 1
kono
parents:
diff changeset
1518 then
kono
parents:
diff changeset
1519 raise Constraint_Error with
kono
parents:
diff changeset
1520 "Before index is out of range (too large)";
kono
parents:
diff changeset
1521 end if;
kono
parents:
diff changeset
1522
kono
parents:
diff changeset
1523 -- We treat inserting 0 items into the container as a no-op, even when
kono
parents:
diff changeset
1524 -- the container is busy, so we simply return.
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 if Count = 0 then
kono
parents:
diff changeset
1527 return;
kono
parents:
diff changeset
1528 end if;
kono
parents:
diff changeset
1529
kono
parents:
diff changeset
1530 -- There are two constraints we need to satisfy. The first constraint is
kono
parents:
diff changeset
1531 -- that a container cannot have more than Count_Type'Last elements, so
kono
parents:
diff changeset
1532 -- we must check the sum of the current length and the insertion count.
kono
parents:
diff changeset
1533 -- Note that we cannot simply add these values, because of the
kono
parents:
diff changeset
1534 -- possibility of overflow.
kono
parents:
diff changeset
1535
kono
parents:
diff changeset
1536 if Checks and then Old_Length > Count_Type'Last - Count then
kono
parents:
diff changeset
1537 raise Constraint_Error with "Count is out of range";
kono
parents:
diff changeset
1538 end if;
kono
parents:
diff changeset
1539
kono
parents:
diff changeset
1540 -- It is now safe compute the length of the new vector, without fear of
kono
parents:
diff changeset
1541 -- overflow.
kono
parents:
diff changeset
1542
kono
parents:
diff changeset
1543 New_Length := Old_Length + Count;
kono
parents:
diff changeset
1544
kono
parents:
diff changeset
1545 -- The second constraint is that the new Last index value cannot exceed
kono
parents:
diff changeset
1546 -- Index_Type'Last. In each branch below, we calculate the maximum
kono
parents:
diff changeset
1547 -- length (computed from the range of values in Index_Type), and then
kono
parents:
diff changeset
1548 -- compare the new length to the maximum length. If the new length is
kono
parents:
diff changeset
1549 -- acceptable, then we compute the new last index from that.
kono
parents:
diff changeset
1550
kono
parents:
diff changeset
1551 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
1552
kono
parents:
diff changeset
1553 -- We have to handle the case when there might be more values in the
kono
parents:
diff changeset
1554 -- range of Index_Type than in the range of Count_Type.
kono
parents:
diff changeset
1555
kono
parents:
diff changeset
1556 if Index_Type'First <= 0 then
kono
parents:
diff changeset
1557
kono
parents:
diff changeset
1558 -- We know that No_Index (the same as Index_Type'First - 1) is
kono
parents:
diff changeset
1559 -- less than 0, so it is safe to compute the following sum without
kono
parents:
diff changeset
1560 -- fear of overflow.
kono
parents:
diff changeset
1561
kono
parents:
diff changeset
1562 Index := No_Index + Index_Type'Base (Count_Type'Last);
kono
parents:
diff changeset
1563
kono
parents:
diff changeset
1564 if Index <= Index_Type'Last then
kono
parents:
diff changeset
1565
kono
parents:
diff changeset
1566 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1567 -- many values as in Count_Type, so Count_Type'Last is the
kono
parents:
diff changeset
1568 -- maximum number of items that are allowed.
kono
parents:
diff changeset
1569
kono
parents:
diff changeset
1570 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1571
kono
parents:
diff changeset
1572 else
kono
parents:
diff changeset
1573 -- The range of Index_Type has fewer values than in Count_Type,
kono
parents:
diff changeset
1574 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1575 -- the Index_Type.
kono
parents:
diff changeset
1576
kono
parents:
diff changeset
1577 Max_Length := Count_Type'Base (Index_Type'Last - No_Index);
kono
parents:
diff changeset
1578 end if;
kono
parents:
diff changeset
1579
kono
parents:
diff changeset
1580 else
kono
parents:
diff changeset
1581 -- No_Index is equal or greater than 0, so we can safely compute
kono
parents:
diff changeset
1582 -- the difference without fear of overflow (which we would have to
kono
parents:
diff changeset
1583 -- worry about if No_Index were less than 0, but that case is
kono
parents:
diff changeset
1584 -- handled above).
kono
parents:
diff changeset
1585
kono
parents:
diff changeset
1586 if Index_Type'Last - No_Index >=
kono
parents:
diff changeset
1587 Count_Type'Pos (Count_Type'Last)
kono
parents:
diff changeset
1588 then
kono
parents:
diff changeset
1589 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1590 -- many values as in Count_Type, so Count_Type'Last is the
kono
parents:
diff changeset
1591 -- maximum number of items that are allowed.
kono
parents:
diff changeset
1592
kono
parents:
diff changeset
1593 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1594
kono
parents:
diff changeset
1595 else
kono
parents:
diff changeset
1596 -- The range of Index_Type has fewer values than in Count_Type,
kono
parents:
diff changeset
1597 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1598 -- the Index_Type.
kono
parents:
diff changeset
1599
kono
parents:
diff changeset
1600 Max_Length := Count_Type'Base (Index_Type'Last - No_Index);
kono
parents:
diff changeset
1601 end if;
kono
parents:
diff changeset
1602 end if;
kono
parents:
diff changeset
1603
kono
parents:
diff changeset
1604 elsif Index_Type'First <= 0 then
kono
parents:
diff changeset
1605
kono
parents:
diff changeset
1606 -- We know that No_Index (the same as Index_Type'First - 1) is less
kono
parents:
diff changeset
1607 -- than 0, so it is safe to compute the following sum without fear of
kono
parents:
diff changeset
1608 -- overflow.
kono
parents:
diff changeset
1609
kono
parents:
diff changeset
1610 J := Count_Type'Base (No_Index) + Count_Type'Last;
kono
parents:
diff changeset
1611
kono
parents:
diff changeset
1612 if J <= Count_Type'Base (Index_Type'Last) then
kono
parents:
diff changeset
1613
kono
parents:
diff changeset
1614 -- We have determined that range of Index_Type has at least as
kono
parents:
diff changeset
1615 -- many values as in Count_Type, so Count_Type'Last is the maximum
kono
parents:
diff changeset
1616 -- number of items that are allowed.
kono
parents:
diff changeset
1617
kono
parents:
diff changeset
1618 Max_Length := Count_Type'Last;
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 else
kono
parents:
diff changeset
1621 -- The range of Index_Type has fewer values than Count_Type does,
kono
parents:
diff changeset
1622 -- so the maximum number of items is computed from the range of
kono
parents:
diff changeset
1623 -- the Index_Type.
kono
parents:
diff changeset
1624
kono
parents:
diff changeset
1625 Max_Length :=
kono
parents:
diff changeset
1626 Count_Type'Base (Index_Type'Last) - Count_Type'Base (No_Index);
kono
parents:
diff changeset
1627 end if;
kono
parents:
diff changeset
1628
kono
parents:
diff changeset
1629 else
kono
parents:
diff changeset
1630 -- No_Index is equal or greater than 0, so we can safely compute the
kono
parents:
diff changeset
1631 -- difference without fear of overflow (which we would have to worry
kono
parents:
diff changeset
1632 -- about if No_Index were less than 0, but that case is handled
kono
parents:
diff changeset
1633 -- above).
kono
parents:
diff changeset
1634
kono
parents:
diff changeset
1635 Max_Length :=
kono
parents:
diff changeset
1636 Count_Type'Base (Index_Type'Last) - Count_Type'Base (No_Index);
kono
parents:
diff changeset
1637 end if;
kono
parents:
diff changeset
1638
kono
parents:
diff changeset
1639 -- We have just computed the maximum length (number of items). We must
kono
parents:
diff changeset
1640 -- now compare the requested length to the maximum length, as we do not
kono
parents:
diff changeset
1641 -- allow a vector expand beyond the maximum (because that would create
kono
parents:
diff changeset
1642 -- an internal array with a last index value greater than
kono
parents:
diff changeset
1643 -- Index_Type'Last, with no way to index those elements).
kono
parents:
diff changeset
1644
kono
parents:
diff changeset
1645 if Checks and then New_Length > Max_Length then
kono
parents:
diff changeset
1646 raise Constraint_Error with "Count is out of range";
kono
parents:
diff changeset
1647 end if;
kono
parents:
diff changeset
1648
kono
parents:
diff changeset
1649 -- The tampering bits exist to prevent an item from being harmfully
kono
parents:
diff changeset
1650 -- manipulated while it is being visited. Query, Update, and Iterate
kono
parents:
diff changeset
1651 -- increment the busy count on entry, and decrement the count on
kono
parents:
diff changeset
1652 -- exit. Insert checks the count to determine whether it is being called
kono
parents:
diff changeset
1653 -- while the associated callback procedure is executing.
kono
parents:
diff changeset
1654
kono
parents:
diff changeset
1655 TC_Check (Container.TC);
kono
parents:
diff changeset
1656
kono
parents:
diff changeset
1657 -- An internal array has already been allocated, so we need to check
kono
parents:
diff changeset
1658 -- whether there is enough unused storage for the new items.
kono
parents:
diff changeset
1659
kono
parents:
diff changeset
1660 if Checks and then New_Length > Container.Capacity then
kono
parents:
diff changeset
1661 raise Capacity_Error with "New length is larger than capacity";
kono
parents:
diff changeset
1662 end if;
kono
parents:
diff changeset
1663
kono
parents:
diff changeset
1664 -- In this case, we're inserting space into a vector that has already
kono
parents:
diff changeset
1665 -- allocated an internal array, and the existing array has enough
kono
parents:
diff changeset
1666 -- unused storage for the new items.
kono
parents:
diff changeset
1667
kono
parents:
diff changeset
1668 if Before <= Container.Last then
kono
parents:
diff changeset
1669
kono
parents:
diff changeset
1670 -- The space is being inserted before some existing elements,
kono
parents:
diff changeset
1671 -- so we must slide the existing elements up to their new home.
kono
parents:
diff changeset
1672
kono
parents:
diff changeset
1673 J := To_Array_Index (Before);
kono
parents:
diff changeset
1674 EA (J + Count .. New_Length) := EA (J .. Old_Length);
kono
parents:
diff changeset
1675 end if;
kono
parents:
diff changeset
1676
kono
parents:
diff changeset
1677 -- New_Last is the last index value of the items in the container after
kono
parents:
diff changeset
1678 -- insertion. Use the wider of Index_Type'Base and Count_Type'Base to
kono
parents:
diff changeset
1679 -- compute its value from the New_Length.
kono
parents:
diff changeset
1680
kono
parents:
diff changeset
1681 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
1682 Container.Last := No_Index + Index_Type'Base (New_Length);
kono
parents:
diff changeset
1683
kono
parents:
diff changeset
1684 else
kono
parents:
diff changeset
1685 Container.Last :=
kono
parents:
diff changeset
1686 Index_Type'Base (Count_Type'Base (No_Index) + New_Length);
kono
parents:
diff changeset
1687 end if;
kono
parents:
diff changeset
1688 end Insert_Space;
kono
parents:
diff changeset
1689
kono
parents:
diff changeset
1690 procedure Insert_Space
kono
parents:
diff changeset
1691 (Container : in out Vector;
kono
parents:
diff changeset
1692 Before : Cursor;
kono
parents:
diff changeset
1693 Position : out Cursor;
kono
parents:
diff changeset
1694 Count : Count_Type := 1)
kono
parents:
diff changeset
1695 is
kono
parents:
diff changeset
1696 Index : Index_Type'Base;
kono
parents:
diff changeset
1697
kono
parents:
diff changeset
1698 begin
kono
parents:
diff changeset
1699 if Checks and then Before.Container /= null
kono
parents:
diff changeset
1700 and then Before.Container /= Container'Unchecked_Access
kono
parents:
diff changeset
1701 then
kono
parents:
diff changeset
1702 raise Program_Error with "Before cursor denotes wrong container";
kono
parents:
diff changeset
1703 end if;
kono
parents:
diff changeset
1704
kono
parents:
diff changeset
1705 if Count = 0 then
kono
parents:
diff changeset
1706 if Before.Container = null
kono
parents:
diff changeset
1707 or else Before.Index > Container.Last
kono
parents:
diff changeset
1708 then
kono
parents:
diff changeset
1709 Position := No_Element;
kono
parents:
diff changeset
1710 else
kono
parents:
diff changeset
1711 Position := (Container'Unchecked_Access, Before.Index);
kono
parents:
diff changeset
1712 end if;
kono
parents:
diff changeset
1713
kono
parents:
diff changeset
1714 return;
kono
parents:
diff changeset
1715 end if;
kono
parents:
diff changeset
1716
kono
parents:
diff changeset
1717 if Before.Container = null
kono
parents:
diff changeset
1718 or else Before.Index > Container.Last
kono
parents:
diff changeset
1719 then
kono
parents:
diff changeset
1720 if Checks and then Container.Last = Index_Type'Last then
kono
parents:
diff changeset
1721 raise Constraint_Error with
kono
parents:
diff changeset
1722 "vector is already at its maximum length";
kono
parents:
diff changeset
1723 end if;
kono
parents:
diff changeset
1724
kono
parents:
diff changeset
1725 Index := Container.Last + 1;
kono
parents:
diff changeset
1726
kono
parents:
diff changeset
1727 else
kono
parents:
diff changeset
1728 Index := Before.Index;
kono
parents:
diff changeset
1729 end if;
kono
parents:
diff changeset
1730
kono
parents:
diff changeset
1731 Insert_Space (Container, Index, Count => Count);
kono
parents:
diff changeset
1732
kono
parents:
diff changeset
1733 Position := Cursor'(Container'Unchecked_Access, Index);
kono
parents:
diff changeset
1734 end Insert_Space;
kono
parents:
diff changeset
1735
kono
parents:
diff changeset
1736 --------------
kono
parents:
diff changeset
1737 -- Is_Empty --
kono
parents:
diff changeset
1738 --------------
kono
parents:
diff changeset
1739
kono
parents:
diff changeset
1740 function Is_Empty (Container : Vector) return Boolean is
kono
parents:
diff changeset
1741 begin
kono
parents:
diff changeset
1742 return Container.Last < Index_Type'First;
kono
parents:
diff changeset
1743 end Is_Empty;
kono
parents:
diff changeset
1744
kono
parents:
diff changeset
1745 -------------
kono
parents:
diff changeset
1746 -- Iterate --
kono
parents:
diff changeset
1747 -------------
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 procedure Iterate
kono
parents:
diff changeset
1750 (Container : Vector;
kono
parents:
diff changeset
1751 Process : not null access procedure (Position : Cursor))
kono
parents:
diff changeset
1752 is
kono
parents:
diff changeset
1753 Busy : With_Busy (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
1754 begin
kono
parents:
diff changeset
1755 for Indx in Index_Type'First .. Container.Last loop
kono
parents:
diff changeset
1756 Process (Cursor'(Container'Unrestricted_Access, Indx));
kono
parents:
diff changeset
1757 end loop;
kono
parents:
diff changeset
1758 end Iterate;
kono
parents:
diff changeset
1759
kono
parents:
diff changeset
1760 function Iterate
kono
parents:
diff changeset
1761 (Container : Vector)
kono
parents:
diff changeset
1762 return Vector_Iterator_Interfaces.Reversible_Iterator'Class
kono
parents:
diff changeset
1763 is
kono
parents:
diff changeset
1764 V : constant Vector_Access := Container'Unrestricted_Access;
kono
parents:
diff changeset
1765 begin
kono
parents:
diff changeset
1766 -- The value of its Index component influences the behavior of the First
kono
parents:
diff changeset
1767 -- and Last selector functions of the iterator object. When the Index
kono
parents:
diff changeset
1768 -- component is No_Index (as is the case here), this means the iterator
kono
parents:
diff changeset
1769 -- object was constructed without a start expression. This is a complete
kono
parents:
diff changeset
1770 -- iterator, meaning that the iteration starts from the (logical)
kono
parents:
diff changeset
1771 -- beginning of the sequence of items.
kono
parents:
diff changeset
1772
kono
parents:
diff changeset
1773 -- Note: For a forward iterator, Container.First is the beginning, and
kono
parents:
diff changeset
1774 -- for a reverse iterator, Container.Last is the beginning.
kono
parents:
diff changeset
1775
kono
parents:
diff changeset
1776 return It : constant Iterator :=
kono
parents:
diff changeset
1777 (Limited_Controlled with
kono
parents:
diff changeset
1778 Container => V,
kono
parents:
diff changeset
1779 Index => No_Index)
kono
parents:
diff changeset
1780 do
kono
parents:
diff changeset
1781 Busy (Container.TC'Unrestricted_Access.all);
kono
parents:
diff changeset
1782 end return;
kono
parents:
diff changeset
1783 end Iterate;
kono
parents:
diff changeset
1784
kono
parents:
diff changeset
1785 function Iterate
kono
parents:
diff changeset
1786 (Container : Vector;
kono
parents:
diff changeset
1787 Start : Cursor)
kono
parents:
diff changeset
1788 return Vector_Iterator_Interfaces.Reversible_Iterator'Class
kono
parents:
diff changeset
1789 is
kono
parents:
diff changeset
1790 V : constant Vector_Access := Container'Unrestricted_Access;
kono
parents:
diff changeset
1791 begin
kono
parents:
diff changeset
1792 -- It was formerly the case that when Start = No_Element, the partial
kono
parents:
diff changeset
1793 -- iterator was defined to behave the same as for a complete iterator,
kono
parents:
diff changeset
1794 -- and iterate over the entire sequence of items. However, those
kono
parents:
diff changeset
1795 -- semantics were unintuitive and arguably error-prone (it is too easy
kono
parents:
diff changeset
1796 -- to accidentally create an endless loop), and so they were changed,
kono
parents:
diff changeset
1797 -- per the ARG meeting in Denver on 2011/11. However, there was no
kono
parents:
diff changeset
1798 -- consensus about what positive meaning this corner case should have,
kono
parents:
diff changeset
1799 -- and so it was decided to simply raise an exception. This does imply,
kono
parents:
diff changeset
1800 -- however, that it is not possible to use a partial iterator to specify
kono
parents:
diff changeset
1801 -- an empty sequence of items.
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 if Checks and then Start.Container = null then
kono
parents:
diff changeset
1804 raise Constraint_Error with
kono
parents:
diff changeset
1805 "Start position for iterator equals No_Element";
kono
parents:
diff changeset
1806 end if;
kono
parents:
diff changeset
1807
kono
parents:
diff changeset
1808 if Checks and then Start.Container /= V then
kono
parents:
diff changeset
1809 raise Program_Error with
kono
parents:
diff changeset
1810 "Start cursor of Iterate designates wrong vector";
kono
parents:
diff changeset
1811 end if;
kono
parents:
diff changeset
1812
kono
parents:
diff changeset
1813 if Checks and then Start.Index > V.Last then
kono
parents:
diff changeset
1814 raise Constraint_Error with
kono
parents:
diff changeset
1815 "Start position for iterator equals No_Element";
kono
parents:
diff changeset
1816 end if;
kono
parents:
diff changeset
1817
kono
parents:
diff changeset
1818 -- The value of its Index component influences the behavior of the First
kono
parents:
diff changeset
1819 -- and Last selector functions of the iterator object. When the Index
kono
parents:
diff changeset
1820 -- component is not No_Index (as is the case here), it means that this
kono
parents:
diff changeset
1821 -- is a partial iteration, over a subset of the complete sequence of
kono
parents:
diff changeset
1822 -- items. The iterator object was constructed with a start expression,
kono
parents:
diff changeset
1823 -- indicating the position from which the iteration begins. Note that
kono
parents:
diff changeset
1824 -- the start position has the same value irrespective of whether this is
kono
parents:
diff changeset
1825 -- a forward or reverse iteration.
kono
parents:
diff changeset
1826
kono
parents:
diff changeset
1827 return It : constant Iterator :=
kono
parents:
diff changeset
1828 (Limited_Controlled with
kono
parents:
diff changeset
1829 Container => V,
kono
parents:
diff changeset
1830 Index => Start.Index)
kono
parents:
diff changeset
1831 do
kono
parents:
diff changeset
1832 Busy (Container.TC'Unrestricted_Access.all);
kono
parents:
diff changeset
1833 end return;
kono
parents:
diff changeset
1834 end Iterate;
kono
parents:
diff changeset
1835
kono
parents:
diff changeset
1836 ----------
kono
parents:
diff changeset
1837 -- Last --
kono
parents:
diff changeset
1838 ----------
kono
parents:
diff changeset
1839
kono
parents:
diff changeset
1840 function Last (Container : Vector) return Cursor is
kono
parents:
diff changeset
1841 begin
kono
parents:
diff changeset
1842 if Is_Empty (Container) then
kono
parents:
diff changeset
1843 return No_Element;
kono
parents:
diff changeset
1844 else
kono
parents:
diff changeset
1845 return (Container'Unrestricted_Access, Container.Last);
kono
parents:
diff changeset
1846 end if;
kono
parents:
diff changeset
1847 end Last;
kono
parents:
diff changeset
1848
kono
parents:
diff changeset
1849 function Last (Object : Iterator) return Cursor is
kono
parents:
diff changeset
1850 begin
kono
parents:
diff changeset
1851 -- The value of the iterator object's Index component influences the
kono
parents:
diff changeset
1852 -- behavior of the Last (and First) selector function.
kono
parents:
diff changeset
1853
kono
parents:
diff changeset
1854 -- When the Index component is No_Index, this means the iterator object
kono
parents:
diff changeset
1855 -- was constructed without a start expression, in which case the
kono
parents:
diff changeset
1856 -- (reverse) iteration starts from the (logical) beginning of the entire
kono
parents:
diff changeset
1857 -- sequence (corresponding to Container.Last, for a reverse iterator).
kono
parents:
diff changeset
1858
kono
parents:
diff changeset
1859 -- Otherwise, this is iteration over a partial sequence of items. When
kono
parents:
diff changeset
1860 -- the Index component is not No_Index, the iterator object was
kono
parents:
diff changeset
1861 -- constructed with a start expression, that specifies the position from
kono
parents:
diff changeset
1862 -- which the (reverse) partial iteration begins.
kono
parents:
diff changeset
1863
kono
parents:
diff changeset
1864 if Object.Index = No_Index then
kono
parents:
diff changeset
1865 return Last (Object.Container.all);
kono
parents:
diff changeset
1866 else
kono
parents:
diff changeset
1867 return Cursor'(Object.Container, Object.Index);
kono
parents:
diff changeset
1868 end if;
kono
parents:
diff changeset
1869 end Last;
kono
parents:
diff changeset
1870
kono
parents:
diff changeset
1871 ------------------
kono
parents:
diff changeset
1872 -- Last_Element --
kono
parents:
diff changeset
1873 ------------------
kono
parents:
diff changeset
1874
kono
parents:
diff changeset
1875 function Last_Element (Container : Vector) return Element_Type is
kono
parents:
diff changeset
1876 begin
kono
parents:
diff changeset
1877 if Checks and then Container.Last = No_Index then
kono
parents:
diff changeset
1878 raise Constraint_Error with "Container is empty";
kono
parents:
diff changeset
1879 end if;
kono
parents:
diff changeset
1880
kono
parents:
diff changeset
1881 return Container.Elements (Container.Length);
kono
parents:
diff changeset
1882 end Last_Element;
kono
parents:
diff changeset
1883
kono
parents:
diff changeset
1884 ----------------
kono
parents:
diff changeset
1885 -- Last_Index --
kono
parents:
diff changeset
1886 ----------------
kono
parents:
diff changeset
1887
kono
parents:
diff changeset
1888 function Last_Index (Container : Vector) return Extended_Index is
kono
parents:
diff changeset
1889 begin
kono
parents:
diff changeset
1890 return Container.Last;
kono
parents:
diff changeset
1891 end Last_Index;
kono
parents:
diff changeset
1892
kono
parents:
diff changeset
1893 ------------
kono
parents:
diff changeset
1894 -- Length --
kono
parents:
diff changeset
1895 ------------
kono
parents:
diff changeset
1896
kono
parents:
diff changeset
1897 function Length (Container : Vector) return Count_Type is
kono
parents:
diff changeset
1898 L : constant Index_Type'Base := Container.Last;
kono
parents:
diff changeset
1899 F : constant Index_Type := Index_Type'First;
kono
parents:
diff changeset
1900
kono
parents:
diff changeset
1901 begin
kono
parents:
diff changeset
1902 -- The base range of the index type (Index_Type'Base) might not include
kono
parents:
diff changeset
1903 -- all values for length (Count_Type). Contrariwise, the index type
kono
parents:
diff changeset
1904 -- might include values outside the range of length. Hence we use
kono
parents:
diff changeset
1905 -- whatever type is wider for intermediate values when calculating
kono
parents:
diff changeset
1906 -- length. Note that no matter what the index type is, the maximum
kono
parents:
diff changeset
1907 -- length to which a vector is allowed to grow is always the minimum
kono
parents:
diff changeset
1908 -- of Count_Type'Last and (IT'Last - IT'First + 1).
kono
parents:
diff changeset
1909
kono
parents:
diff changeset
1910 -- For example, an Index_Type with range -127 .. 127 is only guaranteed
kono
parents:
diff changeset
1911 -- to have a base range of -128 .. 127, but the corresponding vector
kono
parents:
diff changeset
1912 -- would have lengths in the range 0 .. 255. In this case we would need
kono
parents:
diff changeset
1913 -- to use Count_Type'Base for intermediate values.
kono
parents:
diff changeset
1914
kono
parents:
diff changeset
1915 -- Another case would be the index range -2**63 + 1 .. -2**63 + 10. The
kono
parents:
diff changeset
1916 -- vector would have a maximum length of 10, but the index values lie
kono
parents:
diff changeset
1917 -- outside the range of Count_Type (which is only 32 bits). In this
kono
parents:
diff changeset
1918 -- case we would need to use Index_Type'Base for intermediate values.
kono
parents:
diff changeset
1919
kono
parents:
diff changeset
1920 if Count_Type'Base'Last >= Index_Type'Pos (Index_Type'Base'Last) then
kono
parents:
diff changeset
1921 return Count_Type'Base (L) - Count_Type'Base (F) + 1;
kono
parents:
diff changeset
1922 else
kono
parents:
diff changeset
1923 return Count_Type (L - F + 1);
kono
parents:
diff changeset
1924 end if;
kono
parents:
diff changeset
1925 end Length;
kono
parents:
diff changeset
1926
kono
parents:
diff changeset
1927 ----------
kono
parents:
diff changeset
1928 -- Move --
kono
parents:
diff changeset
1929 ----------
kono
parents:
diff changeset
1930
kono
parents:
diff changeset
1931 procedure Move
kono
parents:
diff changeset
1932 (Target : in out Vector;
kono
parents:
diff changeset
1933 Source : in out Vector)
kono
parents:
diff changeset
1934 is
kono
parents:
diff changeset
1935 begin
kono
parents:
diff changeset
1936 if Target'Address = Source'Address then
kono
parents:
diff changeset
1937 return;
kono
parents:
diff changeset
1938 end if;
kono
parents:
diff changeset
1939
kono
parents:
diff changeset
1940 if Checks and then Target.Capacity < Source.Length then
kono
parents:
diff changeset
1941 raise Capacity_Error -- ???
kono
parents:
diff changeset
1942 with "Target capacity is less than Source length";
kono
parents:
diff changeset
1943 end if;
kono
parents:
diff changeset
1944
kono
parents:
diff changeset
1945 TC_Check (Target.TC);
kono
parents:
diff changeset
1946 TC_Check (Source.TC);
kono
parents:
diff changeset
1947
kono
parents:
diff changeset
1948 -- Clear Target now, in case element assignment fails
kono
parents:
diff changeset
1949
kono
parents:
diff changeset
1950 Target.Last := No_Index;
kono
parents:
diff changeset
1951
kono
parents:
diff changeset
1952 Target.Elements (1 .. Source.Length) :=
kono
parents:
diff changeset
1953 Source.Elements (1 .. Source.Length);
kono
parents:
diff changeset
1954
kono
parents:
diff changeset
1955 Target.Last := Source.Last;
kono
parents:
diff changeset
1956 Source.Last := No_Index;
kono
parents:
diff changeset
1957 end Move;
kono
parents:
diff changeset
1958
kono
parents:
diff changeset
1959 ----------
kono
parents:
diff changeset
1960 -- Next --
kono
parents:
diff changeset
1961 ----------
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 function Next (Position : Cursor) return Cursor is
kono
parents:
diff changeset
1964 begin
kono
parents:
diff changeset
1965 if Position.Container = null then
kono
parents:
diff changeset
1966 return No_Element;
kono
parents:
diff changeset
1967 elsif Position.Index < Position.Container.Last then
kono
parents:
diff changeset
1968 return (Position.Container, Position.Index + 1);
kono
parents:
diff changeset
1969 else
kono
parents:
diff changeset
1970 return No_Element;
kono
parents:
diff changeset
1971 end if;
kono
parents:
diff changeset
1972 end Next;
kono
parents:
diff changeset
1973
kono
parents:
diff changeset
1974 function Next (Object : Iterator; Position : Cursor) return Cursor is
kono
parents:
diff changeset
1975 begin
kono
parents:
diff changeset
1976 if Position.Container = null then
kono
parents:
diff changeset
1977 return No_Element;
kono
parents:
diff changeset
1978 end if;
kono
parents:
diff changeset
1979
kono
parents:
diff changeset
1980 if Checks and then Position.Container /= Object.Container then
kono
parents:
diff changeset
1981 raise Program_Error with
kono
parents:
diff changeset
1982 "Position cursor of Next designates wrong vector";
kono
parents:
diff changeset
1983 end if;
kono
parents:
diff changeset
1984
kono
parents:
diff changeset
1985 return Next (Position);
kono
parents:
diff changeset
1986 end Next;
kono
parents:
diff changeset
1987
kono
parents:
diff changeset
1988 procedure Next (Position : in out Cursor) is
kono
parents:
diff changeset
1989 begin
kono
parents:
diff changeset
1990 if Position.Container = null then
kono
parents:
diff changeset
1991 return;
kono
parents:
diff changeset
1992 elsif Position.Index < Position.Container.Last then
kono
parents:
diff changeset
1993 Position.Index := Position.Index + 1;
kono
parents:
diff changeset
1994 else
kono
parents:
diff changeset
1995 Position := No_Element;
kono
parents:
diff changeset
1996 end if;
kono
parents:
diff changeset
1997 end Next;
kono
parents:
diff changeset
1998
kono
parents:
diff changeset
1999 -------------
kono
parents:
diff changeset
2000 -- Prepend --
kono
parents:
diff changeset
2001 -------------
kono
parents:
diff changeset
2002
kono
parents:
diff changeset
2003 procedure Prepend (Container : in out Vector; New_Item : Vector) is
kono
parents:
diff changeset
2004 begin
kono
parents:
diff changeset
2005 Insert (Container, Index_Type'First, New_Item);
kono
parents:
diff changeset
2006 end Prepend;
kono
parents:
diff changeset
2007
kono
parents:
diff changeset
2008 procedure Prepend
kono
parents:
diff changeset
2009 (Container : in out Vector;
kono
parents:
diff changeset
2010 New_Item : Element_Type;
kono
parents:
diff changeset
2011 Count : Count_Type := 1)
kono
parents:
diff changeset
2012 is
kono
parents:
diff changeset
2013 begin
kono
parents:
diff changeset
2014 Insert (Container,
kono
parents:
diff changeset
2015 Index_Type'First,
kono
parents:
diff changeset
2016 New_Item,
kono
parents:
diff changeset
2017 Count);
kono
parents:
diff changeset
2018 end Prepend;
kono
parents:
diff changeset
2019
kono
parents:
diff changeset
2020 --------------
kono
parents:
diff changeset
2021 -- Previous --
kono
parents:
diff changeset
2022 --------------
kono
parents:
diff changeset
2023
kono
parents:
diff changeset
2024 procedure Previous (Position : in out Cursor) is
kono
parents:
diff changeset
2025 begin
kono
parents:
diff changeset
2026 if Position.Container = null then
kono
parents:
diff changeset
2027 return;
kono
parents:
diff changeset
2028 elsif Position.Index > Index_Type'First then
kono
parents:
diff changeset
2029 Position.Index := Position.Index - 1;
kono
parents:
diff changeset
2030 else
kono
parents:
diff changeset
2031 Position := No_Element;
kono
parents:
diff changeset
2032 end if;
kono
parents:
diff changeset
2033 end Previous;
kono
parents:
diff changeset
2034
kono
parents:
diff changeset
2035 function Previous (Position : Cursor) return Cursor is
kono
parents:
diff changeset
2036 begin
kono
parents:
diff changeset
2037 if Position.Container = null then
kono
parents:
diff changeset
2038 return No_Element;
kono
parents:
diff changeset
2039 elsif Position.Index > Index_Type'First then
kono
parents:
diff changeset
2040 return (Position.Container, Position.Index - 1);
kono
parents:
diff changeset
2041 else
kono
parents:
diff changeset
2042 return No_Element;
kono
parents:
diff changeset
2043 end if;
kono
parents:
diff changeset
2044 end Previous;
kono
parents:
diff changeset
2045
kono
parents:
diff changeset
2046 function Previous (Object : Iterator; Position : Cursor) return Cursor is
kono
parents:
diff changeset
2047 begin
kono
parents:
diff changeset
2048 if Position.Container = null then
kono
parents:
diff changeset
2049 return No_Element;
kono
parents:
diff changeset
2050 end if;
kono
parents:
diff changeset
2051
kono
parents:
diff changeset
2052 if Checks and then Position.Container /= Object.Container then
kono
parents:
diff changeset
2053 raise Program_Error with
kono
parents:
diff changeset
2054 "Position cursor of Previous designates wrong vector";
kono
parents:
diff changeset
2055 end if;
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 return Previous (Position);
kono
parents:
diff changeset
2058 end Previous;
kono
parents:
diff changeset
2059
kono
parents:
diff changeset
2060 ----------------------
kono
parents:
diff changeset
2061 -- Pseudo_Reference --
kono
parents:
diff changeset
2062 ----------------------
kono
parents:
diff changeset
2063
kono
parents:
diff changeset
2064 function Pseudo_Reference
kono
parents:
diff changeset
2065 (Container : aliased Vector'Class) return Reference_Control_Type
kono
parents:
diff changeset
2066 is
kono
parents:
diff changeset
2067 TC : constant Tamper_Counts_Access := Container.TC'Unrestricted_Access;
kono
parents:
diff changeset
2068 begin
kono
parents:
diff changeset
2069 return R : constant Reference_Control_Type := (Controlled with TC) do
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2070 Busy (TC.all);
111
kono
parents:
diff changeset
2071 end return;
kono
parents:
diff changeset
2072 end Pseudo_Reference;
kono
parents:
diff changeset
2073
kono
parents:
diff changeset
2074 -------------------
kono
parents:
diff changeset
2075 -- Query_Element --
kono
parents:
diff changeset
2076 -------------------
kono
parents:
diff changeset
2077
kono
parents:
diff changeset
2078 procedure Query_Element
kono
parents:
diff changeset
2079 (Container : Vector;
kono
parents:
diff changeset
2080 Index : Index_Type;
kono
parents:
diff changeset
2081 Process : not null access procedure (Element : Element_Type))
kono
parents:
diff changeset
2082 is
kono
parents:
diff changeset
2083 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
2084 V : Vector renames Container'Unrestricted_Access.all;
kono
parents:
diff changeset
2085 begin
kono
parents:
diff changeset
2086 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
2087 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
2088 end if;
kono
parents:
diff changeset
2089
kono
parents:
diff changeset
2090 Process (V.Elements (To_Array_Index (Index)));
kono
parents:
diff changeset
2091 end Query_Element;
kono
parents:
diff changeset
2092
kono
parents:
diff changeset
2093 procedure Query_Element
kono
parents:
diff changeset
2094 (Position : Cursor;
kono
parents:
diff changeset
2095 Process : not null access procedure (Element : Element_Type))
kono
parents:
diff changeset
2096 is
kono
parents:
diff changeset
2097 begin
kono
parents:
diff changeset
2098 if Checks and then Position.Container = null then
kono
parents:
diff changeset
2099 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
2100 end if;
kono
parents:
diff changeset
2101
kono
parents:
diff changeset
2102 Query_Element (Position.Container.all, Position.Index, Process);
kono
parents:
diff changeset
2103 end Query_Element;
kono
parents:
diff changeset
2104
kono
parents:
diff changeset
2105 ----------
kono
parents:
diff changeset
2106 -- Read --
kono
parents:
diff changeset
2107 ----------
kono
parents:
diff changeset
2108
kono
parents:
diff changeset
2109 procedure Read
kono
parents:
diff changeset
2110 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2111 Container : out Vector)
kono
parents:
diff changeset
2112 is
kono
parents:
diff changeset
2113 Length : Count_Type'Base;
kono
parents:
diff changeset
2114 Last : Index_Type'Base := No_Index;
kono
parents:
diff changeset
2115
kono
parents:
diff changeset
2116 begin
kono
parents:
diff changeset
2117 Clear (Container);
kono
parents:
diff changeset
2118
kono
parents:
diff changeset
2119 Count_Type'Base'Read (Stream, Length);
kono
parents:
diff changeset
2120
kono
parents:
diff changeset
2121 Reserve_Capacity (Container, Capacity => Length);
kono
parents:
diff changeset
2122
kono
parents:
diff changeset
2123 for Idx in Count_Type range 1 .. Length loop
kono
parents:
diff changeset
2124 Last := Last + 1;
kono
parents:
diff changeset
2125 Element_Type'Read (Stream, Container.Elements (Idx));
kono
parents:
diff changeset
2126 Container.Last := Last;
kono
parents:
diff changeset
2127 end loop;
kono
parents:
diff changeset
2128 end Read;
kono
parents:
diff changeset
2129
kono
parents:
diff changeset
2130 procedure Read
kono
parents:
diff changeset
2131 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2132 Position : out Cursor)
kono
parents:
diff changeset
2133 is
kono
parents:
diff changeset
2134 begin
kono
parents:
diff changeset
2135 raise Program_Error with "attempt to stream vector cursor";
kono
parents:
diff changeset
2136 end Read;
kono
parents:
diff changeset
2137
kono
parents:
diff changeset
2138 procedure Read
kono
parents:
diff changeset
2139 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2140 Item : out Reference_Type)
kono
parents:
diff changeset
2141 is
kono
parents:
diff changeset
2142 begin
kono
parents:
diff changeset
2143 raise Program_Error with "attempt to stream reference";
kono
parents:
diff changeset
2144 end Read;
kono
parents:
diff changeset
2145
kono
parents:
diff changeset
2146 procedure Read
kono
parents:
diff changeset
2147 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2148 Item : out Constant_Reference_Type)
kono
parents:
diff changeset
2149 is
kono
parents:
diff changeset
2150 begin
kono
parents:
diff changeset
2151 raise Program_Error with "attempt to stream reference";
kono
parents:
diff changeset
2152 end Read;
kono
parents:
diff changeset
2153
kono
parents:
diff changeset
2154 ---------------
kono
parents:
diff changeset
2155 -- Reference --
kono
parents:
diff changeset
2156 ---------------
kono
parents:
diff changeset
2157
kono
parents:
diff changeset
2158 function Reference
kono
parents:
diff changeset
2159 (Container : aliased in out Vector;
kono
parents:
diff changeset
2160 Position : Cursor) return Reference_Type
kono
parents:
diff changeset
2161 is
kono
parents:
diff changeset
2162 begin
kono
parents:
diff changeset
2163 if Checks and then Position.Container = null then
kono
parents:
diff changeset
2164 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
2165 end if;
kono
parents:
diff changeset
2166
kono
parents:
diff changeset
2167 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
2168 then
kono
parents:
diff changeset
2169 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
2170 end if;
kono
parents:
diff changeset
2171
kono
parents:
diff changeset
2172 if Checks and then Position.Index > Position.Container.Last then
kono
parents:
diff changeset
2173 raise Constraint_Error with "Position cursor is out of range";
kono
parents:
diff changeset
2174 end if;
kono
parents:
diff changeset
2175
kono
parents:
diff changeset
2176 declare
kono
parents:
diff changeset
2177 A : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
2178 J : constant Count_Type := To_Array_Index (Position.Index);
kono
parents:
diff changeset
2179 TC : constant Tamper_Counts_Access :=
kono
parents:
diff changeset
2180 Container.TC'Unrestricted_Access;
kono
parents:
diff changeset
2181 begin
kono
parents:
diff changeset
2182 return R : constant Reference_Type :=
kono
parents:
diff changeset
2183 (Element => A (J)'Access,
kono
parents:
diff changeset
2184 Control => (Controlled with TC))
kono
parents:
diff changeset
2185 do
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2186 Busy (TC.all);
111
kono
parents:
diff changeset
2187 end return;
kono
parents:
diff changeset
2188 end;
kono
parents:
diff changeset
2189 end Reference;
kono
parents:
diff changeset
2190
kono
parents:
diff changeset
2191 function Reference
kono
parents:
diff changeset
2192 (Container : aliased in out Vector;
kono
parents:
diff changeset
2193 Index : Index_Type) return Reference_Type
kono
parents:
diff changeset
2194 is
kono
parents:
diff changeset
2195 begin
kono
parents:
diff changeset
2196 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
2197 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
2198 end if;
kono
parents:
diff changeset
2199
kono
parents:
diff changeset
2200 declare
kono
parents:
diff changeset
2201 A : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
2202 J : constant Count_Type := To_Array_Index (Index);
kono
parents:
diff changeset
2203 TC : constant Tamper_Counts_Access :=
kono
parents:
diff changeset
2204 Container.TC'Unrestricted_Access;
kono
parents:
diff changeset
2205 begin
kono
parents:
diff changeset
2206 return R : constant Reference_Type :=
kono
parents:
diff changeset
2207 (Element => A (J)'Access,
kono
parents:
diff changeset
2208 Control => (Controlled with TC))
kono
parents:
diff changeset
2209 do
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2210 Busy (TC.all);
111
kono
parents:
diff changeset
2211 end return;
kono
parents:
diff changeset
2212 end;
kono
parents:
diff changeset
2213 end Reference;
kono
parents:
diff changeset
2214
kono
parents:
diff changeset
2215 ---------------------
kono
parents:
diff changeset
2216 -- Replace_Element --
kono
parents:
diff changeset
2217 ---------------------
kono
parents:
diff changeset
2218
kono
parents:
diff changeset
2219 procedure Replace_Element
kono
parents:
diff changeset
2220 (Container : in out Vector;
kono
parents:
diff changeset
2221 Index : Index_Type;
kono
parents:
diff changeset
2222 New_Item : Element_Type)
kono
parents:
diff changeset
2223 is
kono
parents:
diff changeset
2224 begin
kono
parents:
diff changeset
2225 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
2226 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
2227 end if;
kono
parents:
diff changeset
2228
kono
parents:
diff changeset
2229 TE_Check (Container.TC);
kono
parents:
diff changeset
2230
kono
parents:
diff changeset
2231 Container.Elements (To_Array_Index (Index)) := New_Item;
kono
parents:
diff changeset
2232 end Replace_Element;
kono
parents:
diff changeset
2233
kono
parents:
diff changeset
2234 procedure Replace_Element
kono
parents:
diff changeset
2235 (Container : in out Vector;
kono
parents:
diff changeset
2236 Position : Cursor;
kono
parents:
diff changeset
2237 New_Item : Element_Type)
kono
parents:
diff changeset
2238 is
kono
parents:
diff changeset
2239 begin
kono
parents:
diff changeset
2240 if Checks and then Position.Container = null then
kono
parents:
diff changeset
2241 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
2242 end if;
kono
parents:
diff changeset
2243
kono
parents:
diff changeset
2244 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
2245 then
kono
parents:
diff changeset
2246 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
2247 end if;
kono
parents:
diff changeset
2248
kono
parents:
diff changeset
2249 if Checks and then Position.Index > Container.Last then
kono
parents:
diff changeset
2250 raise Constraint_Error with "Position cursor is out of range";
kono
parents:
diff changeset
2251 end if;
kono
parents:
diff changeset
2252
kono
parents:
diff changeset
2253 TE_Check (Container.TC);
kono
parents:
diff changeset
2254
kono
parents:
diff changeset
2255 Container.Elements (To_Array_Index (Position.Index)) := New_Item;
kono
parents:
diff changeset
2256 end Replace_Element;
kono
parents:
diff changeset
2257
kono
parents:
diff changeset
2258 ----------------------
kono
parents:
diff changeset
2259 -- Reserve_Capacity --
kono
parents:
diff changeset
2260 ----------------------
kono
parents:
diff changeset
2261
kono
parents:
diff changeset
2262 procedure Reserve_Capacity
kono
parents:
diff changeset
2263 (Container : in out Vector;
kono
parents:
diff changeset
2264 Capacity : Count_Type)
kono
parents:
diff changeset
2265 is
kono
parents:
diff changeset
2266 begin
kono
parents:
diff changeset
2267 if Checks and then Capacity > Container.Capacity then
kono
parents:
diff changeset
2268 raise Capacity_Error with "Capacity is out of range";
kono
parents:
diff changeset
2269 end if;
kono
parents:
diff changeset
2270 end Reserve_Capacity;
kono
parents:
diff changeset
2271
kono
parents:
diff changeset
2272 ----------------------
kono
parents:
diff changeset
2273 -- Reverse_Elements --
kono
parents:
diff changeset
2274 ----------------------
kono
parents:
diff changeset
2275
kono
parents:
diff changeset
2276 procedure Reverse_Elements (Container : in out Vector) is
kono
parents:
diff changeset
2277 E : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
2278 Idx : Count_Type;
kono
parents:
diff changeset
2279 Jdx : Count_Type;
kono
parents:
diff changeset
2280
kono
parents:
diff changeset
2281 begin
kono
parents:
diff changeset
2282 if Container.Length <= 1 then
kono
parents:
diff changeset
2283 return;
kono
parents:
diff changeset
2284 end if;
kono
parents:
diff changeset
2285
kono
parents:
diff changeset
2286 -- The exception behavior for the vector container must match that for
kono
parents:
diff changeset
2287 -- the list container, so we check for cursor tampering here (which will
kono
parents:
diff changeset
2288 -- catch more things) instead of for element tampering (which will catch
kono
parents:
diff changeset
2289 -- fewer things). It's true that the elements of this vector container
kono
parents:
diff changeset
2290 -- could be safely moved around while (say) an iteration is taking place
kono
parents:
diff changeset
2291 -- (iteration only increments the busy counter), and so technically
kono
parents:
diff changeset
2292 -- all we would need here is a test for element tampering (indicated
kono
parents:
diff changeset
2293 -- by the lock counter), that's simply an artifact of our array-based
kono
parents:
diff changeset
2294 -- implementation. Logically Reverse_Elements requires a check for
kono
parents:
diff changeset
2295 -- cursor tampering.
kono
parents:
diff changeset
2296
kono
parents:
diff changeset
2297 TC_Check (Container.TC);
kono
parents:
diff changeset
2298
kono
parents:
diff changeset
2299 Idx := 1;
kono
parents:
diff changeset
2300 Jdx := Container.Length;
kono
parents:
diff changeset
2301 while Idx < Jdx loop
kono
parents:
diff changeset
2302 declare
kono
parents:
diff changeset
2303 EI : constant Element_Type := E (Idx);
kono
parents:
diff changeset
2304
kono
parents:
diff changeset
2305 begin
kono
parents:
diff changeset
2306 E (Idx) := E (Jdx);
kono
parents:
diff changeset
2307 E (Jdx) := EI;
kono
parents:
diff changeset
2308 end;
kono
parents:
diff changeset
2309
kono
parents:
diff changeset
2310 Idx := Idx + 1;
kono
parents:
diff changeset
2311 Jdx := Jdx - 1;
kono
parents:
diff changeset
2312 end loop;
kono
parents:
diff changeset
2313 end Reverse_Elements;
kono
parents:
diff changeset
2314
kono
parents:
diff changeset
2315 ------------------
kono
parents:
diff changeset
2316 -- Reverse_Find --
kono
parents:
diff changeset
2317 ------------------
kono
parents:
diff changeset
2318
kono
parents:
diff changeset
2319 function Reverse_Find
kono
parents:
diff changeset
2320 (Container : Vector;
kono
parents:
diff changeset
2321 Item : Element_Type;
kono
parents:
diff changeset
2322 Position : Cursor := No_Element) return Cursor
kono
parents:
diff changeset
2323 is
kono
parents:
diff changeset
2324 Last : Index_Type'Base;
kono
parents:
diff changeset
2325
kono
parents:
diff changeset
2326 begin
kono
parents:
diff changeset
2327 if Checks and then Position.Container /= null
kono
parents:
diff changeset
2328 and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
2329 then
kono
parents:
diff changeset
2330 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
2331 end if;
kono
parents:
diff changeset
2332
kono
parents:
diff changeset
2333 Last :=
kono
parents:
diff changeset
2334 (if Position.Container = null or else Position.Index > Container.Last
kono
parents:
diff changeset
2335 then Container.Last
kono
parents:
diff changeset
2336 else Position.Index);
kono
parents:
diff changeset
2337
kono
parents:
diff changeset
2338 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
2339 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
2340
kono
parents:
diff changeset
2341 declare
kono
parents:
diff changeset
2342 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
2343 begin
kono
parents:
diff changeset
2344 for Indx in reverse Index_Type'First .. Last loop
kono
parents:
diff changeset
2345 if Container.Elements (To_Array_Index (Indx)) = Item then
kono
parents:
diff changeset
2346 return Cursor'(Container'Unrestricted_Access, Indx);
kono
parents:
diff changeset
2347 end if;
kono
parents:
diff changeset
2348 end loop;
kono
parents:
diff changeset
2349
kono
parents:
diff changeset
2350 return No_Element;
kono
parents:
diff changeset
2351 end;
kono
parents:
diff changeset
2352 end Reverse_Find;
kono
parents:
diff changeset
2353
kono
parents:
diff changeset
2354 ------------------------
kono
parents:
diff changeset
2355 -- Reverse_Find_Index --
kono
parents:
diff changeset
2356 ------------------------
kono
parents:
diff changeset
2357
kono
parents:
diff changeset
2358 function Reverse_Find_Index
kono
parents:
diff changeset
2359 (Container : Vector;
kono
parents:
diff changeset
2360 Item : Element_Type;
kono
parents:
diff changeset
2361 Index : Index_Type := Index_Type'Last) return Extended_Index
kono
parents:
diff changeset
2362 is
kono
parents:
diff changeset
2363 -- Per AI05-0022, the container implementation is required to detect
kono
parents:
diff changeset
2364 -- element tampering by a generic actual subprogram.
kono
parents:
diff changeset
2365
kono
parents:
diff changeset
2366 Lock : With_Lock (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
2367
kono
parents:
diff changeset
2368 Last : constant Index_Type'Base :=
kono
parents:
diff changeset
2369 Index_Type'Min (Container.Last, Index);
kono
parents:
diff changeset
2370
kono
parents:
diff changeset
2371 begin
kono
parents:
diff changeset
2372 for Indx in reverse Index_Type'First .. Last loop
kono
parents:
diff changeset
2373 if Container.Elements (To_Array_Index (Indx)) = Item then
kono
parents:
diff changeset
2374 return Indx;
kono
parents:
diff changeset
2375 end if;
kono
parents:
diff changeset
2376 end loop;
kono
parents:
diff changeset
2377
kono
parents:
diff changeset
2378 return No_Index;
kono
parents:
diff changeset
2379 end Reverse_Find_Index;
kono
parents:
diff changeset
2380
kono
parents:
diff changeset
2381 ---------------------
kono
parents:
diff changeset
2382 -- Reverse_Iterate --
kono
parents:
diff changeset
2383 ---------------------
kono
parents:
diff changeset
2384
kono
parents:
diff changeset
2385 procedure Reverse_Iterate
kono
parents:
diff changeset
2386 (Container : Vector;
kono
parents:
diff changeset
2387 Process : not null access procedure (Position : Cursor))
kono
parents:
diff changeset
2388 is
kono
parents:
diff changeset
2389 Busy : With_Busy (Container.TC'Unrestricted_Access);
kono
parents:
diff changeset
2390 begin
kono
parents:
diff changeset
2391 for Indx in reverse Index_Type'First .. Container.Last loop
kono
parents:
diff changeset
2392 Process (Cursor'(Container'Unrestricted_Access, Indx));
kono
parents:
diff changeset
2393 end loop;
kono
parents:
diff changeset
2394 end Reverse_Iterate;
kono
parents:
diff changeset
2395
kono
parents:
diff changeset
2396 ----------------
kono
parents:
diff changeset
2397 -- Set_Length --
kono
parents:
diff changeset
2398 ----------------
kono
parents:
diff changeset
2399
kono
parents:
diff changeset
2400 procedure Set_Length (Container : in out Vector; Length : Count_Type) is
kono
parents:
diff changeset
2401 Count : constant Count_Type'Base := Container.Length - Length;
kono
parents:
diff changeset
2402
kono
parents:
diff changeset
2403 begin
kono
parents:
diff changeset
2404 -- Set_Length allows the user to set the length explicitly, instead of
kono
parents:
diff changeset
2405 -- implicitly as a side-effect of deletion or insertion. If the
kono
parents:
diff changeset
2406 -- requested length is less than the current length, this is equivalent
kono
parents:
diff changeset
2407 -- to deleting items from the back end of the vector. If the requested
kono
parents:
diff changeset
2408 -- length is greater than the current length, then this is equivalent to
kono
parents:
diff changeset
2409 -- inserting "space" (nonce items) at the end.
kono
parents:
diff changeset
2410
kono
parents:
diff changeset
2411 if Count >= 0 then
kono
parents:
diff changeset
2412 Container.Delete_Last (Count);
kono
parents:
diff changeset
2413 elsif Checks and then Container.Last >= Index_Type'Last then
kono
parents:
diff changeset
2414 raise Constraint_Error with "vector is already at its maximum length";
kono
parents:
diff changeset
2415 else
kono
parents:
diff changeset
2416 Container.Insert_Space (Container.Last + 1, -Count);
kono
parents:
diff changeset
2417 end if;
kono
parents:
diff changeset
2418 end Set_Length;
kono
parents:
diff changeset
2419
kono
parents:
diff changeset
2420 ----------
kono
parents:
diff changeset
2421 -- Swap --
kono
parents:
diff changeset
2422 ----------
kono
parents:
diff changeset
2423
kono
parents:
diff changeset
2424 procedure Swap (Container : in out Vector; I, J : Index_Type) is
kono
parents:
diff changeset
2425 E : Elements_Array renames Container.Elements;
kono
parents:
diff changeset
2426
kono
parents:
diff changeset
2427 begin
kono
parents:
diff changeset
2428 if Checks and then I > Container.Last then
kono
parents:
diff changeset
2429 raise Constraint_Error with "I index is out of range";
kono
parents:
diff changeset
2430 end if;
kono
parents:
diff changeset
2431
kono
parents:
diff changeset
2432 if Checks and then J > Container.Last then
kono
parents:
diff changeset
2433 raise Constraint_Error with "J index is out of range";
kono
parents:
diff changeset
2434 end if;
kono
parents:
diff changeset
2435
kono
parents:
diff changeset
2436 if I = J then
kono
parents:
diff changeset
2437 return;
kono
parents:
diff changeset
2438 end if;
kono
parents:
diff changeset
2439
kono
parents:
diff changeset
2440 TE_Check (Container.TC);
kono
parents:
diff changeset
2441
kono
parents:
diff changeset
2442 declare
kono
parents:
diff changeset
2443 EI_Copy : constant Element_Type := E (To_Array_Index (I));
kono
parents:
diff changeset
2444 begin
kono
parents:
diff changeset
2445 E (To_Array_Index (I)) := E (To_Array_Index (J));
kono
parents:
diff changeset
2446 E (To_Array_Index (J)) := EI_Copy;
kono
parents:
diff changeset
2447 end;
kono
parents:
diff changeset
2448 end Swap;
kono
parents:
diff changeset
2449
kono
parents:
diff changeset
2450 procedure Swap (Container : in out Vector; I, J : Cursor) is
kono
parents:
diff changeset
2451 begin
kono
parents:
diff changeset
2452 if Checks and then I.Container = null then
kono
parents:
diff changeset
2453 raise Constraint_Error with "I cursor has no element";
kono
parents:
diff changeset
2454 end if;
kono
parents:
diff changeset
2455
kono
parents:
diff changeset
2456 if Checks and then J.Container = null then
kono
parents:
diff changeset
2457 raise Constraint_Error with "J cursor has no element";
kono
parents:
diff changeset
2458 end if;
kono
parents:
diff changeset
2459
kono
parents:
diff changeset
2460 if Checks and then I.Container /= Container'Unrestricted_Access then
kono
parents:
diff changeset
2461 raise Program_Error with "I cursor denotes wrong container";
kono
parents:
diff changeset
2462 end if;
kono
parents:
diff changeset
2463
kono
parents:
diff changeset
2464 if Checks and then J.Container /= Container'Unrestricted_Access then
kono
parents:
diff changeset
2465 raise Program_Error with "J cursor denotes wrong container";
kono
parents:
diff changeset
2466 end if;
kono
parents:
diff changeset
2467
kono
parents:
diff changeset
2468 Swap (Container, I.Index, J.Index);
kono
parents:
diff changeset
2469 end Swap;
kono
parents:
diff changeset
2470
kono
parents:
diff changeset
2471 --------------------
kono
parents:
diff changeset
2472 -- To_Array_Index --
kono
parents:
diff changeset
2473 --------------------
kono
parents:
diff changeset
2474
kono
parents:
diff changeset
2475 function To_Array_Index (Index : Index_Type'Base) return Count_Type'Base is
kono
parents:
diff changeset
2476 Offset : Count_Type'Base;
kono
parents:
diff changeset
2477
kono
parents:
diff changeset
2478 begin
kono
parents:
diff changeset
2479 -- We know that
kono
parents:
diff changeset
2480 -- Index >= Index_Type'First
kono
parents:
diff changeset
2481 -- hence we also know that
kono
parents:
diff changeset
2482 -- Index - Index_Type'First >= 0
kono
parents:
diff changeset
2483
kono
parents:
diff changeset
2484 -- The issue is that even though 0 is guaranteed to be a value in
kono
parents:
diff changeset
2485 -- the type Index_Type'Base, there's no guarantee that the difference
kono
parents:
diff changeset
2486 -- is a value in that type. To prevent overflow we use the wider
kono
parents:
diff changeset
2487 -- of Count_Type'Base and Index_Type'Base to perform intermediate
kono
parents:
diff changeset
2488 -- calculations.
kono
parents:
diff changeset
2489
kono
parents:
diff changeset
2490 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
2491 Offset := Count_Type'Base (Index - Index_Type'First);
kono
parents:
diff changeset
2492
kono
parents:
diff changeset
2493 else
kono
parents:
diff changeset
2494 Offset := Count_Type'Base (Index) -
kono
parents:
diff changeset
2495 Count_Type'Base (Index_Type'First);
kono
parents:
diff changeset
2496 end if;
kono
parents:
diff changeset
2497
kono
parents:
diff changeset
2498 -- The array index subtype for all container element arrays
kono
parents:
diff changeset
2499 -- always starts with 1.
kono
parents:
diff changeset
2500
kono
parents:
diff changeset
2501 return 1 + Offset;
kono
parents:
diff changeset
2502 end To_Array_Index;
kono
parents:
diff changeset
2503
kono
parents:
diff changeset
2504 ---------------
kono
parents:
diff changeset
2505 -- To_Cursor --
kono
parents:
diff changeset
2506 ---------------
kono
parents:
diff changeset
2507
kono
parents:
diff changeset
2508 function To_Cursor
kono
parents:
diff changeset
2509 (Container : Vector;
kono
parents:
diff changeset
2510 Index : Extended_Index) return Cursor
kono
parents:
diff changeset
2511 is
kono
parents:
diff changeset
2512 begin
kono
parents:
diff changeset
2513 if Index not in Index_Type'First .. Container.Last then
kono
parents:
diff changeset
2514 return No_Element;
kono
parents:
diff changeset
2515 end if;
kono
parents:
diff changeset
2516
kono
parents:
diff changeset
2517 return Cursor'(Container'Unrestricted_Access, Index);
kono
parents:
diff changeset
2518 end To_Cursor;
kono
parents:
diff changeset
2519
kono
parents:
diff changeset
2520 --------------
kono
parents:
diff changeset
2521 -- To_Index --
kono
parents:
diff changeset
2522 --------------
kono
parents:
diff changeset
2523
kono
parents:
diff changeset
2524 function To_Index (Position : Cursor) return Extended_Index is
kono
parents:
diff changeset
2525 begin
kono
parents:
diff changeset
2526 if Position.Container = null then
kono
parents:
diff changeset
2527 return No_Index;
kono
parents:
diff changeset
2528 end if;
kono
parents:
diff changeset
2529
kono
parents:
diff changeset
2530 if Position.Index <= Position.Container.Last then
kono
parents:
diff changeset
2531 return Position.Index;
kono
parents:
diff changeset
2532 end if;
kono
parents:
diff changeset
2533
kono
parents:
diff changeset
2534 return No_Index;
kono
parents:
diff changeset
2535 end To_Index;
kono
parents:
diff changeset
2536
kono
parents:
diff changeset
2537 ---------------
kono
parents:
diff changeset
2538 -- To_Vector --
kono
parents:
diff changeset
2539 ---------------
kono
parents:
diff changeset
2540
kono
parents:
diff changeset
2541 function To_Vector (Length : Count_Type) return Vector is
kono
parents:
diff changeset
2542 Index : Count_Type'Base;
kono
parents:
diff changeset
2543 Last : Index_Type'Base;
kono
parents:
diff changeset
2544
kono
parents:
diff changeset
2545 begin
kono
parents:
diff changeset
2546 if Length = 0 then
kono
parents:
diff changeset
2547 return Empty_Vector;
kono
parents:
diff changeset
2548 end if;
kono
parents:
diff changeset
2549
kono
parents:
diff changeset
2550 -- We create a vector object with a capacity that matches the specified
kono
parents:
diff changeset
2551 -- Length, but we do not allow the vector capacity (the length of the
kono
parents:
diff changeset
2552 -- internal array) to exceed the number of values in Index_Type'Range
kono
parents:
diff changeset
2553 -- (otherwise, there would be no way to refer to those components via an
kono
parents:
diff changeset
2554 -- index). We must therefore check whether the specified Length would
kono
parents:
diff changeset
2555 -- create a Last index value greater than Index_Type'Last.
kono
parents:
diff changeset
2556
kono
parents:
diff changeset
2557 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
2558 -- We perform a two-part test. First we determine whether the
kono
parents:
diff changeset
2559 -- computed Last value lies in the base range of the type, and then
kono
parents:
diff changeset
2560 -- determine whether it lies in the range of the index (sub)type.
kono
parents:
diff changeset
2561
kono
parents:
diff changeset
2562 -- Last must satisfy this relation:
kono
parents:
diff changeset
2563 -- First + Length - 1 <= Last
kono
parents:
diff changeset
2564 -- We regroup terms:
kono
parents:
diff changeset
2565 -- First - 1 <= Last - Length
kono
parents:
diff changeset
2566 -- Which can rewrite as:
kono
parents:
diff changeset
2567 -- No_Index <= Last - Length
kono
parents:
diff changeset
2568
kono
parents:
diff changeset
2569 if Checks and then
kono
parents:
diff changeset
2570 Index_Type'Base'Last - Index_Type'Base (Length) < No_Index
kono
parents:
diff changeset
2571 then
kono
parents:
diff changeset
2572 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2573 end if;
kono
parents:
diff changeset
2574
kono
parents:
diff changeset
2575 -- We now know that the computed value of Last is within the base
kono
parents:
diff changeset
2576 -- range of the type, so it is safe to compute its value:
kono
parents:
diff changeset
2577
kono
parents:
diff changeset
2578 Last := No_Index + Index_Type'Base (Length);
kono
parents:
diff changeset
2579
kono
parents:
diff changeset
2580 -- Finally we test whether the value is within the range of the
kono
parents:
diff changeset
2581 -- generic actual index subtype:
kono
parents:
diff changeset
2582
kono
parents:
diff changeset
2583 if Checks and then Last > Index_Type'Last then
kono
parents:
diff changeset
2584 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2585 end if;
kono
parents:
diff changeset
2586
kono
parents:
diff changeset
2587 elsif Index_Type'First <= 0 then
kono
parents:
diff changeset
2588
kono
parents:
diff changeset
2589 -- Here we can compute Last directly, in the normal way. We know that
kono
parents:
diff changeset
2590 -- No_Index is less than 0, so there is no danger of overflow when
kono
parents:
diff changeset
2591 -- adding the (positive) value of Length.
kono
parents:
diff changeset
2592
kono
parents:
diff changeset
2593 Index := Count_Type'Base (No_Index) + Length; -- Last
kono
parents:
diff changeset
2594
kono
parents:
diff changeset
2595 if Checks and then Index > Count_Type'Base (Index_Type'Last) then
kono
parents:
diff changeset
2596 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2597 end if;
kono
parents:
diff changeset
2598
kono
parents:
diff changeset
2599 -- We know that the computed value (having type Count_Type) of Last
kono
parents:
diff changeset
2600 -- is within the range of the generic actual index subtype, so it is
kono
parents:
diff changeset
2601 -- safe to convert to Index_Type:
kono
parents:
diff changeset
2602
kono
parents:
diff changeset
2603 Last := Index_Type'Base (Index);
kono
parents:
diff changeset
2604
kono
parents:
diff changeset
2605 else
kono
parents:
diff changeset
2606 -- Here Index_Type'First (and Index_Type'Last) is positive, so we
kono
parents:
diff changeset
2607 -- must test the length indirectly (by working backwards from the
kono
parents:
diff changeset
2608 -- largest possible value of Last), in order to prevent overflow.
kono
parents:
diff changeset
2609
kono
parents:
diff changeset
2610 Index := Count_Type'Base (Index_Type'Last) - Length; -- No_Index
kono
parents:
diff changeset
2611
kono
parents:
diff changeset
2612 if Checks and then Index < Count_Type'Base (No_Index) then
kono
parents:
diff changeset
2613 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2614 end if;
kono
parents:
diff changeset
2615
kono
parents:
diff changeset
2616 -- We have determined that the value of Length would not create a
kono
parents:
diff changeset
2617 -- Last index value outside of the range of Index_Type, so we can now
kono
parents:
diff changeset
2618 -- safely compute its value.
kono
parents:
diff changeset
2619
kono
parents:
diff changeset
2620 Last := Index_Type'Base (Count_Type'Base (No_Index) + Length);
kono
parents:
diff changeset
2621 end if;
kono
parents:
diff changeset
2622
kono
parents:
diff changeset
2623 return V : Vector (Capacity => Length) do
kono
parents:
diff changeset
2624 V.Last := Last;
kono
parents:
diff changeset
2625 end return;
kono
parents:
diff changeset
2626 end To_Vector;
kono
parents:
diff changeset
2627
kono
parents:
diff changeset
2628 function To_Vector
kono
parents:
diff changeset
2629 (New_Item : Element_Type;
kono
parents:
diff changeset
2630 Length : Count_Type) return Vector
kono
parents:
diff changeset
2631 is
kono
parents:
diff changeset
2632 Index : Count_Type'Base;
kono
parents:
diff changeset
2633 Last : Index_Type'Base;
kono
parents:
diff changeset
2634
kono
parents:
diff changeset
2635 begin
kono
parents:
diff changeset
2636 if Length = 0 then
kono
parents:
diff changeset
2637 return Empty_Vector;
kono
parents:
diff changeset
2638 end if;
kono
parents:
diff changeset
2639
kono
parents:
diff changeset
2640 -- We create a vector object with a capacity that matches the specified
kono
parents:
diff changeset
2641 -- Length, but we do not allow the vector capacity (the length of the
kono
parents:
diff changeset
2642 -- internal array) to exceed the number of values in Index_Type'Range
kono
parents:
diff changeset
2643 -- (otherwise, there would be no way to refer to those components via an
kono
parents:
diff changeset
2644 -- index). We must therefore check whether the specified Length would
kono
parents:
diff changeset
2645 -- create a Last index value greater than Index_Type'Last.
kono
parents:
diff changeset
2646
kono
parents:
diff changeset
2647 if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
kono
parents:
diff changeset
2648
kono
parents:
diff changeset
2649 -- We perform a two-part test. First we determine whether the
kono
parents:
diff changeset
2650 -- computed Last value lies in the base range of the type, and then
kono
parents:
diff changeset
2651 -- determine whether it lies in the range of the index (sub)type.
kono
parents:
diff changeset
2652
kono
parents:
diff changeset
2653 -- Last must satisfy this relation:
kono
parents:
diff changeset
2654 -- First + Length - 1 <= Last
kono
parents:
diff changeset
2655 -- We regroup terms:
kono
parents:
diff changeset
2656 -- First - 1 <= Last - Length
kono
parents:
diff changeset
2657 -- Which can rewrite as:
kono
parents:
diff changeset
2658 -- No_Index <= Last - Length
kono
parents:
diff changeset
2659
kono
parents:
diff changeset
2660 if Checks and then
kono
parents:
diff changeset
2661 Index_Type'Base'Last - Index_Type'Base (Length) < No_Index
kono
parents:
diff changeset
2662 then
kono
parents:
diff changeset
2663 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2664 end if;
kono
parents:
diff changeset
2665
kono
parents:
diff changeset
2666 -- We now know that the computed value of Last is within the base
kono
parents:
diff changeset
2667 -- range of the type, so it is safe to compute its value:
kono
parents:
diff changeset
2668
kono
parents:
diff changeset
2669 Last := No_Index + Index_Type'Base (Length);
kono
parents:
diff changeset
2670
kono
parents:
diff changeset
2671 -- Finally we test whether the value is within the range of the
kono
parents:
diff changeset
2672 -- generic actual index subtype:
kono
parents:
diff changeset
2673
kono
parents:
diff changeset
2674 if Checks and then Last > Index_Type'Last then
kono
parents:
diff changeset
2675 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2676 end if;
kono
parents:
diff changeset
2677
kono
parents:
diff changeset
2678 elsif Index_Type'First <= 0 then
kono
parents:
diff changeset
2679
kono
parents:
diff changeset
2680 -- Here we can compute Last directly, in the normal way. We know that
kono
parents:
diff changeset
2681 -- No_Index is less than 0, so there is no danger of overflow when
kono
parents:
diff changeset
2682 -- adding the (positive) value of Length.
kono
parents:
diff changeset
2683
kono
parents:
diff changeset
2684 Index := Count_Type'Base (No_Index) + Length; -- same value as V.Last
kono
parents:
diff changeset
2685
kono
parents:
diff changeset
2686 if Checks and then Index > Count_Type'Base (Index_Type'Last) then
kono
parents:
diff changeset
2687 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2688 end if;
kono
parents:
diff changeset
2689
kono
parents:
diff changeset
2690 -- We know that the computed value (having type Count_Type) of Last
kono
parents:
diff changeset
2691 -- is within the range of the generic actual index subtype, so it is
kono
parents:
diff changeset
2692 -- safe to convert to Index_Type:
kono
parents:
diff changeset
2693
kono
parents:
diff changeset
2694 Last := Index_Type'Base (Index);
kono
parents:
diff changeset
2695
kono
parents:
diff changeset
2696 else
kono
parents:
diff changeset
2697 -- Here Index_Type'First (and Index_Type'Last) is positive, so we
kono
parents:
diff changeset
2698 -- must test the length indirectly (by working backwards from the
kono
parents:
diff changeset
2699 -- largest possible value of Last), in order to prevent overflow.
kono
parents:
diff changeset
2700
kono
parents:
diff changeset
2701 Index := Count_Type'Base (Index_Type'Last) - Length; -- No_Index
kono
parents:
diff changeset
2702
kono
parents:
diff changeset
2703 if Checks and then Index < Count_Type'Base (No_Index) then
kono
parents:
diff changeset
2704 raise Constraint_Error with "Length is out of range";
kono
parents:
diff changeset
2705 end if;
kono
parents:
diff changeset
2706
kono
parents:
diff changeset
2707 -- We have determined that the value of Length would not create a
kono
parents:
diff changeset
2708 -- Last index value outside of the range of Index_Type, so we can now
kono
parents:
diff changeset
2709 -- safely compute its value.
kono
parents:
diff changeset
2710
kono
parents:
diff changeset
2711 Last := Index_Type'Base (Count_Type'Base (No_Index) + Length);
kono
parents:
diff changeset
2712 end if;
kono
parents:
diff changeset
2713
kono
parents:
diff changeset
2714 return V : Vector (Capacity => Length) do
kono
parents:
diff changeset
2715 V.Elements := (others => New_Item);
kono
parents:
diff changeset
2716 V.Last := Last;
kono
parents:
diff changeset
2717 end return;
kono
parents:
diff changeset
2718 end To_Vector;
kono
parents:
diff changeset
2719
kono
parents:
diff changeset
2720 --------------------
kono
parents:
diff changeset
2721 -- Update_Element --
kono
parents:
diff changeset
2722 --------------------
kono
parents:
diff changeset
2723
kono
parents:
diff changeset
2724 procedure Update_Element
kono
parents:
diff changeset
2725 (Container : in out Vector;
kono
parents:
diff changeset
2726 Index : Index_Type;
kono
parents:
diff changeset
2727 Process : not null access procedure (Element : in out Element_Type))
kono
parents:
diff changeset
2728 is
kono
parents:
diff changeset
2729 Lock : With_Lock (Container.TC'Unchecked_Access);
kono
parents:
diff changeset
2730 begin
kono
parents:
diff changeset
2731 if Checks and then Index > Container.Last then
kono
parents:
diff changeset
2732 raise Constraint_Error with "Index is out of range";
kono
parents:
diff changeset
2733 end if;
kono
parents:
diff changeset
2734
kono
parents:
diff changeset
2735 Process (Container.Elements (To_Array_Index (Index)));
kono
parents:
diff changeset
2736 end Update_Element;
kono
parents:
diff changeset
2737
kono
parents:
diff changeset
2738 procedure Update_Element
kono
parents:
diff changeset
2739 (Container : in out Vector;
kono
parents:
diff changeset
2740 Position : Cursor;
kono
parents:
diff changeset
2741 Process : not null access procedure (Element : in out Element_Type))
kono
parents:
diff changeset
2742 is
kono
parents:
diff changeset
2743 begin
kono
parents:
diff changeset
2744 if Checks and then Position.Container = null then
kono
parents:
diff changeset
2745 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
2746 end if;
kono
parents:
diff changeset
2747
kono
parents:
diff changeset
2748 if Checks and then Position.Container /= Container'Unrestricted_Access
kono
parents:
diff changeset
2749 then
kono
parents:
diff changeset
2750 raise Program_Error with "Position cursor denotes wrong container";
kono
parents:
diff changeset
2751 end if;
kono
parents:
diff changeset
2752
kono
parents:
diff changeset
2753 Update_Element (Container, Position.Index, Process);
kono
parents:
diff changeset
2754 end Update_Element;
kono
parents:
diff changeset
2755
kono
parents:
diff changeset
2756 -----------
kono
parents:
diff changeset
2757 -- Write --
kono
parents:
diff changeset
2758 -----------
kono
parents:
diff changeset
2759
kono
parents:
diff changeset
2760 procedure Write
kono
parents:
diff changeset
2761 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2762 Container : Vector)
kono
parents:
diff changeset
2763 is
kono
parents:
diff changeset
2764 N : Count_Type;
kono
parents:
diff changeset
2765
kono
parents:
diff changeset
2766 begin
kono
parents:
diff changeset
2767 N := Container.Length;
kono
parents:
diff changeset
2768 Count_Type'Base'Write (Stream, N);
kono
parents:
diff changeset
2769
kono
parents:
diff changeset
2770 for J in 1 .. N loop
kono
parents:
diff changeset
2771 Element_Type'Write (Stream, Container.Elements (J));
kono
parents:
diff changeset
2772 end loop;
kono
parents:
diff changeset
2773 end Write;
kono
parents:
diff changeset
2774
kono
parents:
diff changeset
2775 procedure Write
kono
parents:
diff changeset
2776 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2777 Position : Cursor)
kono
parents:
diff changeset
2778 is
kono
parents:
diff changeset
2779 begin
kono
parents:
diff changeset
2780 raise Program_Error with "attempt to stream vector cursor";
kono
parents:
diff changeset
2781 end Write;
kono
parents:
diff changeset
2782
kono
parents:
diff changeset
2783 procedure Write
kono
parents:
diff changeset
2784 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2785 Item : Reference_Type)
kono
parents:
diff changeset
2786 is
kono
parents:
diff changeset
2787 begin
kono
parents:
diff changeset
2788 raise Program_Error with "attempt to stream reference";
kono
parents:
diff changeset
2789 end Write;
kono
parents:
diff changeset
2790
kono
parents:
diff changeset
2791 procedure Write
kono
parents:
diff changeset
2792 (Stream : not null access Root_Stream_Type'Class;
kono
parents:
diff changeset
2793 Item : Constant_Reference_Type)
kono
parents:
diff changeset
2794 is
kono
parents:
diff changeset
2795 begin
kono
parents:
diff changeset
2796 raise Program_Error with "attempt to stream reference";
kono
parents:
diff changeset
2797 end Write;
kono
parents:
diff changeset
2798
kono
parents:
diff changeset
2799 end Ada.Containers.Bounded_Vectors;