annotate gcc/ada/libgnat/a-cfdlli.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 -- ADA.CONTAINERS.FORMAL_DOUBLY_LINKED_LISTS --
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) 2010-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
kono
parents:
diff changeset
28 with System; use type System.Address;
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 package body Ada.Containers.Formal_Doubly_Linked_Lists with
kono
parents:
diff changeset
31 SPARK_Mode => Off
kono
parents:
diff changeset
32 is
kono
parents:
diff changeset
33 -----------------------
kono
parents:
diff changeset
34 -- Local Subprograms --
kono
parents:
diff changeset
35 -----------------------
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 procedure Allocate
kono
parents:
diff changeset
38 (Container : in out List;
kono
parents:
diff changeset
39 New_Item : Element_Type;
kono
parents:
diff changeset
40 New_Node : out Count_Type);
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 procedure Free (Container : in out List; X : Count_Type);
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 procedure Insert_Internal
kono
parents:
diff changeset
45 (Container : in out List;
kono
parents:
diff changeset
46 Before : Count_Type;
kono
parents:
diff changeset
47 New_Node : Count_Type);
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 function Vet (L : List; Position : Cursor) return Boolean;
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 ---------
kono
parents:
diff changeset
52 -- "=" --
kono
parents:
diff changeset
53 ---------
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 function "=" (Left : List; Right : List) return Boolean is
kono
parents:
diff changeset
56 LI : Count_Type;
kono
parents:
diff changeset
57 RI : Count_Type;
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 begin
kono
parents:
diff changeset
60 if Left'Address = Right'Address then
kono
parents:
diff changeset
61 return True;
kono
parents:
diff changeset
62 end if;
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 if Left.Length /= Right.Length then
kono
parents:
diff changeset
65 return False;
kono
parents:
diff changeset
66 end if;
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 LI := Left.First;
kono
parents:
diff changeset
69 RI := Left.First;
kono
parents:
diff changeset
70 while LI /= 0 loop
kono
parents:
diff changeset
71 if Left.Nodes (LI).Element /= Right.Nodes (LI).Element then
kono
parents:
diff changeset
72 return False;
kono
parents:
diff changeset
73 end if;
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 LI := Left.Nodes (LI).Next;
kono
parents:
diff changeset
76 RI := Right.Nodes (RI).Next;
kono
parents:
diff changeset
77 end loop;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 return True;
kono
parents:
diff changeset
80 end "=";
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 --------------
kono
parents:
diff changeset
83 -- Allocate --
kono
parents:
diff changeset
84 --------------
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 procedure Allocate
kono
parents:
diff changeset
87 (Container : in out List;
kono
parents:
diff changeset
88 New_Item : Element_Type;
kono
parents:
diff changeset
89 New_Node : out Count_Type)
kono
parents:
diff changeset
90 is
kono
parents:
diff changeset
91 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 begin
kono
parents:
diff changeset
94 if Container.Free >= 0 then
kono
parents:
diff changeset
95 New_Node := Container.Free;
kono
parents:
diff changeset
96 N (New_Node).Element := New_Item;
kono
parents:
diff changeset
97 Container.Free := N (New_Node).Next;
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 else
kono
parents:
diff changeset
100 New_Node := abs Container.Free;
kono
parents:
diff changeset
101 N (New_Node).Element := New_Item;
kono
parents:
diff changeset
102 Container.Free := Container.Free - 1;
kono
parents:
diff changeset
103 end if;
kono
parents:
diff changeset
104 end Allocate;
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 ------------
kono
parents:
diff changeset
107 -- Append --
kono
parents:
diff changeset
108 ------------
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 procedure Append (Container : in out List; New_Item : Element_Type) is
kono
parents:
diff changeset
111 begin
kono
parents:
diff changeset
112 Insert (Container, No_Element, New_Item, 1);
kono
parents:
diff changeset
113 end Append;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 procedure Append
kono
parents:
diff changeset
116 (Container : in out List;
kono
parents:
diff changeset
117 New_Item : Element_Type;
kono
parents:
diff changeset
118 Count : Count_Type)
kono
parents:
diff changeset
119 is
kono
parents:
diff changeset
120 begin
kono
parents:
diff changeset
121 Insert (Container, No_Element, New_Item, Count);
kono
parents:
diff changeset
122 end Append;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 ------------
kono
parents:
diff changeset
125 -- Assign --
kono
parents:
diff changeset
126 ------------
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 procedure Assign (Target : in out List; Source : List) is
kono
parents:
diff changeset
129 N : Node_Array renames Source.Nodes;
kono
parents:
diff changeset
130 J : Count_Type;
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 begin
kono
parents:
diff changeset
133 if Target'Address = Source'Address then
kono
parents:
diff changeset
134 return;
kono
parents:
diff changeset
135 end if;
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 if Target.Capacity < Source.Length then
kono
parents:
diff changeset
138 raise Constraint_Error with -- ???
kono
parents:
diff changeset
139 "Source length exceeds Target capacity";
kono
parents:
diff changeset
140 end if;
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 Clear (Target);
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 J := Source.First;
kono
parents:
diff changeset
145 while J /= 0 loop
kono
parents:
diff changeset
146 Append (Target, N (J).Element, 1);
kono
parents:
diff changeset
147 J := N (J).Next;
kono
parents:
diff changeset
148 end loop;
kono
parents:
diff changeset
149 end Assign;
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 -----------
kono
parents:
diff changeset
152 -- Clear --
kono
parents:
diff changeset
153 -----------
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 procedure Clear (Container : in out List) is
kono
parents:
diff changeset
156 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
157 X : Count_Type;
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 begin
kono
parents:
diff changeset
160 if Container.Length = 0 then
kono
parents:
diff changeset
161 pragma Assert (Container.First = 0);
kono
parents:
diff changeset
162 pragma Assert (Container.Last = 0);
kono
parents:
diff changeset
163 return;
kono
parents:
diff changeset
164 end if;
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 pragma Assert (Container.First >= 1);
kono
parents:
diff changeset
167 pragma Assert (Container.Last >= 1);
kono
parents:
diff changeset
168 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
169 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 while Container.Length > 1 loop
kono
parents:
diff changeset
172 X := Container.First;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 Container.First := N (X).Next;
kono
parents:
diff changeset
175 N (Container.First).Prev := 0;
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 Container.Length := Container.Length - 1;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 Free (Container, X);
kono
parents:
diff changeset
180 end loop;
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 X := Container.First;
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 Container.First := 0;
kono
parents:
diff changeset
185 Container.Last := 0;
kono
parents:
diff changeset
186 Container.Length := 0;
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 Free (Container, X);
kono
parents:
diff changeset
189 end Clear;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 --------------
kono
parents:
diff changeset
192 -- Contains --
kono
parents:
diff changeset
193 --------------
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 function Contains
kono
parents:
diff changeset
196 (Container : List;
kono
parents:
diff changeset
197 Item : Element_Type) return Boolean
kono
parents:
diff changeset
198 is
kono
parents:
diff changeset
199 begin
kono
parents:
diff changeset
200 return Find (Container, Item) /= No_Element;
kono
parents:
diff changeset
201 end Contains;
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 ----------
kono
parents:
diff changeset
204 -- Copy --
kono
parents:
diff changeset
205 ----------
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 function Copy
kono
parents:
diff changeset
208 (Source : List;
kono
parents:
diff changeset
209 Capacity : Count_Type := 0) return List
kono
parents:
diff changeset
210 is
kono
parents:
diff changeset
211 C : constant Count_Type := Count_Type'Max (Source.Capacity, Capacity);
kono
parents:
diff changeset
212 N : Count_Type;
kono
parents:
diff changeset
213 P : List (C);
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 begin
kono
parents:
diff changeset
216 if 0 < Capacity and then Capacity < Source.Capacity then
kono
parents:
diff changeset
217 raise Capacity_Error;
kono
parents:
diff changeset
218 end if;
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 N := 1;
kono
parents:
diff changeset
221 while N <= Source.Capacity loop
kono
parents:
diff changeset
222 P.Nodes (N).Prev := Source.Nodes (N).Prev;
kono
parents:
diff changeset
223 P.Nodes (N).Next := Source.Nodes (N).Next;
kono
parents:
diff changeset
224 P.Nodes (N).Element := Source.Nodes (N).Element;
kono
parents:
diff changeset
225 N := N + 1;
kono
parents:
diff changeset
226 end loop;
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 P.Free := Source.Free;
kono
parents:
diff changeset
229 P.Length := Source.Length;
kono
parents:
diff changeset
230 P.First := Source.First;
kono
parents:
diff changeset
231 P.Last := Source.Last;
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 if P.Free >= 0 then
kono
parents:
diff changeset
234 N := Source.Capacity + 1;
kono
parents:
diff changeset
235 while N <= C loop
kono
parents:
diff changeset
236 Free (P, N);
kono
parents:
diff changeset
237 N := N + 1;
kono
parents:
diff changeset
238 end loop;
kono
parents:
diff changeset
239 end if;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 return P;
kono
parents:
diff changeset
242 end Copy;
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 ------------
kono
parents:
diff changeset
245 -- Delete --
kono
parents:
diff changeset
246 ------------
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 procedure Delete (Container : in out List; Position : in out Cursor) is
kono
parents:
diff changeset
249 begin
kono
parents:
diff changeset
250 Delete
kono
parents:
diff changeset
251 (Container => Container,
kono
parents:
diff changeset
252 Position => Position,
kono
parents:
diff changeset
253 Count => 1);
kono
parents:
diff changeset
254 end Delete;
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 procedure Delete
kono
parents:
diff changeset
257 (Container : in out List;
kono
parents:
diff changeset
258 Position : in out Cursor;
kono
parents:
diff changeset
259 Count : Count_Type)
kono
parents:
diff changeset
260 is
kono
parents:
diff changeset
261 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
262 X : Count_Type;
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 begin
kono
parents:
diff changeset
265 if not Has_Element (Container => Container,
kono
parents:
diff changeset
266 Position => Position)
kono
parents:
diff changeset
267 then
kono
parents:
diff changeset
268 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
269 end if;
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 pragma Assert (Vet (Container, Position), "bad cursor in Delete");
kono
parents:
diff changeset
272 pragma Assert (Container.First >= 1);
kono
parents:
diff changeset
273 pragma Assert (Container.Last >= 1);
kono
parents:
diff changeset
274 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
275 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 if Position.Node = Container.First then
kono
parents:
diff changeset
278 Delete_First (Container, Count);
kono
parents:
diff changeset
279 Position := No_Element;
kono
parents:
diff changeset
280 return;
kono
parents:
diff changeset
281 end if;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 if Count = 0 then
kono
parents:
diff changeset
284 Position := No_Element;
kono
parents:
diff changeset
285 return;
kono
parents:
diff changeset
286 end if;
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 for Index in 1 .. Count loop
kono
parents:
diff changeset
289 pragma Assert (Container.Length >= 2);
kono
parents:
diff changeset
290
kono
parents:
diff changeset
291 X := Position.Node;
kono
parents:
diff changeset
292 Container.Length := Container.Length - 1;
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 if X = Container.Last then
kono
parents:
diff changeset
295 Position := No_Element;
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 Container.Last := N (X).Prev;
kono
parents:
diff changeset
298 N (Container.Last).Next := 0;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 Free (Container, X);
kono
parents:
diff changeset
301 return;
kono
parents:
diff changeset
302 end if;
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Position.Node := N (X).Next;
kono
parents:
diff changeset
305 pragma Assert (N (Position.Node).Prev >= 0);
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 N (N (X).Next).Prev := N (X).Prev;
kono
parents:
diff changeset
308 N (N (X).Prev).Next := N (X).Next;
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 Free (Container, X);
kono
parents:
diff changeset
311 end loop;
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 Position := No_Element;
kono
parents:
diff changeset
314 end Delete;
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 ------------------
kono
parents:
diff changeset
317 -- Delete_First --
kono
parents:
diff changeset
318 ------------------
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 procedure Delete_First (Container : in out List) is
kono
parents:
diff changeset
321 begin
kono
parents:
diff changeset
322 Delete_First
kono
parents:
diff changeset
323 (Container => Container,
kono
parents:
diff changeset
324 Count => 1);
kono
parents:
diff changeset
325 end Delete_First;
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 procedure Delete_First (Container : in out List; Count : Count_Type) is
kono
parents:
diff changeset
328 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
329 X : Count_Type;
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 begin
kono
parents:
diff changeset
332 if Count >= Container.Length then
kono
parents:
diff changeset
333 Clear (Container);
kono
parents:
diff changeset
334 return;
kono
parents:
diff changeset
335 end if;
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 if Count = 0 then
kono
parents:
diff changeset
338 return;
kono
parents:
diff changeset
339 end if;
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 for J in 1 .. Count loop
kono
parents:
diff changeset
342 X := Container.First;
kono
parents:
diff changeset
343 pragma Assert (N (N (X).Next).Prev = Container.First);
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 Container.First := N (X).Next;
kono
parents:
diff changeset
346 N (Container.First).Prev := 0;
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 Container.Length := Container.Length - 1;
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 Free (Container, X);
kono
parents:
diff changeset
351 end loop;
kono
parents:
diff changeset
352 end Delete_First;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 -----------------
kono
parents:
diff changeset
355 -- Delete_Last --
kono
parents:
diff changeset
356 -----------------
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 procedure Delete_Last (Container : in out List) is
kono
parents:
diff changeset
359 begin
kono
parents:
diff changeset
360 Delete_Last
kono
parents:
diff changeset
361 (Container => Container,
kono
parents:
diff changeset
362 Count => 1);
kono
parents:
diff changeset
363 end Delete_Last;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 procedure Delete_Last (Container : in out List; Count : Count_Type) is
kono
parents:
diff changeset
366 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
367 X : Count_Type;
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 begin
kono
parents:
diff changeset
370 if Count >= Container.Length then
kono
parents:
diff changeset
371 Clear (Container);
kono
parents:
diff changeset
372 return;
kono
parents:
diff changeset
373 end if;
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 if Count = 0 then
kono
parents:
diff changeset
376 return;
kono
parents:
diff changeset
377 end if;
kono
parents:
diff changeset
378
kono
parents:
diff changeset
379 for J in 1 .. Count loop
kono
parents:
diff changeset
380 X := Container.Last;
kono
parents:
diff changeset
381 pragma Assert (N (N (X).Prev).Next = Container.Last);
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 Container.Last := N (X).Prev;
kono
parents:
diff changeset
384 N (Container.Last).Next := 0;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 Container.Length := Container.Length - 1;
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 Free (Container, X);
kono
parents:
diff changeset
389 end loop;
kono
parents:
diff changeset
390 end Delete_Last;
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 -------------
kono
parents:
diff changeset
393 -- Element --
kono
parents:
diff changeset
394 -------------
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 function Element
kono
parents:
diff changeset
397 (Container : List;
kono
parents:
diff changeset
398 Position : Cursor) return Element_Type
kono
parents:
diff changeset
399 is
kono
parents:
diff changeset
400 begin
kono
parents:
diff changeset
401 if not Has_Element (Container => Container, Position => Position) then
kono
parents:
diff changeset
402 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
403 end if;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 return Container.Nodes (Position.Node).Element;
kono
parents:
diff changeset
406 end Element;
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 ----------
kono
parents:
diff changeset
409 -- Find --
kono
parents:
diff changeset
410 ----------
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 function Find
kono
parents:
diff changeset
413 (Container : List;
kono
parents:
diff changeset
414 Item : Element_Type;
kono
parents:
diff changeset
415 Position : Cursor := No_Element) return Cursor
kono
parents:
diff changeset
416 is
kono
parents:
diff changeset
417 From : Count_Type := Position.Node;
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 begin
kono
parents:
diff changeset
420 if From = 0 and Container.Length = 0 then
kono
parents:
diff changeset
421 return No_Element;
kono
parents:
diff changeset
422 end if;
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if From = 0 then
kono
parents:
diff changeset
425 From := Container.First;
kono
parents:
diff changeset
426 end if;
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 if Position.Node /= 0 and then not Has_Element (Container, Position) then
kono
parents:
diff changeset
429 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
430 end if;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 while From /= 0 loop
kono
parents:
diff changeset
433 if Container.Nodes (From).Element = Item then
kono
parents:
diff changeset
434 return (Node => From);
kono
parents:
diff changeset
435 end if;
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 From := Container.Nodes (From).Next;
kono
parents:
diff changeset
438 end loop;
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 return No_Element;
kono
parents:
diff changeset
441 end Find;
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 -----------
kono
parents:
diff changeset
444 -- First --
kono
parents:
diff changeset
445 -----------
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 function First (Container : List) return Cursor is
kono
parents:
diff changeset
448 begin
kono
parents:
diff changeset
449 if Container.First = 0 then
kono
parents:
diff changeset
450 return No_Element;
kono
parents:
diff changeset
451 end if;
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 return (Node => Container.First);
kono
parents:
diff changeset
454 end First;
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 -------------------
kono
parents:
diff changeset
457 -- First_Element --
kono
parents:
diff changeset
458 -------------------
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 function First_Element (Container : List) return Element_Type is
kono
parents:
diff changeset
461 F : constant Count_Type := Container.First;
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 begin
kono
parents:
diff changeset
464 if F = 0 then
kono
parents:
diff changeset
465 raise Constraint_Error with "list is empty";
kono
parents:
diff changeset
466 else
kono
parents:
diff changeset
467 return Container.Nodes (F).Element;
kono
parents:
diff changeset
468 end if;
kono
parents:
diff changeset
469 end First_Element;
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 ------------------
kono
parents:
diff changeset
472 -- Formal_Model --
kono
parents:
diff changeset
473 ------------------
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 package body Formal_Model is
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 ----------------------------
kono
parents:
diff changeset
478 -- Lift_Abstraction_Level --
kono
parents:
diff changeset
479 ----------------------------
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 procedure Lift_Abstraction_Level (Container : List) is null;
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 -------------------------
kono
parents:
diff changeset
484 -- M_Elements_In_Union --
kono
parents:
diff changeset
485 -------------------------
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 function M_Elements_In_Union
kono
parents:
diff changeset
488 (Container : M.Sequence;
kono
parents:
diff changeset
489 Left : M.Sequence;
kono
parents:
diff changeset
490 Right : M.Sequence) return Boolean
kono
parents:
diff changeset
491 is
kono
parents:
diff changeset
492 Elem : Element_Type;
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 begin
kono
parents:
diff changeset
495 for Index in 1 .. M.Length (Container) loop
kono
parents:
diff changeset
496 Elem := Element (Container, Index);
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 if not M.Contains (Left, 1, M.Length (Left), Elem)
kono
parents:
diff changeset
499 and then not M.Contains (Right, 1, M.Length (Right), Elem)
kono
parents:
diff changeset
500 then
kono
parents:
diff changeset
501 return False;
kono
parents:
diff changeset
502 end if;
kono
parents:
diff changeset
503 end loop;
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 return True;
kono
parents:
diff changeset
506 end M_Elements_In_Union;
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 -------------------------
kono
parents:
diff changeset
509 -- M_Elements_Included --
kono
parents:
diff changeset
510 -------------------------
kono
parents:
diff changeset
511
kono
parents:
diff changeset
512 function M_Elements_Included
kono
parents:
diff changeset
513 (Left : M.Sequence;
kono
parents:
diff changeset
514 L_Fst : Positive_Count_Type := 1;
kono
parents:
diff changeset
515 L_Lst : Count_Type;
kono
parents:
diff changeset
516 Right : M.Sequence;
kono
parents:
diff changeset
517 R_Fst : Positive_Count_Type := 1;
kono
parents:
diff changeset
518 R_Lst : Count_Type) return Boolean
kono
parents:
diff changeset
519 is
kono
parents:
diff changeset
520 begin
kono
parents:
diff changeset
521 for I in L_Fst .. L_Lst loop
kono
parents:
diff changeset
522 declare
kono
parents:
diff changeset
523 Found : Boolean := False;
kono
parents:
diff changeset
524 J : Count_Type := R_Fst - 1;
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 begin
kono
parents:
diff changeset
527 while not Found and J < R_Lst loop
kono
parents:
diff changeset
528 J := J + 1;
kono
parents:
diff changeset
529 if Element (Left, I) = Element (Right, J) then
kono
parents:
diff changeset
530 Found := True;
kono
parents:
diff changeset
531 end if;
kono
parents:
diff changeset
532 end loop;
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 if not Found then
kono
parents:
diff changeset
535 return False;
kono
parents:
diff changeset
536 end if;
kono
parents:
diff changeset
537 end;
kono
parents:
diff changeset
538 end loop;
kono
parents:
diff changeset
539
kono
parents:
diff changeset
540 return True;
kono
parents:
diff changeset
541 end M_Elements_Included;
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 -------------------------
kono
parents:
diff changeset
544 -- M_Elements_Reversed --
kono
parents:
diff changeset
545 -------------------------
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 function M_Elements_Reversed
kono
parents:
diff changeset
548 (Left : M.Sequence;
kono
parents:
diff changeset
549 Right : M.Sequence) return Boolean
kono
parents:
diff changeset
550 is
kono
parents:
diff changeset
551 L : constant Count_Type := M.Length (Left);
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 begin
kono
parents:
diff changeset
554 if L /= M.Length (Right) then
kono
parents:
diff changeset
555 return False;
kono
parents:
diff changeset
556 end if;
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 for I in 1 .. L loop
kono
parents:
diff changeset
559 if Element (Left, I) /= Element (Right, L - I + 1) then
kono
parents:
diff changeset
560 return False;
kono
parents:
diff changeset
561 end if;
kono
parents:
diff changeset
562 end loop;
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 return True;
kono
parents:
diff changeset
565 end M_Elements_Reversed;
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 ------------------------
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
568 -- M_Elements_Swapped --
111
kono
parents:
diff changeset
569 ------------------------
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 function M_Elements_Swapped
kono
parents:
diff changeset
572 (Left : M.Sequence;
kono
parents:
diff changeset
573 Right : M.Sequence;
kono
parents:
diff changeset
574 X : Positive_Count_Type;
kono
parents:
diff changeset
575 Y : Positive_Count_Type) return Boolean
kono
parents:
diff changeset
576 is
kono
parents:
diff changeset
577 begin
kono
parents:
diff changeset
578 if M.Length (Left) /= M.Length (Right)
kono
parents:
diff changeset
579 or else Element (Left, X) /= Element (Right, Y)
kono
parents:
diff changeset
580 or else Element (Left, Y) /= Element (Right, X)
kono
parents:
diff changeset
581 then
kono
parents:
diff changeset
582 return False;
kono
parents:
diff changeset
583 end if;
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 for I in 1 .. M.Length (Left) loop
kono
parents:
diff changeset
586 if I /= X and then I /= Y
kono
parents:
diff changeset
587 and then Element (Left, I) /= Element (Right, I)
kono
parents:
diff changeset
588 then
kono
parents:
diff changeset
589 return False;
kono
parents:
diff changeset
590 end if;
kono
parents:
diff changeset
591 end loop;
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 return True;
kono
parents:
diff changeset
594 end M_Elements_Swapped;
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 -----------
kono
parents:
diff changeset
597 -- Model --
kono
parents:
diff changeset
598 -----------
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 function Model (Container : List) return M.Sequence is
kono
parents:
diff changeset
601 Position : Count_Type := Container.First;
kono
parents:
diff changeset
602 R : M.Sequence;
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 begin
kono
parents:
diff changeset
605 -- Can't use First, Next or Element here, since they depend on models
kono
parents:
diff changeset
606 -- for their postconditions.
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 while Position /= 0 loop
kono
parents:
diff changeset
609 R := M.Add (R, Container.Nodes (Position).Element);
kono
parents:
diff changeset
610 Position := Container.Nodes (Position).Next;
kono
parents:
diff changeset
611 end loop;
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 return R;
kono
parents:
diff changeset
614 end Model;
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 -----------------------
kono
parents:
diff changeset
617 -- Mapping_Preserved --
kono
parents:
diff changeset
618 -----------------------
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 function Mapping_Preserved
kono
parents:
diff changeset
621 (M_Left : M.Sequence;
kono
parents:
diff changeset
622 M_Right : M.Sequence;
kono
parents:
diff changeset
623 P_Left : P.Map;
kono
parents:
diff changeset
624 P_Right : P.Map) return Boolean
kono
parents:
diff changeset
625 is
kono
parents:
diff changeset
626 begin
kono
parents:
diff changeset
627 for C of P_Left loop
kono
parents:
diff changeset
628 if not P.Has_Key (P_Right, C)
kono
parents:
diff changeset
629 or else P.Get (P_Left, C) > M.Length (M_Left)
kono
parents:
diff changeset
630 or else P.Get (P_Right, C) > M.Length (M_Right)
kono
parents:
diff changeset
631 or else M.Get (M_Left, P.Get (P_Left, C)) /=
kono
parents:
diff changeset
632 M.Get (M_Right, P.Get (P_Right, C))
kono
parents:
diff changeset
633 then
kono
parents:
diff changeset
634 return False;
kono
parents:
diff changeset
635 end if;
kono
parents:
diff changeset
636 end loop;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 for C of P_Right loop
kono
parents:
diff changeset
639 if not P.Has_Key (P_Left, C) then
kono
parents:
diff changeset
640 return False;
kono
parents:
diff changeset
641 end if;
kono
parents:
diff changeset
642 end loop;
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 return True;
kono
parents:
diff changeset
645 end Mapping_Preserved;
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 -------------------------
kono
parents:
diff changeset
648 -- P_Positions_Shifted --
kono
parents:
diff changeset
649 -------------------------
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 function P_Positions_Shifted
kono
parents:
diff changeset
652 (Small : P.Map;
kono
parents:
diff changeset
653 Big : P.Map;
kono
parents:
diff changeset
654 Cut : Positive_Count_Type;
kono
parents:
diff changeset
655 Count : Count_Type := 1) return Boolean
kono
parents:
diff changeset
656 is
kono
parents:
diff changeset
657 begin
kono
parents:
diff changeset
658 for Cu of Small loop
kono
parents:
diff changeset
659 if not P.Has_Key (Big, Cu) then
kono
parents:
diff changeset
660 return False;
kono
parents:
diff changeset
661 end if;
kono
parents:
diff changeset
662 end loop;
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 for Cu of Big loop
kono
parents:
diff changeset
665 declare
kono
parents:
diff changeset
666 Pos : constant Positive_Count_Type := P.Get (Big, Cu);
kono
parents:
diff changeset
667
kono
parents:
diff changeset
668 begin
kono
parents:
diff changeset
669 if Pos < Cut then
kono
parents:
diff changeset
670 if not P.Has_Key (Small, Cu)
kono
parents:
diff changeset
671 or else Pos /= P.Get (Small, Cu)
kono
parents:
diff changeset
672 then
kono
parents:
diff changeset
673 return False;
kono
parents:
diff changeset
674 end if;
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 elsif Pos >= Cut + Count then
kono
parents:
diff changeset
677 if not P.Has_Key (Small, Cu)
kono
parents:
diff changeset
678 or else Pos /= P.Get (Small, Cu) + Count
kono
parents:
diff changeset
679 then
kono
parents:
diff changeset
680 return False;
kono
parents:
diff changeset
681 end if;
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 else
kono
parents:
diff changeset
684 if P.Has_Key (Small, Cu) then
kono
parents:
diff changeset
685 return False;
kono
parents:
diff changeset
686 end if;
kono
parents:
diff changeset
687 end if;
kono
parents:
diff changeset
688 end;
kono
parents:
diff changeset
689 end loop;
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 return True;
kono
parents:
diff changeset
692 end P_Positions_Shifted;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 -------------------------
kono
parents:
diff changeset
695 -- P_Positions_Swapped --
kono
parents:
diff changeset
696 -------------------------
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 function P_Positions_Swapped
kono
parents:
diff changeset
699 (Left : P.Map;
kono
parents:
diff changeset
700 Right : P.Map;
kono
parents:
diff changeset
701 X : Cursor;
kono
parents:
diff changeset
702 Y : Cursor) return Boolean
kono
parents:
diff changeset
703 is
kono
parents:
diff changeset
704 begin
kono
parents:
diff changeset
705 if not P.Has_Key (Left, X)
kono
parents:
diff changeset
706 or not P.Has_Key (Left, Y)
kono
parents:
diff changeset
707 or not P.Has_Key (Right, X)
kono
parents:
diff changeset
708 or not P.Has_Key (Right, Y)
kono
parents:
diff changeset
709 then
kono
parents:
diff changeset
710 return False;
kono
parents:
diff changeset
711 end if;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 if P.Get (Left, X) /= P.Get (Right, Y)
kono
parents:
diff changeset
714 or P.Get (Left, Y) /= P.Get (Right, X)
kono
parents:
diff changeset
715 then
kono
parents:
diff changeset
716 return False;
kono
parents:
diff changeset
717 end if;
kono
parents:
diff changeset
718
kono
parents:
diff changeset
719 for C of Left loop
kono
parents:
diff changeset
720 if not P.Has_Key (Right, C) then
kono
parents:
diff changeset
721 return False;
kono
parents:
diff changeset
722 end if;
kono
parents:
diff changeset
723 end loop;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 for C of Right loop
kono
parents:
diff changeset
726 if not P.Has_Key (Left, C)
kono
parents:
diff changeset
727 or else (C /= X
kono
parents:
diff changeset
728 and C /= Y
kono
parents:
diff changeset
729 and P.Get (Left, C) /= P.Get (Right, C))
kono
parents:
diff changeset
730 then
kono
parents:
diff changeset
731 return False;
kono
parents:
diff changeset
732 end if;
kono
parents:
diff changeset
733 end loop;
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 return True;
kono
parents:
diff changeset
736 end P_Positions_Swapped;
kono
parents:
diff changeset
737
kono
parents:
diff changeset
738 ---------------------------
kono
parents:
diff changeset
739 -- P_Positions_Truncated --
kono
parents:
diff changeset
740 ---------------------------
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 function P_Positions_Truncated
kono
parents:
diff changeset
743 (Small : P.Map;
kono
parents:
diff changeset
744 Big : P.Map;
kono
parents:
diff changeset
745 Cut : Positive_Count_Type;
kono
parents:
diff changeset
746 Count : Count_Type := 1) return Boolean
kono
parents:
diff changeset
747 is
kono
parents:
diff changeset
748 begin
kono
parents:
diff changeset
749 for Cu of Small loop
kono
parents:
diff changeset
750 if not P.Has_Key (Big, Cu) then
kono
parents:
diff changeset
751 return False;
kono
parents:
diff changeset
752 end if;
kono
parents:
diff changeset
753 end loop;
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 for Cu of Big loop
kono
parents:
diff changeset
756 declare
kono
parents:
diff changeset
757 Pos : constant Positive_Count_Type := P.Get (Big, Cu);
kono
parents:
diff changeset
758
kono
parents:
diff changeset
759 begin
kono
parents:
diff changeset
760 if Pos < Cut then
kono
parents:
diff changeset
761 if not P.Has_Key (Small, Cu)
kono
parents:
diff changeset
762 or else Pos /= P.Get (Small, Cu)
kono
parents:
diff changeset
763 then
kono
parents:
diff changeset
764 return False;
kono
parents:
diff changeset
765 end if;
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 elsif Pos >= Cut + Count then
kono
parents:
diff changeset
768 return False;
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 elsif P.Has_Key (Small, Cu) then
kono
parents:
diff changeset
771 return False;
kono
parents:
diff changeset
772 end if;
kono
parents:
diff changeset
773 end;
kono
parents:
diff changeset
774 end loop;
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 return True;
kono
parents:
diff changeset
777 end P_Positions_Truncated;
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 ---------------
kono
parents:
diff changeset
780 -- Positions --
kono
parents:
diff changeset
781 ---------------
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 function Positions (Container : List) return P.Map is
kono
parents:
diff changeset
784 I : Count_Type := 1;
kono
parents:
diff changeset
785 Position : Count_Type := Container.First;
kono
parents:
diff changeset
786 R : P.Map;
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 begin
kono
parents:
diff changeset
789 -- Can't use First, Next or Element here, since they depend on models
kono
parents:
diff changeset
790 -- for their postconditions.
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 while Position /= 0 loop
kono
parents:
diff changeset
793 R := P.Add (R, (Node => Position), I);
kono
parents:
diff changeset
794 pragma Assert (P.Length (R) = I);
kono
parents:
diff changeset
795 Position := Container.Nodes (Position).Next;
kono
parents:
diff changeset
796 I := I + 1;
kono
parents:
diff changeset
797 end loop;
kono
parents:
diff changeset
798
kono
parents:
diff changeset
799 return R;
kono
parents:
diff changeset
800 end Positions;
kono
parents:
diff changeset
801
kono
parents:
diff changeset
802 end Formal_Model;
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 ----------
kono
parents:
diff changeset
805 -- Free --
kono
parents:
diff changeset
806 ----------
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 procedure Free (Container : in out List; X : Count_Type) is
kono
parents:
diff changeset
809 pragma Assert (X > 0);
kono
parents:
diff changeset
810 pragma Assert (X <= Container.Capacity);
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
813
kono
parents:
diff changeset
814 begin
kono
parents:
diff changeset
815 N (X).Prev := -1; -- Node is deallocated (not on active list)
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 if Container.Free >= 0 then
kono
parents:
diff changeset
818 N (X).Next := Container.Free;
kono
parents:
diff changeset
819 Container.Free := X;
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 elsif X + 1 = abs Container.Free then
kono
parents:
diff changeset
822 N (X).Next := 0; -- Not strictly necessary, but marginally safer
kono
parents:
diff changeset
823 Container.Free := Container.Free + 1;
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 else
kono
parents:
diff changeset
826 Container.Free := abs Container.Free;
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 if Container.Free > Container.Capacity then
kono
parents:
diff changeset
829 Container.Free := 0;
kono
parents:
diff changeset
830
kono
parents:
diff changeset
831 else
kono
parents:
diff changeset
832 for J in Container.Free .. Container.Capacity - 1 loop
kono
parents:
diff changeset
833 N (J).Next := J + 1;
kono
parents:
diff changeset
834 end loop;
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 N (Container.Capacity).Next := 0;
kono
parents:
diff changeset
837 end if;
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 N (X).Next := Container.Free;
kono
parents:
diff changeset
840 Container.Free := X;
kono
parents:
diff changeset
841 end if;
kono
parents:
diff changeset
842 end Free;
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 ---------------------
kono
parents:
diff changeset
845 -- Generic_Sorting --
kono
parents:
diff changeset
846 ---------------------
kono
parents:
diff changeset
847
kono
parents:
diff changeset
848 package body Generic_Sorting with SPARK_Mode => Off is
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 ------------------
kono
parents:
diff changeset
851 -- Formal_Model --
kono
parents:
diff changeset
852 ------------------
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 package body Formal_Model is
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 -----------------------
kono
parents:
diff changeset
857 -- M_Elements_Sorted --
kono
parents:
diff changeset
858 -----------------------
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 function M_Elements_Sorted (Container : M.Sequence) return Boolean is
kono
parents:
diff changeset
861 begin
kono
parents:
diff changeset
862 if M.Length (Container) = 0 then
kono
parents:
diff changeset
863 return True;
kono
parents:
diff changeset
864 end if;
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 declare
kono
parents:
diff changeset
867 E1 : Element_Type := Element (Container, 1);
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 begin
kono
parents:
diff changeset
870 for I in 2 .. M.Length (Container) loop
kono
parents:
diff changeset
871 declare
kono
parents:
diff changeset
872 E2 : constant Element_Type := Element (Container, I);
kono
parents:
diff changeset
873
kono
parents:
diff changeset
874 begin
kono
parents:
diff changeset
875 if E2 < E1 then
kono
parents:
diff changeset
876 return False;
kono
parents:
diff changeset
877 end if;
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 E1 := E2;
kono
parents:
diff changeset
880 end;
kono
parents:
diff changeset
881 end loop;
kono
parents:
diff changeset
882 end;
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 return True;
kono
parents:
diff changeset
885 end M_Elements_Sorted;
kono
parents:
diff changeset
886
kono
parents:
diff changeset
887 end Formal_Model;
kono
parents:
diff changeset
888
kono
parents:
diff changeset
889 ---------------
kono
parents:
diff changeset
890 -- Is_Sorted --
kono
parents:
diff changeset
891 ---------------
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 function Is_Sorted (Container : List) return Boolean is
kono
parents:
diff changeset
894 Nodes : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
895 Node : Count_Type := Container.First;
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 begin
kono
parents:
diff changeset
898 for J in 2 .. Container.Length loop
kono
parents:
diff changeset
899 if Nodes (Nodes (Node).Next).Element < Nodes (Node).Element then
kono
parents:
diff changeset
900 return False;
kono
parents:
diff changeset
901 else
kono
parents:
diff changeset
902 Node := Nodes (Node).Next;
kono
parents:
diff changeset
903 end if;
kono
parents:
diff changeset
904 end loop;
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 return True;
kono
parents:
diff changeset
907 end Is_Sorted;
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 -----------
kono
parents:
diff changeset
910 -- Merge --
kono
parents:
diff changeset
911 -----------
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 procedure Merge (Target : in out List; Source : in out List) is
kono
parents:
diff changeset
914 LN : Node_Array renames Target.Nodes;
kono
parents:
diff changeset
915 RN : Node_Array renames Source.Nodes;
kono
parents:
diff changeset
916 LI : Cursor;
kono
parents:
diff changeset
917 RI : Cursor;
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 begin
kono
parents:
diff changeset
920 if Target'Address = Source'Address then
kono
parents:
diff changeset
921 raise Program_Error with "Target and Source denote same container";
kono
parents:
diff changeset
922 end if;
kono
parents:
diff changeset
923
kono
parents:
diff changeset
924 LI := First (Target);
kono
parents:
diff changeset
925 RI := First (Source);
kono
parents:
diff changeset
926 while RI.Node /= 0 loop
kono
parents:
diff changeset
927 pragma Assert
kono
parents:
diff changeset
928 (RN (RI.Node).Next = 0
kono
parents:
diff changeset
929 or else not (RN (RN (RI.Node).Next).Element <
kono
parents:
diff changeset
930 RN (RI.Node).Element));
kono
parents:
diff changeset
931
kono
parents:
diff changeset
932 if LI.Node = 0 then
kono
parents:
diff changeset
933 Splice (Target, No_Element, Source);
kono
parents:
diff changeset
934 return;
kono
parents:
diff changeset
935 end if;
kono
parents:
diff changeset
936
kono
parents:
diff changeset
937 pragma Assert
kono
parents:
diff changeset
938 (LN (LI.Node).Next = 0
kono
parents:
diff changeset
939 or else not (LN (LN (LI.Node).Next).Element <
kono
parents:
diff changeset
940 LN (LI.Node).Element));
kono
parents:
diff changeset
941
kono
parents:
diff changeset
942 if RN (RI.Node).Element < LN (LI.Node).Element then
kono
parents:
diff changeset
943 declare
kono
parents:
diff changeset
944 RJ : Cursor := RI;
kono
parents:
diff changeset
945 pragma Warnings (Off, RJ);
kono
parents:
diff changeset
946 begin
kono
parents:
diff changeset
947 RI.Node := RN (RI.Node).Next;
kono
parents:
diff changeset
948 Splice (Target, LI, Source, RJ);
kono
parents:
diff changeset
949 end;
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 else
kono
parents:
diff changeset
952 LI.Node := LN (LI.Node).Next;
kono
parents:
diff changeset
953 end if;
kono
parents:
diff changeset
954 end loop;
kono
parents:
diff changeset
955 end Merge;
kono
parents:
diff changeset
956
kono
parents:
diff changeset
957 ----------
kono
parents:
diff changeset
958 -- Sort --
kono
parents:
diff changeset
959 ----------
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 procedure Sort (Container : in out List) is
kono
parents:
diff changeset
962 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 procedure Partition (Pivot : Count_Type; Back : Count_Type);
kono
parents:
diff changeset
965 procedure Sort (Front : Count_Type; Back : Count_Type);
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 ---------------
kono
parents:
diff changeset
968 -- Partition --
kono
parents:
diff changeset
969 ---------------
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 procedure Partition (Pivot : Count_Type; Back : Count_Type) is
kono
parents:
diff changeset
972 Node : Count_Type;
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 begin
kono
parents:
diff changeset
975 Node := N (Pivot).Next;
kono
parents:
diff changeset
976 while Node /= Back loop
kono
parents:
diff changeset
977 if N (Node).Element < N (Pivot).Element then
kono
parents:
diff changeset
978 declare
kono
parents:
diff changeset
979 Prev : constant Count_Type := N (Node).Prev;
kono
parents:
diff changeset
980 Next : constant Count_Type := N (Node).Next;
kono
parents:
diff changeset
981
kono
parents:
diff changeset
982 begin
kono
parents:
diff changeset
983 N (Prev).Next := Next;
kono
parents:
diff changeset
984
kono
parents:
diff changeset
985 if Next = 0 then
kono
parents:
diff changeset
986 Container.Last := Prev;
kono
parents:
diff changeset
987 else
kono
parents:
diff changeset
988 N (Next).Prev := Prev;
kono
parents:
diff changeset
989 end if;
kono
parents:
diff changeset
990
kono
parents:
diff changeset
991 N (Node).Next := Pivot;
kono
parents:
diff changeset
992 N (Node).Prev := N (Pivot).Prev;
kono
parents:
diff changeset
993
kono
parents:
diff changeset
994 N (Pivot).Prev := Node;
kono
parents:
diff changeset
995
kono
parents:
diff changeset
996 if N (Node).Prev = 0 then
kono
parents:
diff changeset
997 Container.First := Node;
kono
parents:
diff changeset
998 else
kono
parents:
diff changeset
999 N (N (Node).Prev).Next := Node;
kono
parents:
diff changeset
1000 end if;
kono
parents:
diff changeset
1001
kono
parents:
diff changeset
1002 Node := Next;
kono
parents:
diff changeset
1003 end;
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 else
kono
parents:
diff changeset
1006 Node := N (Node).Next;
kono
parents:
diff changeset
1007 end if;
kono
parents:
diff changeset
1008 end loop;
kono
parents:
diff changeset
1009 end Partition;
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 ----------
kono
parents:
diff changeset
1012 -- Sort --
kono
parents:
diff changeset
1013 ----------
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 procedure Sort (Front : Count_Type; Back : Count_Type) is
kono
parents:
diff changeset
1016 Pivot : Count_Type;
kono
parents:
diff changeset
1017
kono
parents:
diff changeset
1018 begin
kono
parents:
diff changeset
1019 if Front = 0 then
kono
parents:
diff changeset
1020 Pivot := Container.First;
kono
parents:
diff changeset
1021 else
kono
parents:
diff changeset
1022 Pivot := N (Front).Next;
kono
parents:
diff changeset
1023 end if;
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 if Pivot /= Back then
kono
parents:
diff changeset
1026 Partition (Pivot, Back);
kono
parents:
diff changeset
1027 Sort (Front, Pivot);
kono
parents:
diff changeset
1028 Sort (Pivot, Back);
kono
parents:
diff changeset
1029 end if;
kono
parents:
diff changeset
1030 end Sort;
kono
parents:
diff changeset
1031
kono
parents:
diff changeset
1032 -- Start of processing for Sort
kono
parents:
diff changeset
1033
kono
parents:
diff changeset
1034 begin
kono
parents:
diff changeset
1035 if Container.Length <= 1 then
kono
parents:
diff changeset
1036 return;
kono
parents:
diff changeset
1037 end if;
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1040 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 Sort (Front => 0, Back => 0);
kono
parents:
diff changeset
1043
kono
parents:
diff changeset
1044 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1045 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1046 end Sort;
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 end Generic_Sorting;
kono
parents:
diff changeset
1049
kono
parents:
diff changeset
1050 -----------------
kono
parents:
diff changeset
1051 -- Has_Element --
kono
parents:
diff changeset
1052 -----------------
kono
parents:
diff changeset
1053
kono
parents:
diff changeset
1054 function Has_Element (Container : List; Position : Cursor) return Boolean is
kono
parents:
diff changeset
1055 begin
kono
parents:
diff changeset
1056 if Position.Node = 0 then
kono
parents:
diff changeset
1057 return False;
kono
parents:
diff changeset
1058 end if;
kono
parents:
diff changeset
1059
kono
parents:
diff changeset
1060 return Container.Nodes (Position.Node).Prev /= -1;
kono
parents:
diff changeset
1061 end Has_Element;
kono
parents:
diff changeset
1062
kono
parents:
diff changeset
1063 ------------
kono
parents:
diff changeset
1064 -- Insert --
kono
parents:
diff changeset
1065 ------------
kono
parents:
diff changeset
1066
kono
parents:
diff changeset
1067 procedure Insert
kono
parents:
diff changeset
1068 (Container : in out List;
kono
parents:
diff changeset
1069 Before : Cursor;
kono
parents:
diff changeset
1070 New_Item : Element_Type;
kono
parents:
diff changeset
1071 Position : out Cursor;
kono
parents:
diff changeset
1072 Count : Count_Type)
kono
parents:
diff changeset
1073 is
kono
parents:
diff changeset
1074 J : Count_Type;
kono
parents:
diff changeset
1075
kono
parents:
diff changeset
1076 begin
kono
parents:
diff changeset
1077 if Before.Node /= 0 then
kono
parents:
diff changeset
1078 pragma Assert (Vet (Container, Before), "bad cursor in Insert");
kono
parents:
diff changeset
1079 end if;
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 if Count = 0 then
kono
parents:
diff changeset
1082 Position := Before;
kono
parents:
diff changeset
1083 return;
kono
parents:
diff changeset
1084 end if;
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 if Container.Length > Container.Capacity - Count then
kono
parents:
diff changeset
1087 raise Constraint_Error with "new length exceeds capacity";
kono
parents:
diff changeset
1088 end if;
kono
parents:
diff changeset
1089
kono
parents:
diff changeset
1090 Allocate (Container, New_Item, New_Node => J);
kono
parents:
diff changeset
1091 Insert_Internal (Container, Before.Node, New_Node => J);
kono
parents:
diff changeset
1092 Position := (Node => J);
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 for Index in 2 .. Count loop
kono
parents:
diff changeset
1095 Allocate (Container, New_Item, New_Node => J);
kono
parents:
diff changeset
1096 Insert_Internal (Container, Before.Node, New_Node => J);
kono
parents:
diff changeset
1097 end loop;
kono
parents:
diff changeset
1098 end Insert;
kono
parents:
diff changeset
1099
kono
parents:
diff changeset
1100 procedure Insert
kono
parents:
diff changeset
1101 (Container : in out List;
kono
parents:
diff changeset
1102 Before : Cursor;
kono
parents:
diff changeset
1103 New_Item : Element_Type;
kono
parents:
diff changeset
1104 Position : out Cursor)
kono
parents:
diff changeset
1105 is
kono
parents:
diff changeset
1106 begin
kono
parents:
diff changeset
1107 Insert
kono
parents:
diff changeset
1108 (Container => Container,
kono
parents:
diff changeset
1109 Before => Before,
kono
parents:
diff changeset
1110 New_Item => New_Item,
kono
parents:
diff changeset
1111 Position => Position,
kono
parents:
diff changeset
1112 Count => 1);
kono
parents:
diff changeset
1113 end Insert;
kono
parents:
diff changeset
1114
kono
parents:
diff changeset
1115 procedure Insert
kono
parents:
diff changeset
1116 (Container : in out List;
kono
parents:
diff changeset
1117 Before : Cursor;
kono
parents:
diff changeset
1118 New_Item : Element_Type;
kono
parents:
diff changeset
1119 Count : Count_Type)
kono
parents:
diff changeset
1120 is
kono
parents:
diff changeset
1121 Position : Cursor;
kono
parents:
diff changeset
1122
kono
parents:
diff changeset
1123 begin
kono
parents:
diff changeset
1124 Insert (Container, Before, New_Item, Position, Count);
kono
parents:
diff changeset
1125 end Insert;
kono
parents:
diff changeset
1126
kono
parents:
diff changeset
1127 procedure Insert
kono
parents:
diff changeset
1128 (Container : in out List;
kono
parents:
diff changeset
1129 Before : Cursor;
kono
parents:
diff changeset
1130 New_Item : Element_Type)
kono
parents:
diff changeset
1131 is
kono
parents:
diff changeset
1132 Position : Cursor;
kono
parents:
diff changeset
1133
kono
parents:
diff changeset
1134 begin
kono
parents:
diff changeset
1135 Insert (Container, Before, New_Item, Position, 1);
kono
parents:
diff changeset
1136 end Insert;
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 ---------------------
kono
parents:
diff changeset
1139 -- Insert_Internal --
kono
parents:
diff changeset
1140 ---------------------
kono
parents:
diff changeset
1141
kono
parents:
diff changeset
1142 procedure Insert_Internal
kono
parents:
diff changeset
1143 (Container : in out List;
kono
parents:
diff changeset
1144 Before : Count_Type;
kono
parents:
diff changeset
1145 New_Node : Count_Type)
kono
parents:
diff changeset
1146 is
kono
parents:
diff changeset
1147 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
1148
kono
parents:
diff changeset
1149 begin
kono
parents:
diff changeset
1150 if Container.Length = 0 then
kono
parents:
diff changeset
1151 pragma Assert (Before = 0);
kono
parents:
diff changeset
1152 pragma Assert (Container.First = 0);
kono
parents:
diff changeset
1153 pragma Assert (Container.Last = 0);
kono
parents:
diff changeset
1154
kono
parents:
diff changeset
1155 Container.First := New_Node;
kono
parents:
diff changeset
1156 Container.Last := New_Node;
kono
parents:
diff changeset
1157
kono
parents:
diff changeset
1158 N (Container.First).Prev := 0;
kono
parents:
diff changeset
1159 N (Container.Last).Next := 0;
kono
parents:
diff changeset
1160
kono
parents:
diff changeset
1161 elsif Before = 0 then
kono
parents:
diff changeset
1162 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1163
kono
parents:
diff changeset
1164 N (Container.Last).Next := New_Node;
kono
parents:
diff changeset
1165 N (New_Node).Prev := Container.Last;
kono
parents:
diff changeset
1166
kono
parents:
diff changeset
1167 Container.Last := New_Node;
kono
parents:
diff changeset
1168 N (Container.Last).Next := 0;
kono
parents:
diff changeset
1169
kono
parents:
diff changeset
1170 elsif Before = Container.First then
kono
parents:
diff changeset
1171 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1172
kono
parents:
diff changeset
1173 N (Container.First).Prev := New_Node;
kono
parents:
diff changeset
1174 N (New_Node).Next := Container.First;
kono
parents:
diff changeset
1175
kono
parents:
diff changeset
1176 Container.First := New_Node;
kono
parents:
diff changeset
1177 N (Container.First).Prev := 0;
kono
parents:
diff changeset
1178
kono
parents:
diff changeset
1179 else
kono
parents:
diff changeset
1180 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1181 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1182
kono
parents:
diff changeset
1183 N (New_Node).Next := Before;
kono
parents:
diff changeset
1184 N (New_Node).Prev := N (Before).Prev;
kono
parents:
diff changeset
1185
kono
parents:
diff changeset
1186 N (N (Before).Prev).Next := New_Node;
kono
parents:
diff changeset
1187 N (Before).Prev := New_Node;
kono
parents:
diff changeset
1188 end if;
kono
parents:
diff changeset
1189
kono
parents:
diff changeset
1190 Container.Length := Container.Length + 1;
kono
parents:
diff changeset
1191 end Insert_Internal;
kono
parents:
diff changeset
1192
kono
parents:
diff changeset
1193 --------------
kono
parents:
diff changeset
1194 -- Is_Empty --
kono
parents:
diff changeset
1195 --------------
kono
parents:
diff changeset
1196
kono
parents:
diff changeset
1197 function Is_Empty (Container : List) return Boolean is
kono
parents:
diff changeset
1198 begin
kono
parents:
diff changeset
1199 return Length (Container) = 0;
kono
parents:
diff changeset
1200 end Is_Empty;
kono
parents:
diff changeset
1201
kono
parents:
diff changeset
1202 ----------
kono
parents:
diff changeset
1203 -- Last --
kono
parents:
diff changeset
1204 ----------
kono
parents:
diff changeset
1205
kono
parents:
diff changeset
1206 function Last (Container : List) return Cursor is
kono
parents:
diff changeset
1207 begin
kono
parents:
diff changeset
1208 if Container.Last = 0 then
kono
parents:
diff changeset
1209 return No_Element;
kono
parents:
diff changeset
1210 end if;
kono
parents:
diff changeset
1211
kono
parents:
diff changeset
1212 return (Node => Container.Last);
kono
parents:
diff changeset
1213 end Last;
kono
parents:
diff changeset
1214
kono
parents:
diff changeset
1215 ------------------
kono
parents:
diff changeset
1216 -- Last_Element --
kono
parents:
diff changeset
1217 ------------------
kono
parents:
diff changeset
1218
kono
parents:
diff changeset
1219 function Last_Element (Container : List) return Element_Type is
kono
parents:
diff changeset
1220 L : constant Count_Type := Container.Last;
kono
parents:
diff changeset
1221
kono
parents:
diff changeset
1222 begin
kono
parents:
diff changeset
1223 if L = 0 then
kono
parents:
diff changeset
1224 raise Constraint_Error with "list is empty";
kono
parents:
diff changeset
1225 else
kono
parents:
diff changeset
1226 return Container.Nodes (L).Element;
kono
parents:
diff changeset
1227 end if;
kono
parents:
diff changeset
1228 end Last_Element;
kono
parents:
diff changeset
1229
kono
parents:
diff changeset
1230 ------------
kono
parents:
diff changeset
1231 -- Length --
kono
parents:
diff changeset
1232 ------------
kono
parents:
diff changeset
1233
kono
parents:
diff changeset
1234 function Length (Container : List) return Count_Type is
kono
parents:
diff changeset
1235 begin
kono
parents:
diff changeset
1236 return Container.Length;
kono
parents:
diff changeset
1237 end Length;
kono
parents:
diff changeset
1238
kono
parents:
diff changeset
1239 ----------
kono
parents:
diff changeset
1240 -- Move --
kono
parents:
diff changeset
1241 ----------
kono
parents:
diff changeset
1242
kono
parents:
diff changeset
1243 procedure Move (Target : in out List; Source : in out List) is
kono
parents:
diff changeset
1244 N : Node_Array renames Source.Nodes;
kono
parents:
diff changeset
1245 X : Count_Type;
kono
parents:
diff changeset
1246
kono
parents:
diff changeset
1247 begin
kono
parents:
diff changeset
1248 if Target'Address = Source'Address then
kono
parents:
diff changeset
1249 return;
kono
parents:
diff changeset
1250 end if;
kono
parents:
diff changeset
1251
kono
parents:
diff changeset
1252 if Target.Capacity < Source.Length then
kono
parents:
diff changeset
1253 raise Constraint_Error with -- ???
kono
parents:
diff changeset
1254 "Source length exceeds Target capacity";
kono
parents:
diff changeset
1255 end if;
kono
parents:
diff changeset
1256
kono
parents:
diff changeset
1257 Clear (Target);
kono
parents:
diff changeset
1258
kono
parents:
diff changeset
1259 while Source.Length > 1 loop
kono
parents:
diff changeset
1260 pragma Assert (Source.First in 1 .. Source.Capacity);
kono
parents:
diff changeset
1261 pragma Assert (Source.Last /= Source.First);
kono
parents:
diff changeset
1262 pragma Assert (N (Source.First).Prev = 0);
kono
parents:
diff changeset
1263 pragma Assert (N (Source.Last).Next = 0);
kono
parents:
diff changeset
1264
kono
parents:
diff changeset
1265 -- Copy first element from Source to Target
kono
parents:
diff changeset
1266
kono
parents:
diff changeset
1267 X := Source.First;
kono
parents:
diff changeset
1268 Append (Target, N (X).Element); -- optimize away???
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 -- Unlink first node of Source
kono
parents:
diff changeset
1271
kono
parents:
diff changeset
1272 Source.First := N (X).Next;
kono
parents:
diff changeset
1273 N (Source.First).Prev := 0;
kono
parents:
diff changeset
1274
kono
parents:
diff changeset
1275 Source.Length := Source.Length - 1;
kono
parents:
diff changeset
1276
kono
parents:
diff changeset
1277 -- The representation invariants for Source have been restored. It is
kono
parents:
diff changeset
1278 -- now safe to free the unlinked node, without fear of corrupting the
kono
parents:
diff changeset
1279 -- active links of Source.
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 -- Note that the algorithm we use here models similar algorithms used
kono
parents:
diff changeset
1282 -- in the unbounded form of the doubly-linked list container. In that
kono
parents:
diff changeset
1283 -- case, Free is an instantation of Unchecked_Deallocation, which can
kono
parents:
diff changeset
1284 -- fail (because PE will be raised if controlled Finalize fails), so
kono
parents:
diff changeset
1285 -- we must defer the call until the last step. Here in the bounded
kono
parents:
diff changeset
1286 -- form, Free merely links the node we have just "deallocated" onto a
kono
parents:
diff changeset
1287 -- list of inactive nodes, so technically Free cannot fail. However,
kono
parents:
diff changeset
1288 -- for consistency, we handle Free the same way here as we do for the
kono
parents:
diff changeset
1289 -- unbounded form, with the pessimistic assumption that it can fail.
kono
parents:
diff changeset
1290
kono
parents:
diff changeset
1291 Free (Source, X);
kono
parents:
diff changeset
1292 end loop;
kono
parents:
diff changeset
1293
kono
parents:
diff changeset
1294 if Source.Length = 1 then
kono
parents:
diff changeset
1295 pragma Assert (Source.First in 1 .. Source.Capacity);
kono
parents:
diff changeset
1296 pragma Assert (Source.Last = Source.First);
kono
parents:
diff changeset
1297 pragma Assert (N (Source.First).Prev = 0);
kono
parents:
diff changeset
1298 pragma Assert (N (Source.Last).Next = 0);
kono
parents:
diff changeset
1299
kono
parents:
diff changeset
1300 -- Copy element from Source to Target
kono
parents:
diff changeset
1301
kono
parents:
diff changeset
1302 X := Source.First;
kono
parents:
diff changeset
1303 Append (Target, N (X).Element);
kono
parents:
diff changeset
1304
kono
parents:
diff changeset
1305 -- Unlink node of Source
kono
parents:
diff changeset
1306
kono
parents:
diff changeset
1307 Source.First := 0;
kono
parents:
diff changeset
1308 Source.Last := 0;
kono
parents:
diff changeset
1309 Source.Length := 0;
kono
parents:
diff changeset
1310
kono
parents:
diff changeset
1311 -- Return the unlinked node to the free store
kono
parents:
diff changeset
1312
kono
parents:
diff changeset
1313 Free (Source, X);
kono
parents:
diff changeset
1314 end if;
kono
parents:
diff changeset
1315 end Move;
kono
parents:
diff changeset
1316
kono
parents:
diff changeset
1317 ----------
kono
parents:
diff changeset
1318 -- Next --
kono
parents:
diff changeset
1319 ----------
kono
parents:
diff changeset
1320
kono
parents:
diff changeset
1321 procedure Next (Container : List; Position : in out Cursor) is
kono
parents:
diff changeset
1322 begin
kono
parents:
diff changeset
1323 Position := Next (Container, Position);
kono
parents:
diff changeset
1324 end Next;
kono
parents:
diff changeset
1325
kono
parents:
diff changeset
1326 function Next (Container : List; Position : Cursor) return Cursor is
kono
parents:
diff changeset
1327 begin
kono
parents:
diff changeset
1328 if Position.Node = 0 then
kono
parents:
diff changeset
1329 return No_Element;
kono
parents:
diff changeset
1330 end if;
kono
parents:
diff changeset
1331
kono
parents:
diff changeset
1332 if not Has_Element (Container, Position) then
kono
parents:
diff changeset
1333 raise Program_Error with "Position cursor has no element";
kono
parents:
diff changeset
1334 end if;
kono
parents:
diff changeset
1335
kono
parents:
diff changeset
1336 return (Node => Container.Nodes (Position.Node).Next);
kono
parents:
diff changeset
1337 end Next;
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 -------------
kono
parents:
diff changeset
1340 -- Prepend --
kono
parents:
diff changeset
1341 -------------
kono
parents:
diff changeset
1342
kono
parents:
diff changeset
1343 procedure Prepend (Container : in out List; New_Item : Element_Type) is
kono
parents:
diff changeset
1344 begin
kono
parents:
diff changeset
1345 Insert (Container, First (Container), New_Item, 1);
kono
parents:
diff changeset
1346 end Prepend;
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 procedure Prepend
kono
parents:
diff changeset
1349 (Container : in out List;
kono
parents:
diff changeset
1350 New_Item : Element_Type;
kono
parents:
diff changeset
1351 Count : Count_Type)
kono
parents:
diff changeset
1352 is
kono
parents:
diff changeset
1353 begin
kono
parents:
diff changeset
1354 Insert (Container, First (Container), New_Item, Count);
kono
parents:
diff changeset
1355 end Prepend;
kono
parents:
diff changeset
1356
kono
parents:
diff changeset
1357 --------------
kono
parents:
diff changeset
1358 -- Previous --
kono
parents:
diff changeset
1359 --------------
kono
parents:
diff changeset
1360
kono
parents:
diff changeset
1361 procedure Previous (Container : List; Position : in out Cursor) is
kono
parents:
diff changeset
1362 begin
kono
parents:
diff changeset
1363 Position := Previous (Container, Position);
kono
parents:
diff changeset
1364 end Previous;
kono
parents:
diff changeset
1365
kono
parents:
diff changeset
1366 function Previous (Container : List; Position : Cursor) return Cursor is
kono
parents:
diff changeset
1367 begin
kono
parents:
diff changeset
1368 if Position.Node = 0 then
kono
parents:
diff changeset
1369 return No_Element;
kono
parents:
diff changeset
1370 end if;
kono
parents:
diff changeset
1371
kono
parents:
diff changeset
1372 if not Has_Element (Container, Position) then
kono
parents:
diff changeset
1373 raise Program_Error with "Position cursor has no element";
kono
parents:
diff changeset
1374 end if;
kono
parents:
diff changeset
1375
kono
parents:
diff changeset
1376 return (Node => Container.Nodes (Position.Node).Prev);
kono
parents:
diff changeset
1377 end Previous;
kono
parents:
diff changeset
1378
kono
parents:
diff changeset
1379 ---------------------
kono
parents:
diff changeset
1380 -- Replace_Element --
kono
parents:
diff changeset
1381 ---------------------
kono
parents:
diff changeset
1382
kono
parents:
diff changeset
1383 procedure Replace_Element
kono
parents:
diff changeset
1384 (Container : in out List;
kono
parents:
diff changeset
1385 Position : Cursor;
kono
parents:
diff changeset
1386 New_Item : Element_Type)
kono
parents:
diff changeset
1387 is
kono
parents:
diff changeset
1388 begin
kono
parents:
diff changeset
1389 if not Has_Element (Container, Position) then
kono
parents:
diff changeset
1390 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
1391 end if;
kono
parents:
diff changeset
1392
kono
parents:
diff changeset
1393 pragma Assert
kono
parents:
diff changeset
1394 (Vet (Container, Position), "bad cursor in Replace_Element");
kono
parents:
diff changeset
1395
kono
parents:
diff changeset
1396 Container.Nodes (Position.Node).Element := New_Item;
kono
parents:
diff changeset
1397 end Replace_Element;
kono
parents:
diff changeset
1398
kono
parents:
diff changeset
1399 ----------------------
kono
parents:
diff changeset
1400 -- Reverse_Elements --
kono
parents:
diff changeset
1401 ----------------------
kono
parents:
diff changeset
1402
kono
parents:
diff changeset
1403 procedure Reverse_Elements (Container : in out List) is
kono
parents:
diff changeset
1404 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
1405 I : Count_Type := Container.First;
kono
parents:
diff changeset
1406 J : Count_Type := Container.Last;
kono
parents:
diff changeset
1407
kono
parents:
diff changeset
1408 procedure Swap (L : Count_Type; R : Count_Type);
kono
parents:
diff changeset
1409
kono
parents:
diff changeset
1410 ----------
kono
parents:
diff changeset
1411 -- Swap --
kono
parents:
diff changeset
1412 ----------
kono
parents:
diff changeset
1413
kono
parents:
diff changeset
1414 procedure Swap (L : Count_Type; R : Count_Type) is
kono
parents:
diff changeset
1415 LN : constant Count_Type := N (L).Next;
kono
parents:
diff changeset
1416 LP : constant Count_Type := N (L).Prev;
kono
parents:
diff changeset
1417
kono
parents:
diff changeset
1418 RN : constant Count_Type := N (R).Next;
kono
parents:
diff changeset
1419 RP : constant Count_Type := N (R).Prev;
kono
parents:
diff changeset
1420
kono
parents:
diff changeset
1421 begin
kono
parents:
diff changeset
1422 if LP /= 0 then
kono
parents:
diff changeset
1423 N (LP).Next := R;
kono
parents:
diff changeset
1424 end if;
kono
parents:
diff changeset
1425
kono
parents:
diff changeset
1426 if RN /= 0 then
kono
parents:
diff changeset
1427 N (RN).Prev := L;
kono
parents:
diff changeset
1428 end if;
kono
parents:
diff changeset
1429
kono
parents:
diff changeset
1430 N (L).Next := RN;
kono
parents:
diff changeset
1431 N (R).Prev := LP;
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 if LN = R then
kono
parents:
diff changeset
1434 pragma Assert (RP = L);
kono
parents:
diff changeset
1435
kono
parents:
diff changeset
1436 N (L).Prev := R;
kono
parents:
diff changeset
1437 N (R).Next := L;
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 else
kono
parents:
diff changeset
1440 N (L).Prev := RP;
kono
parents:
diff changeset
1441 N (RP).Next := L;
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 N (R).Next := LN;
kono
parents:
diff changeset
1444 N (LN).Prev := R;
kono
parents:
diff changeset
1445 end if;
kono
parents:
diff changeset
1446 end Swap;
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 -- Start of processing for Reverse_Elements
kono
parents:
diff changeset
1449
kono
parents:
diff changeset
1450 begin
kono
parents:
diff changeset
1451 if Container.Length <= 1 then
kono
parents:
diff changeset
1452 return;
kono
parents:
diff changeset
1453 end if;
kono
parents:
diff changeset
1454
kono
parents:
diff changeset
1455 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1456 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1457
kono
parents:
diff changeset
1458 Container.First := J;
kono
parents:
diff changeset
1459 Container.Last := I;
kono
parents:
diff changeset
1460 loop
kono
parents:
diff changeset
1461 Swap (L => I, R => J);
kono
parents:
diff changeset
1462
kono
parents:
diff changeset
1463 J := N (J).Next;
kono
parents:
diff changeset
1464 exit when I = J;
kono
parents:
diff changeset
1465
kono
parents:
diff changeset
1466 I := N (I).Prev;
kono
parents:
diff changeset
1467 exit when I = J;
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 Swap (L => J, R => I);
kono
parents:
diff changeset
1470
kono
parents:
diff changeset
1471 I := N (I).Next;
kono
parents:
diff changeset
1472 exit when I = J;
kono
parents:
diff changeset
1473
kono
parents:
diff changeset
1474 J := N (J).Prev;
kono
parents:
diff changeset
1475 exit when I = J;
kono
parents:
diff changeset
1476 end loop;
kono
parents:
diff changeset
1477
kono
parents:
diff changeset
1478 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1479 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1480 end Reverse_Elements;
kono
parents:
diff changeset
1481
kono
parents:
diff changeset
1482 ------------------
kono
parents:
diff changeset
1483 -- Reverse_Find --
kono
parents:
diff changeset
1484 ------------------
kono
parents:
diff changeset
1485
kono
parents:
diff changeset
1486 function Reverse_Find
kono
parents:
diff changeset
1487 (Container : List;
kono
parents:
diff changeset
1488 Item : Element_Type;
kono
parents:
diff changeset
1489 Position : Cursor := No_Element) return Cursor
kono
parents:
diff changeset
1490 is
kono
parents:
diff changeset
1491 CFirst : Count_Type := Position.Node;
kono
parents:
diff changeset
1492
kono
parents:
diff changeset
1493 begin
kono
parents:
diff changeset
1494 if CFirst = 0 then
kono
parents:
diff changeset
1495 CFirst := Container.Last;
kono
parents:
diff changeset
1496 end if;
kono
parents:
diff changeset
1497
kono
parents:
diff changeset
1498 if Container.Length = 0 then
kono
parents:
diff changeset
1499 return No_Element;
kono
parents:
diff changeset
1500
kono
parents:
diff changeset
1501 else
kono
parents:
diff changeset
1502 while CFirst /= 0 loop
kono
parents:
diff changeset
1503 if Container.Nodes (CFirst).Element = Item then
kono
parents:
diff changeset
1504 return (Node => CFirst);
kono
parents:
diff changeset
1505 else
kono
parents:
diff changeset
1506 CFirst := Container.Nodes (CFirst).Prev;
kono
parents:
diff changeset
1507 end if;
kono
parents:
diff changeset
1508 end loop;
kono
parents:
diff changeset
1509
kono
parents:
diff changeset
1510 return No_Element;
kono
parents:
diff changeset
1511 end if;
kono
parents:
diff changeset
1512 end Reverse_Find;
kono
parents:
diff changeset
1513
kono
parents:
diff changeset
1514 ------------
kono
parents:
diff changeset
1515 -- Splice --
kono
parents:
diff changeset
1516 ------------
kono
parents:
diff changeset
1517
kono
parents:
diff changeset
1518 procedure Splice
kono
parents:
diff changeset
1519 (Target : in out List;
kono
parents:
diff changeset
1520 Before : Cursor;
kono
parents:
diff changeset
1521 Source : in out List)
kono
parents:
diff changeset
1522 is
kono
parents:
diff changeset
1523 SN : Node_Array renames Source.Nodes;
kono
parents:
diff changeset
1524
kono
parents:
diff changeset
1525 begin
kono
parents:
diff changeset
1526 if Target'Address = Source'Address then
kono
parents:
diff changeset
1527 raise Program_Error with "Target and Source denote same container";
kono
parents:
diff changeset
1528 end if;
kono
parents:
diff changeset
1529
kono
parents:
diff changeset
1530 if Before.Node /= 0 then
kono
parents:
diff changeset
1531 pragma Assert (Vet (Target, Before), "bad cursor in Splice");
kono
parents:
diff changeset
1532 end if;
kono
parents:
diff changeset
1533
kono
parents:
diff changeset
1534 pragma Assert (SN (Source.First).Prev = 0);
kono
parents:
diff changeset
1535 pragma Assert (SN (Source.Last).Next = 0);
kono
parents:
diff changeset
1536
kono
parents:
diff changeset
1537 if Target.Length > Count_Type'Base'Last - Source.Length then
kono
parents:
diff changeset
1538 raise Constraint_Error with "new length exceeds maximum";
kono
parents:
diff changeset
1539 end if;
kono
parents:
diff changeset
1540
kono
parents:
diff changeset
1541 if Target.Length + Source.Length > Target.Capacity then
kono
parents:
diff changeset
1542 raise Constraint_Error;
kono
parents:
diff changeset
1543 end if;
kono
parents:
diff changeset
1544
kono
parents:
diff changeset
1545 loop
kono
parents:
diff changeset
1546 Insert (Target, Before, SN (Source.Last).Element);
kono
parents:
diff changeset
1547 Delete_Last (Source);
kono
parents:
diff changeset
1548 exit when Is_Empty (Source);
kono
parents:
diff changeset
1549 end loop;
kono
parents:
diff changeset
1550 end Splice;
kono
parents:
diff changeset
1551
kono
parents:
diff changeset
1552 procedure Splice
kono
parents:
diff changeset
1553 (Target : in out List;
kono
parents:
diff changeset
1554 Before : Cursor;
kono
parents:
diff changeset
1555 Source : in out List;
kono
parents:
diff changeset
1556 Position : in out Cursor)
kono
parents:
diff changeset
1557 is
kono
parents:
diff changeset
1558 Target_Position : Cursor;
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560 begin
kono
parents:
diff changeset
1561 if Target'Address = Source'Address then
kono
parents:
diff changeset
1562 raise Program_Error with "Target and Source denote same container";
kono
parents:
diff changeset
1563 end if;
kono
parents:
diff changeset
1564
kono
parents:
diff changeset
1565 if Position.Node = 0 then
kono
parents:
diff changeset
1566 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
1567 end if;
kono
parents:
diff changeset
1568
kono
parents:
diff changeset
1569 pragma Assert (Vet (Source, Position), "bad Position cursor in Splice");
kono
parents:
diff changeset
1570
kono
parents:
diff changeset
1571 if Target.Length >= Target.Capacity then
kono
parents:
diff changeset
1572 raise Constraint_Error;
kono
parents:
diff changeset
1573 end if;
kono
parents:
diff changeset
1574
kono
parents:
diff changeset
1575 Insert
kono
parents:
diff changeset
1576 (Container => Target,
kono
parents:
diff changeset
1577 Before => Before,
kono
parents:
diff changeset
1578 New_Item => Source.Nodes (Position.Node).Element,
kono
parents:
diff changeset
1579 Position => Target_Position);
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 Delete (Source, Position);
kono
parents:
diff changeset
1582 Position := Target_Position;
kono
parents:
diff changeset
1583 end Splice;
kono
parents:
diff changeset
1584
kono
parents:
diff changeset
1585 procedure Splice
kono
parents:
diff changeset
1586 (Container : in out List;
kono
parents:
diff changeset
1587 Before : Cursor;
kono
parents:
diff changeset
1588 Position : Cursor)
kono
parents:
diff changeset
1589 is
kono
parents:
diff changeset
1590 N : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
1591
kono
parents:
diff changeset
1592 begin
kono
parents:
diff changeset
1593 if Before.Node /= 0 then
kono
parents:
diff changeset
1594 pragma Assert
kono
parents:
diff changeset
1595 (Vet (Container, Before), "bad Before cursor in Splice");
kono
parents:
diff changeset
1596 end if;
kono
parents:
diff changeset
1597
kono
parents:
diff changeset
1598 if Position.Node = 0 then
kono
parents:
diff changeset
1599 raise Constraint_Error with "Position cursor has no element";
kono
parents:
diff changeset
1600 end if;
kono
parents:
diff changeset
1601
kono
parents:
diff changeset
1602 pragma Assert
kono
parents:
diff changeset
1603 (Vet (Container, Position), "bad Position cursor in Splice");
kono
parents:
diff changeset
1604
kono
parents:
diff changeset
1605 if Position.Node = Before.Node
kono
parents:
diff changeset
1606 or else N (Position.Node).Next = Before.Node
kono
parents:
diff changeset
1607 then
kono
parents:
diff changeset
1608 return;
kono
parents:
diff changeset
1609 end if;
kono
parents:
diff changeset
1610
kono
parents:
diff changeset
1611 pragma Assert (Container.Length >= 2);
kono
parents:
diff changeset
1612
kono
parents:
diff changeset
1613 if Before.Node = 0 then
kono
parents:
diff changeset
1614 pragma Assert (Position.Node /= Container.Last);
kono
parents:
diff changeset
1615
kono
parents:
diff changeset
1616 if Position.Node = Container.First then
kono
parents:
diff changeset
1617 Container.First := N (Position.Node).Next;
kono
parents:
diff changeset
1618 N (Container.First).Prev := 0;
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 else
kono
parents:
diff changeset
1621 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
kono
parents:
diff changeset
1622 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
kono
parents:
diff changeset
1623 end if;
kono
parents:
diff changeset
1624
kono
parents:
diff changeset
1625 N (Container.Last).Next := Position.Node;
kono
parents:
diff changeset
1626 N (Position.Node).Prev := Container.Last;
kono
parents:
diff changeset
1627
kono
parents:
diff changeset
1628 Container.Last := Position.Node;
kono
parents:
diff changeset
1629 N (Container.Last).Next := 0;
kono
parents:
diff changeset
1630
kono
parents:
diff changeset
1631 return;
kono
parents:
diff changeset
1632 end if;
kono
parents:
diff changeset
1633
kono
parents:
diff changeset
1634 if Before.Node = Container.First then
kono
parents:
diff changeset
1635 pragma Assert (Position.Node /= Container.First);
kono
parents:
diff changeset
1636
kono
parents:
diff changeset
1637 if Position.Node = Container.Last then
kono
parents:
diff changeset
1638 Container.Last := N (Position.Node).Prev;
kono
parents:
diff changeset
1639 N (Container.Last).Next := 0;
kono
parents:
diff changeset
1640
kono
parents:
diff changeset
1641 else
kono
parents:
diff changeset
1642 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
kono
parents:
diff changeset
1643 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
kono
parents:
diff changeset
1644 end if;
kono
parents:
diff changeset
1645
kono
parents:
diff changeset
1646 N (Container.First).Prev := Position.Node;
kono
parents:
diff changeset
1647 N (Position.Node).Next := Container.First;
kono
parents:
diff changeset
1648
kono
parents:
diff changeset
1649 Container.First := Position.Node;
kono
parents:
diff changeset
1650 N (Container.First).Prev := 0;
kono
parents:
diff changeset
1651
kono
parents:
diff changeset
1652 return;
kono
parents:
diff changeset
1653 end if;
kono
parents:
diff changeset
1654
kono
parents:
diff changeset
1655 if Position.Node = Container.First then
kono
parents:
diff changeset
1656 Container.First := N (Position.Node).Next;
kono
parents:
diff changeset
1657 N (Container.First).Prev := 0;
kono
parents:
diff changeset
1658
kono
parents:
diff changeset
1659 elsif Position.Node = Container.Last then
kono
parents:
diff changeset
1660 Container.Last := N (Position.Node).Prev;
kono
parents:
diff changeset
1661 N (Container.Last).Next := 0;
kono
parents:
diff changeset
1662
kono
parents:
diff changeset
1663 else
kono
parents:
diff changeset
1664 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
kono
parents:
diff changeset
1665 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
kono
parents:
diff changeset
1666 end if;
kono
parents:
diff changeset
1667
kono
parents:
diff changeset
1668 N (N (Before.Node).Prev).Next := Position.Node;
kono
parents:
diff changeset
1669 N (Position.Node).Prev := N (Before.Node).Prev;
kono
parents:
diff changeset
1670
kono
parents:
diff changeset
1671 N (Before.Node).Prev := Position.Node;
kono
parents:
diff changeset
1672 N (Position.Node).Next := Before.Node;
kono
parents:
diff changeset
1673
kono
parents:
diff changeset
1674 pragma Assert (N (Container.First).Prev = 0);
kono
parents:
diff changeset
1675 pragma Assert (N (Container.Last).Next = 0);
kono
parents:
diff changeset
1676 end Splice;
kono
parents:
diff changeset
1677
kono
parents:
diff changeset
1678 ----------
kono
parents:
diff changeset
1679 -- Swap --
kono
parents:
diff changeset
1680 ----------
kono
parents:
diff changeset
1681
kono
parents:
diff changeset
1682 procedure Swap
kono
parents:
diff changeset
1683 (Container : in out List;
kono
parents:
diff changeset
1684 I : Cursor;
kono
parents:
diff changeset
1685 J : Cursor)
kono
parents:
diff changeset
1686 is
kono
parents:
diff changeset
1687 begin
kono
parents:
diff changeset
1688 if I.Node = 0 then
kono
parents:
diff changeset
1689 raise Constraint_Error with "I cursor has no element";
kono
parents:
diff changeset
1690 end if;
kono
parents:
diff changeset
1691
kono
parents:
diff changeset
1692 if J.Node = 0 then
kono
parents:
diff changeset
1693 raise Constraint_Error with "J cursor has no element";
kono
parents:
diff changeset
1694 end if;
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 if I.Node = J.Node then
kono
parents:
diff changeset
1697 return;
kono
parents:
diff changeset
1698 end if;
kono
parents:
diff changeset
1699
kono
parents:
diff changeset
1700 pragma Assert (Vet (Container, I), "bad I cursor in Swap");
kono
parents:
diff changeset
1701 pragma Assert (Vet (Container, J), "bad J cursor in Swap");
kono
parents:
diff changeset
1702
kono
parents:
diff changeset
1703 declare
kono
parents:
diff changeset
1704 NN : Node_Array renames Container.Nodes;
kono
parents:
diff changeset
1705 NI : Node_Type renames NN (I.Node);
kono
parents:
diff changeset
1706 NJ : Node_Type renames NN (J.Node);
kono
parents:
diff changeset
1707
kono
parents:
diff changeset
1708 EI_Copy : constant Element_Type := NI.Element;
kono
parents:
diff changeset
1709
kono
parents:
diff changeset
1710 begin
kono
parents:
diff changeset
1711 NI.Element := NJ.Element;
kono
parents:
diff changeset
1712 NJ.Element := EI_Copy;
kono
parents:
diff changeset
1713 end;
kono
parents:
diff changeset
1714 end Swap;
kono
parents:
diff changeset
1715
kono
parents:
diff changeset
1716 ----------------
kono
parents:
diff changeset
1717 -- Swap_Links --
kono
parents:
diff changeset
1718 ----------------
kono
parents:
diff changeset
1719
kono
parents:
diff changeset
1720 procedure Swap_Links
kono
parents:
diff changeset
1721 (Container : in out List;
kono
parents:
diff changeset
1722 I : Cursor;
kono
parents:
diff changeset
1723 J : Cursor)
kono
parents:
diff changeset
1724 is
kono
parents:
diff changeset
1725 I_Next : Cursor;
kono
parents:
diff changeset
1726 J_Next : Cursor;
kono
parents:
diff changeset
1727
kono
parents:
diff changeset
1728 begin
kono
parents:
diff changeset
1729 if I.Node = 0 then
kono
parents:
diff changeset
1730 raise Constraint_Error with "I cursor has no element";
kono
parents:
diff changeset
1731 end if;
kono
parents:
diff changeset
1732
kono
parents:
diff changeset
1733 if J.Node = 0 then
kono
parents:
diff changeset
1734 raise Constraint_Error with "J cursor has no element";
kono
parents:
diff changeset
1735 end if;
kono
parents:
diff changeset
1736
kono
parents:
diff changeset
1737 if I.Node = J.Node then
kono
parents:
diff changeset
1738 return;
kono
parents:
diff changeset
1739 end if;
kono
parents:
diff changeset
1740
kono
parents:
diff changeset
1741 pragma Assert (Vet (Container, I), "bad I cursor in Swap_Links");
kono
parents:
diff changeset
1742 pragma Assert (Vet (Container, J), "bad J cursor in Swap_Links");
kono
parents:
diff changeset
1743
kono
parents:
diff changeset
1744 I_Next := Next (Container, I);
kono
parents:
diff changeset
1745
kono
parents:
diff changeset
1746 if I_Next = J then
kono
parents:
diff changeset
1747 Splice (Container, Before => I, Position => J);
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 else
kono
parents:
diff changeset
1750 J_Next := Next (Container, J);
kono
parents:
diff changeset
1751
kono
parents:
diff changeset
1752 if J_Next = I then
kono
parents:
diff changeset
1753 Splice (Container, Before => J, Position => I);
kono
parents:
diff changeset
1754
kono
parents:
diff changeset
1755 else
kono
parents:
diff changeset
1756 pragma Assert (Container.Length >= 3);
kono
parents:
diff changeset
1757 Splice (Container, Before => I_Next, Position => J);
kono
parents:
diff changeset
1758 Splice (Container, Before => J_Next, Position => I);
kono
parents:
diff changeset
1759 end if;
kono
parents:
diff changeset
1760 end if;
kono
parents:
diff changeset
1761 end Swap_Links;
kono
parents:
diff changeset
1762
kono
parents:
diff changeset
1763 ---------
kono
parents:
diff changeset
1764 -- Vet --
kono
parents:
diff changeset
1765 ---------
kono
parents:
diff changeset
1766
kono
parents:
diff changeset
1767 function Vet (L : List; Position : Cursor) return Boolean is
kono
parents:
diff changeset
1768 N : Node_Array renames L.Nodes;
kono
parents:
diff changeset
1769
kono
parents:
diff changeset
1770 begin
kono
parents:
diff changeset
1771 if L.Length = 0 then
kono
parents:
diff changeset
1772 return False;
kono
parents:
diff changeset
1773 end if;
kono
parents:
diff changeset
1774
kono
parents:
diff changeset
1775 if L.First = 0 then
kono
parents:
diff changeset
1776 return False;
kono
parents:
diff changeset
1777 end if;
kono
parents:
diff changeset
1778
kono
parents:
diff changeset
1779 if L.Last = 0 then
kono
parents:
diff changeset
1780 return False;
kono
parents:
diff changeset
1781 end if;
kono
parents:
diff changeset
1782
kono
parents:
diff changeset
1783 if Position.Node > L.Capacity then
kono
parents:
diff changeset
1784 return False;
kono
parents:
diff changeset
1785 end if;
kono
parents:
diff changeset
1786
kono
parents:
diff changeset
1787 if N (Position.Node).Prev < 0
kono
parents:
diff changeset
1788 or else N (Position.Node).Prev > L.Capacity
kono
parents:
diff changeset
1789 then
kono
parents:
diff changeset
1790 return False;
kono
parents:
diff changeset
1791 end if;
kono
parents:
diff changeset
1792
kono
parents:
diff changeset
1793 if N (Position.Node).Next > L.Capacity then
kono
parents:
diff changeset
1794 return False;
kono
parents:
diff changeset
1795 end if;
kono
parents:
diff changeset
1796
kono
parents:
diff changeset
1797 if N (L.First).Prev /= 0 then
kono
parents:
diff changeset
1798 return False;
kono
parents:
diff changeset
1799 end if;
kono
parents:
diff changeset
1800
kono
parents:
diff changeset
1801 if N (L.Last).Next /= 0 then
kono
parents:
diff changeset
1802 return False;
kono
parents:
diff changeset
1803 end if;
kono
parents:
diff changeset
1804
kono
parents:
diff changeset
1805 if N (Position.Node).Prev = 0 and then Position.Node /= L.First then
kono
parents:
diff changeset
1806 return False;
kono
parents:
diff changeset
1807 end if;
kono
parents:
diff changeset
1808
kono
parents:
diff changeset
1809 if N (Position.Node).Next = 0 and then Position.Node /= L.Last then
kono
parents:
diff changeset
1810 return False;
kono
parents:
diff changeset
1811 end if;
kono
parents:
diff changeset
1812
kono
parents:
diff changeset
1813 if L.Length = 1 then
kono
parents:
diff changeset
1814 return L.First = L.Last;
kono
parents:
diff changeset
1815 end if;
kono
parents:
diff changeset
1816
kono
parents:
diff changeset
1817 if L.First = L.Last then
kono
parents:
diff changeset
1818 return False;
kono
parents:
diff changeset
1819 end if;
kono
parents:
diff changeset
1820
kono
parents:
diff changeset
1821 if N (L.First).Next = 0 then
kono
parents:
diff changeset
1822 return False;
kono
parents:
diff changeset
1823 end if;
kono
parents:
diff changeset
1824
kono
parents:
diff changeset
1825 if N (L.Last).Prev = 0 then
kono
parents:
diff changeset
1826 return False;
kono
parents:
diff changeset
1827 end if;
kono
parents:
diff changeset
1828
kono
parents:
diff changeset
1829 if N (N (L.First).Next).Prev /= L.First then
kono
parents:
diff changeset
1830 return False;
kono
parents:
diff changeset
1831 end if;
kono
parents:
diff changeset
1832
kono
parents:
diff changeset
1833 if N (N (L.Last).Prev).Next /= L.Last then
kono
parents:
diff changeset
1834 return False;
kono
parents:
diff changeset
1835 end if;
kono
parents:
diff changeset
1836
kono
parents:
diff changeset
1837 if L.Length = 2 then
kono
parents:
diff changeset
1838 if N (L.First).Next /= L.Last then
kono
parents:
diff changeset
1839 return False;
kono
parents:
diff changeset
1840 end if;
kono
parents:
diff changeset
1841
kono
parents:
diff changeset
1842 if N (L.Last).Prev /= L.First then
kono
parents:
diff changeset
1843 return False;
kono
parents:
diff changeset
1844 end if;
kono
parents:
diff changeset
1845
kono
parents:
diff changeset
1846 return True;
kono
parents:
diff changeset
1847 end if;
kono
parents:
diff changeset
1848
kono
parents:
diff changeset
1849 if N (L.First).Next = L.Last then
kono
parents:
diff changeset
1850 return False;
kono
parents:
diff changeset
1851 end if;
kono
parents:
diff changeset
1852
kono
parents:
diff changeset
1853 if N (L.Last).Prev = L.First then
kono
parents:
diff changeset
1854 return False;
kono
parents:
diff changeset
1855 end if;
kono
parents:
diff changeset
1856
kono
parents:
diff changeset
1857 if Position.Node = L.First then
kono
parents:
diff changeset
1858 return True;
kono
parents:
diff changeset
1859 end if;
kono
parents:
diff changeset
1860
kono
parents:
diff changeset
1861 if Position.Node = L.Last then
kono
parents:
diff changeset
1862 return True;
kono
parents:
diff changeset
1863 end if;
kono
parents:
diff changeset
1864
kono
parents:
diff changeset
1865 if N (Position.Node).Next = 0 then
kono
parents:
diff changeset
1866 return False;
kono
parents:
diff changeset
1867 end if;
kono
parents:
diff changeset
1868
kono
parents:
diff changeset
1869 if N (Position.Node).Prev = 0 then
kono
parents:
diff changeset
1870 return False;
kono
parents:
diff changeset
1871 end if;
kono
parents:
diff changeset
1872
kono
parents:
diff changeset
1873 if N (N (Position.Node).Next).Prev /= Position.Node then
kono
parents:
diff changeset
1874 return False;
kono
parents:
diff changeset
1875 end if;
kono
parents:
diff changeset
1876
kono
parents:
diff changeset
1877 if N (N (Position.Node).Prev).Next /= Position.Node then
kono
parents:
diff changeset
1878 return False;
kono
parents:
diff changeset
1879 end if;
kono
parents:
diff changeset
1880
kono
parents:
diff changeset
1881 if L.Length = 3 then
kono
parents:
diff changeset
1882 if N (L.First).Next /= Position.Node then
kono
parents:
diff changeset
1883 return False;
kono
parents:
diff changeset
1884 end if;
kono
parents:
diff changeset
1885
kono
parents:
diff changeset
1886 if N (L.Last).Prev /= Position.Node then
kono
parents:
diff changeset
1887 return False;
kono
parents:
diff changeset
1888 end if;
kono
parents:
diff changeset
1889 end if;
kono
parents:
diff changeset
1890
kono
parents:
diff changeset
1891 return True;
kono
parents:
diff changeset
1892 end Vet;
kono
parents:
diff changeset
1893
kono
parents:
diff changeset
1894 end Ada.Containers.Formal_Doubly_Linked_Lists;