1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . --
6 -- R E S R I C T E D _ D O U B L Y _ L I N K E D _ L I S T S --
10 -- Copyright (C) 2004-2007, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
21 -- Boston, MA 02110-1301, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- This unit was originally developed by Matthew J Heaney. --
31 ------------------------------------------------------------------------------
33 with System
; use type System
.Address
;
35 package body Ada
.Containers
.Restricted_Doubly_Linked_Lists
is
37 -----------------------
38 -- Local Subprograms --
39 -----------------------
42 (Container
: in out List
'Class;
43 New_Item
: Element_Type
;
44 New_Node
: out Count_Type
);
47 (Container
: in out List
'Class;
50 procedure Insert_Internal
51 (Container
: in out List
'Class;
53 New_Node
: Count_Type
);
55 function Vet
(Position
: Cursor
) return Boolean;
61 function "=" (Left
, Right
: List
) return Boolean is
62 LN
: Node_Array
renames Left
.Nodes
;
63 RN
: Node_Array
renames Right
.Nodes
;
65 LI
: Count_Type
:= Left
.First
;
66 RI
: Count_Type
:= Right
.First
;
69 if Left
'Address = Right
'Address then
73 if Left
.Length
/= Right
.Length
then
77 for J
in 1 .. Left
.Length
loop
78 if LN
(LI
).Element
/= RN
(RI
).Element
then
94 (Container
: in out List
'Class;
95 New_Item
: Element_Type
;
96 New_Node
: out Count_Type
)
98 N
: Node_Array
renames Container
.Nodes
;
101 if Container
.Free
>= 0 then
102 New_Node
:= Container
.Free
;
103 N
(New_Node
).Element
:= New_Item
;
104 Container
.Free
:= N
(New_Node
).Next
;
107 New_Node
:= abs Container
.Free
;
108 N
(New_Node
).Element
:= New_Item
;
109 Container
.Free
:= Container
.Free
- 1;
118 (Container
: in out List
;
119 New_Item
: Element_Type
;
120 Count
: Count_Type
:= 1)
123 Insert
(Container
, No_Element
, New_Item
, Count
);
130 procedure Assign
(Target
: in out List
; Source
: List
) is
132 if Target
'Address = Source
'Address then
136 if Target
.Capacity
< Source
.Length
then
137 raise Constraint_Error
; -- ???
143 N
: Node_Array
renames Source
.Nodes
;
144 J
: Count_Type
:= Source
.First
;
148 Append
(Target
, N
(J
).Element
);
158 procedure Clear
(Container
: in out List
) is
159 N
: Node_Array
renames Container
.Nodes
;
163 if Container
.Length
= 0 then
164 pragma Assert
(Container
.First
= 0);
165 pragma Assert
(Container
.Last
= 0);
166 -- pragma Assert (Container.Busy = 0);
167 -- pragma Assert (Container.Lock = 0);
171 pragma Assert
(Container
.First
>= 1);
172 pragma Assert
(Container
.Last
>= 1);
173 pragma Assert
(N
(Container
.First
).Prev
= 0);
174 pragma Assert
(N
(Container
.Last
).Next
= 0);
176 -- if Container.Busy > 0 then
177 -- raise Program_Error;
180 while Container
.Length
> 1 loop
181 X
:= Container
.First
;
183 Container
.First
:= N
(X
).Next
;
184 N
(Container
.First
).Prev
:= 0;
186 Container
.Length
:= Container
.Length
- 1;
191 X
:= Container
.First
;
193 Container
.First
:= 0;
195 Container
.Length
:= 0;
206 Item
: Element_Type
) return Boolean
209 return Find
(Container
, Item
) /= No_Element
;
217 (Container
: in out List
;
218 Position
: in out Cursor
;
219 Count
: Count_Type
:= 1)
221 N
: Node_Array
renames Container
.Nodes
;
225 if Position
.Node
= 0 then
226 raise Constraint_Error
;
229 if Position
.Container
/= Container
'Unrestricted_Access then
233 pragma Assert
(Vet
(Position
), "bad cursor in Delete");
235 if Position
.Node
= Container
.First
then
236 Delete_First
(Container
, Count
);
237 Position
:= No_Element
;
242 Position
:= No_Element
;
246 -- if Container.Busy > 0 then
247 -- raise Program_Error;
250 pragma Assert
(Container
.First
>= 1);
251 pragma Assert
(Container
.Last
>= 1);
252 pragma Assert
(N
(Container
.First
).Prev
= 0);
253 pragma Assert
(N
(Container
.Last
).Next
= 0);
255 for Index
in 1 .. Count
loop
256 pragma Assert
(Container
.Length
>= 2);
259 Container
.Length
:= Container
.Length
- 1;
261 if X
= Container
.Last
then
262 Position
:= No_Element
;
264 Container
.Last
:= N
(X
).Prev
;
265 N
(Container
.Last
).Next
:= 0;
271 Position
.Node
:= N
(X
).Next
;
273 N
(N
(X
).Next
).Prev
:= N
(X
).Prev
;
274 N
(N
(X
).Prev
).Next
:= N
(X
).Next
;
279 Position
:= No_Element
;
286 procedure Delete_First
287 (Container
: in out List
;
288 Count
: Count_Type
:= 1)
290 N
: Node_Array
renames Container
.Nodes
;
294 if Count
>= Container
.Length
then
303 -- if Container.Busy > 0 then
304 -- raise Program_Error;
307 for I
in 1 .. Count
loop
308 X
:= Container
.First
;
309 pragma Assert
(N
(N
(X
).Next
).Prev
= Container
.First
);
311 Container
.First
:= N
(X
).Next
;
312 N
(Container
.First
).Prev
:= 0;
314 Container
.Length
:= Container
.Length
- 1;
324 procedure Delete_Last
325 (Container
: in out List
;
326 Count
: Count_Type
:= 1)
328 N
: Node_Array
renames Container
.Nodes
;
332 if Count
>= Container
.Length
then
341 -- if Container.Busy > 0 then
342 -- raise Program_Error;
345 for I
in 1 .. Count
loop
347 pragma Assert
(N
(N
(X
).Prev
).Next
= Container
.Last
);
349 Container
.Last
:= N
(X
).Prev
;
350 N
(Container
.Last
).Next
:= 0;
352 Container
.Length
:= Container
.Length
- 1;
362 function Element
(Position
: Cursor
) return Element_Type
is
364 if Position
.Node
= 0 then
365 raise Constraint_Error
;
368 pragma Assert
(Vet
(Position
), "bad cursor in Element");
371 N
: Node_Array
renames Position
.Container
.Nodes
;
373 return N
(Position
.Node
).Element
;
384 Position
: Cursor
:= No_Element
) return Cursor
386 Nodes
: Node_Array
renames Container
.Nodes
;
387 Node
: Count_Type
:= Position
.Node
;
391 Node
:= Container
.First
;
394 if Position
.Container
/= Container
'Unrestricted_Access then
398 pragma Assert
(Vet
(Position
), "bad cursor in Find");
402 if Nodes
(Node
).Element
= Item
then
403 return Cursor
'(Container'Unrestricted_Access, Node);
406 Node := Nodes (Node).Next;
416 function First (Container : List) return Cursor is
418 if Container.First = 0 then
422 return Cursor'(Container
'Unrestricted_Access, Container
.First
);
429 function First_Element
(Container
: List
) return Element_Type
is
430 N
: Node_Array
renames Container
.Nodes
;
433 if Container
.First
= 0 then
434 raise Constraint_Error
;
437 return N
(Container
.First
).Element
;
445 (Container
: in out List
'Class;
448 pragma Assert
(X
> 0);
449 pragma Assert
(X
<= Container
.Capacity
);
451 N
: Node_Array
renames Container
.Nodes
;
454 N
(X
).Prev
:= -1; -- Node is deallocated (not on active list)
456 if Container
.Free
>= 0 then
457 N
(X
).Next
:= Container
.Free
;
460 elsif X
+ 1 = abs Container
.Free
then
461 N
(X
).Next
:= 0; -- Not strictly necessary, but marginally safer
462 Container
.Free
:= Container
.Free
+ 1;
465 Container
.Free
:= abs Container
.Free
;
467 if Container
.Free
> Container
.Capacity
then
471 for I
in Container
.Free
.. Container
.Capacity
- 1 loop
475 N
(Container
.Capacity
).Next
:= 0;
478 N
(X
).Next
:= Container
.Free
;
483 ---------------------
484 -- Generic_Sorting --
485 ---------------------
487 package body Generic_Sorting
is
493 function Is_Sorted
(Container
: List
) return Boolean is
494 Nodes
: Node_Array
renames Container
.Nodes
;
495 Node
: Count_Type
:= Container
.First
;
498 for I
in 2 .. Container
.Length
loop
499 if Nodes
(Nodes
(Node
).Next
).Element
< Nodes
(Node
).Element
then
503 Node
:= Nodes
(Node
).Next
;
513 procedure Sort
(Container
: in out List
) is
514 N
: Node_Array
renames Container
.Nodes
;
516 procedure Partition
(Pivot
, Back
: Count_Type
);
517 procedure Sort
(Front
, Back
: Count_Type
);
523 procedure Partition
(Pivot
, Back
: Count_Type
) is
524 Node
: Count_Type
:= N
(Pivot
).Next
;
527 while Node
/= Back
loop
528 if N
(Node
).Element
< N
(Pivot
).Element
then
530 Prev
: constant Count_Type
:= N
(Node
).Prev
;
531 Next
: constant Count_Type
:= N
(Node
).Next
;
534 N
(Prev
).Next
:= Next
;
537 Container
.Last
:= Prev
;
539 N
(Next
).Prev
:= Prev
;
542 N
(Node
).Next
:= Pivot
;
543 N
(Node
).Prev
:= N
(Pivot
).Prev
;
545 N
(Pivot
).Prev
:= Node
;
547 if N
(Node
).Prev
= 0 then
548 Container
.First
:= Node
;
550 N
(N
(Node
).Prev
).Next
:= Node
;
557 Node
:= N
(Node
).Next
;
566 procedure Sort
(Front
, Back
: Count_Type
) is
571 Pivot
:= Container
.First
;
573 Pivot
:= N
(Front
).Next
;
576 if Pivot
/= Back
then
577 Partition
(Pivot
, Back
);
583 -- Start of processing for Sort
586 if Container
.Length
<= 1 then
590 pragma Assert
(N
(Container
.First
).Prev
= 0);
591 pragma Assert
(N
(Container
.Last
).Next
= 0);
593 -- if Container.Busy > 0 then
594 -- raise Program_Error;
597 Sort
(Front
=> 0, Back
=> 0);
599 pragma Assert
(N
(Container
.First
).Prev
= 0);
600 pragma Assert
(N
(Container
.Last
).Next
= 0);
609 function Has_Element
(Position
: Cursor
) return Boolean is
611 pragma Assert
(Vet
(Position
), "bad cursor in Has_Element");
612 return Position
.Node
/= 0;
620 (Container
: in out List
;
622 New_Item
: Element_Type
;
623 Position
: out Cursor
;
624 Count
: Count_Type
:= 1)
629 if Before
.Container
/= null then
630 if Before
.Container
/= Container
'Unrestricted_Access then
634 pragma Assert
(Vet
(Before
), "bad cursor in Insert");
642 if Container
.Length
> Container
.Capacity
- Count
then
643 raise Constraint_Error
;
646 -- if Container.Busy > 0 then
647 -- raise Program_Error;
650 Allocate
(Container
, New_Item
, New_Node
=> J
);
651 Insert_Internal
(Container
, Before
.Node
, New_Node
=> J
);
652 Position
:= Cursor
'(Container'Unrestricted_Access, Node => J);
654 for Index in 2 .. Count loop
655 Allocate (Container, New_Item, New_Node => J);
656 Insert_Internal (Container, Before.Node, New_Node => J);
661 (Container : in out List;
663 New_Item : Element_Type;
664 Count : Count_Type := 1)
667 pragma Unreferenced (Position);
669 Insert (Container, Before, New_Item, Position, Count);
673 (Container : in out List;
675 Position : out Cursor;
676 Count : Count_Type := 1)
678 New_Item : Element_Type; -- Do we need to reinit node ???
679 pragma Warnings (Off, New_Item);
682 Insert (Container, Before, New_Item, Position, Count);
685 ---------------------
686 -- Insert_Internal --
687 ---------------------
689 procedure Insert_Internal
690 (Container : in out List'Class;
692 New_Node : Count_Type)
694 N : Node_Array renames Container.Nodes;
697 if Container.Length = 0 then
698 pragma Assert (Before = 0);
699 pragma Assert (Container.First = 0);
700 pragma Assert (Container.Last = 0);
702 Container.First := New_Node;
703 Container.Last := New_Node;
705 N (Container.First).Prev := 0;
706 N (Container.Last).Next := 0;
708 elsif Before = 0 then
709 pragma Assert (N (Container.Last).Next = 0);
711 N (Container.Last).Next := New_Node;
712 N (New_Node).Prev := Container.Last;
714 Container.Last := New_Node;
715 N (Container.Last).Next := 0;
717 elsif Before = Container.First then
718 pragma Assert (N (Container.First).Prev = 0);
720 N (Container.First).Prev := New_Node;
721 N (New_Node).Next := Container.First;
723 Container.First := New_Node;
724 N (Container.First).Prev := 0;
727 pragma Assert (N (Container.First).Prev = 0);
728 pragma Assert (N (Container.Last).Next = 0);
730 N (New_Node).Next := Before;
731 N (New_Node).Prev := N (Before).Prev;
733 N (N (Before).Prev).Next := New_Node;
734 N (Before).Prev := New_Node;
737 Container.Length := Container.Length + 1;
744 function Is_Empty (Container : List) return Boolean is
746 return Container.Length = 0;
755 Process : not null access procedure (Position : Cursor))
757 C : List renames Container'Unrestricted_Access.all;
758 N : Node_Array renames C.Nodes;
759 -- B : Natural renames C.Busy;
761 Node : Count_Type := Container.First;
763 Index : Count_Type := 0;
764 Index_Max : constant Count_Type := Container.Length;
767 if Index_Max = 0 then
768 pragma Assert (Node = 0);
773 pragma Assert (Node /= 0);
775 Process (Cursor'(C
'Unchecked_Access, Node
));
776 pragma Assert
(Container
.Length
= Index_Max
);
777 pragma Assert
(N
(Node
).Prev
/= -1);
779 Node
:= N
(Node
).Next
;
782 if Index
= Index_Max
then
783 pragma Assert
(Node
= 0);
793 function Last
(Container
: List
) return Cursor
is
795 if Container
.Last
= 0 then
799 return Cursor
'(Container'Unrestricted_Access, Container.Last);
806 function Last_Element (Container : List) return Element_Type is
807 N : Node_Array renames Container.Nodes;
810 if Container.Last = 0 then
811 raise Constraint_Error;
814 return N (Container.Last).Element;
821 function Length (Container : List) return Count_Type is
823 return Container.Length;
830 procedure Next (Position : in out Cursor) is
832 Position := Next (Position);
835 function Next (Position : Cursor) return Cursor is
837 if Position.Node = 0 then
841 pragma Assert (Vet (Position), "bad cursor in Next");
844 Nodes : Node_Array renames Position.Container.Nodes;
845 Node : constant Count_Type := Nodes (Position.Node).Next;
852 return Cursor'(Position
.Container
, Node
);
861 (Container
: in out List
;
862 New_Item
: Element_Type
;
863 Count
: Count_Type
:= 1)
866 Insert
(Container
, First
(Container
), New_Item
, Count
);
873 procedure Previous
(Position
: in out Cursor
) is
875 Position
:= Previous
(Position
);
878 function Previous
(Position
: Cursor
) return Cursor
is
880 if Position
.Node
= 0 then
884 pragma Assert
(Vet
(Position
), "bad cursor in Previous");
887 Nodes
: Node_Array
renames Position
.Container
.Nodes
;
888 Node
: constant Count_Type
:= Nodes
(Position
.Node
).Prev
;
894 return Cursor
'(Position.Container, Node);
902 procedure Query_Element
904 Process : not null access procedure (Element : Element_Type))
907 if Position.Node = 0 then
908 raise Constraint_Error;
911 pragma Assert (Vet (Position), "bad cursor in Query_Element");
914 C : List renames Position.Container.all'Unrestricted_Access.all;
915 N : Node_Type renames C.Nodes (Position.Node);
919 pragma Assert (N.Prev >= 0);
923 ---------------------
924 -- Replace_Element --
925 ---------------------
927 procedure Replace_Element
928 (Container : in out List;
930 New_Item : Element_Type)
933 if Position.Container = null then
934 raise Constraint_Error;
937 if Position.Container /= Container'Unrestricted_Access then
941 -- if Container.Lock > 0 then
942 -- raise Program_Error;
945 pragma Assert (Vet (Position), "bad cursor in Replace_Element");
948 N : Node_Array renames Container.Nodes;
950 N (Position.Node).Element := New_Item;
954 ----------------------
955 -- Reverse_Elements --
956 ----------------------
958 procedure Reverse_Elements (Container : in out List) is
959 N : Node_Array renames Container.Nodes;
960 I : Count_Type := Container.First;
961 J : Count_Type := Container.Last;
963 procedure Swap (L, R : Count_Type);
969 procedure Swap (L, R : Count_Type) is
970 LN : constant Count_Type := N (L).Next;
971 LP : constant Count_Type := N (L).Prev;
973 RN : constant Count_Type := N (R).Next;
974 RP : constant Count_Type := N (R).Prev;
989 pragma Assert (RP = L);
1003 -- Start of processing for Reverse_Elements
1006 if Container.Length <= 1 then
1010 pragma Assert (N (Container.First).Prev = 0);
1011 pragma Assert (N (Container.Last).Next = 0);
1013 -- if Container.Busy > 0 then
1014 -- raise Program_Error;
1017 Container.First := J;
1018 Container.Last := I;
1020 Swap (L => I, R => J);
1028 Swap (L => J, R => I);
1037 pragma Assert (N (Container.First).Prev = 0);
1038 pragma Assert (N (Container.Last).Next = 0);
1039 end Reverse_Elements;
1045 function Reverse_Find
1047 Item : Element_Type;
1048 Position : Cursor := No_Element) return Cursor
1050 N : Node_Array renames Container.Nodes;
1051 Node : Count_Type := Position.Node;
1055 Node := Container.Last;
1058 if Position.Container /= Container'Unrestricted_Access then
1059 raise Program_Error;
1062 pragma Assert (Vet (Position), "bad cursor in Reverse_Find");
1065 while Node /= 0 loop
1066 if N (Node).Element = Item then
1067 return Cursor'(Container
'Unrestricted_Access, Node
);
1070 Node
:= N
(Node
).Prev
;
1076 ---------------------
1077 -- Reverse_Iterate --
1078 ---------------------
1080 procedure Reverse_Iterate
1082 Process
: not null access procedure (Position
: Cursor
))
1084 C
: List
renames Container
'Unrestricted_Access.all;
1085 N
: Node_Array
renames C
.Nodes
;
1086 -- B : Natural renames C.Busy;
1088 Node
: Count_Type
:= Container
.Last
;
1090 Index
: Count_Type
:= 0;
1091 Index_Max
: constant Count_Type
:= Container
.Length
;
1094 if Index_Max
= 0 then
1095 pragma Assert
(Node
= 0);
1100 pragma Assert
(Node
> 0);
1102 Process
(Cursor
'(C'Unchecked_Access, Node));
1103 pragma Assert (Container.Length = Index_Max);
1104 pragma Assert (N (Node).Prev /= -1);
1106 Node := N (Node).Prev;
1109 if Index = Index_Max then
1110 pragma Assert (Node = 0);
1114 end Reverse_Iterate;
1121 (Container : in out List;
1123 Position : in out Cursor)
1125 N : Node_Array renames Container.Nodes;
1128 if Before.Container /= null then
1129 if Before.Container /= Container'Unrestricted_Access then
1130 raise Program_Error;
1133 pragma Assert (Vet (Before), "bad Before cursor in Splice");
1136 if Position.Node = 0 then
1137 raise Constraint_Error;
1140 if Position.Container /= Container'Unrestricted_Access then
1141 raise Program_Error;
1144 pragma Assert (Vet (Position), "bad Position cursor in Splice");
1146 if Position.Node = Before.Node
1147 or else N (Position.Node).Next = Before.Node
1152 pragma Assert (Container.Length >= 2);
1154 -- if Container.Busy > 0 then
1155 -- raise Program_Error;
1158 if Before.Node = 0 then
1159 pragma Assert (Position.Node /= Container.Last);
1161 if Position.Node = Container.First then
1162 Container.First := N (Position.Node).Next;
1163 N (Container.First).Prev := 0;
1166 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1167 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1170 N (Container.Last).Next := Position.Node;
1171 N (Position.Node).Prev := Container.Last;
1173 Container.Last := Position.Node;
1174 N (Container.Last).Next := 0;
1179 if Before.Node = Container.First then
1180 pragma Assert (Position.Node /= Container.First);
1182 if Position.Node = Container.Last then
1183 Container.Last := N (Position.Node).Prev;
1184 N (Container.Last).Next := 0;
1187 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1188 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1191 N (Container.First).Prev := Position.Node;
1192 N (Position.Node).Next := Container.First;
1194 Container.First := Position.Node;
1195 N (Container.First).Prev := 0;
1200 if Position.Node = Container.First then
1201 Container.First := N (Position.Node).Next;
1202 N (Container.First).Prev := 0;
1204 elsif Position.Node = Container.Last then
1205 Container.Last := N (Position.Node).Prev;
1206 N (Container.Last).Next := 0;
1209 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1210 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1213 N (N (Before.Node).Prev).Next := Position.Node;
1214 N (Position.Node).Prev := N (Before.Node).Prev;
1216 N (Before.Node).Prev := Position.Node;
1217 N (Position.Node).Next := Before.Node;
1219 pragma Assert (N (Container.First).Prev = 0);
1220 pragma Assert (N (Container.Last).Next = 0);
1228 (Container : in out List;
1235 raise Constraint_Error;
1238 if I.Container /= Container'Unrestricted_Access
1239 or else J.Container /= Container'Unrestricted_Access
1241 raise Program_Error;
1244 if I.Node = J.Node then
1248 -- if Container.Lock > 0 then
1249 -- raise Program_Error;
1252 pragma Assert (Vet (I), "bad I cursor in Swap");
1253 pragma Assert (Vet (J), "bad J cursor in Swap");
1256 N : Node_Array renames Container.Nodes;
1258 EI : Element_Type renames N (I.Node).Element;
1259 EJ : Element_Type renames N (J.Node).Element;
1261 EI_Copy : constant Element_Type := EI;
1273 procedure Swap_Links
1274 (Container : in out List;
1281 raise Constraint_Error;
1284 if I.Container /= Container'Unrestricted_Access
1285 or else I.Container /= J.Container
1287 raise Program_Error;
1290 if I.Node = J.Node then
1294 -- if Container.Busy > 0 then
1295 -- raise Program_Error;
1298 pragma Assert (Vet (I), "bad I cursor in Swap_Links");
1299 pragma Assert (Vet (J), "bad J cursor in Swap_Links");
1302 I_Next : constant Cursor := Next (I);
1304 J_Copy : Cursor := J;
1305 pragma Warnings (Off, J_Copy);
1309 Splice (Container, Before => I, Position => J_Copy);
1313 J_Next : constant Cursor := Next (J);
1315 I_Copy : Cursor := I;
1316 pragma Warnings (Off, I_Copy);
1320 Splice (Container, Before => J, Position => I_Copy);
1323 pragma Assert (Container.Length >= 3);
1325 Splice (Container, Before => I_Next, Position => J_Copy);
1326 Splice (Container, Before => J_Next, Position => I_Copy);
1333 --------------------
1334 -- Update_Element --
1335 --------------------
1337 procedure Update_Element
1338 (Container : in out List;
1340 Process : not null access procedure (Element : in out Element_Type))
1343 if Position.Node = 0 then
1344 raise Constraint_Error;
1347 if Position.Container /= Container'Unrestricted_Access then
1348 raise Program_Error;
1351 pragma Assert (Vet (Position), "bad cursor in Update_Element");
1354 N : Node_Type renames Container.Nodes (Position.Node);
1357 Process (N.Element);
1358 pragma Assert (N.Prev >= 0);
1366 function Vet (Position : Cursor) return Boolean is
1368 if Position.Node = 0 then
1369 return Position.Container = null;
1372 if Position.Container = null then
1377 L : List renames Position.Container.all;
1378 N : Node_Array renames L.Nodes;
1381 if L.Length = 0 then
1393 if Position.Node > L.Capacity then
1397 if N (Position.Node).Prev < 0
1398 or else N (Position.Node).Prev > L.Capacity
1403 if N (Position.Node).Next > L.Capacity then
1407 if N (L.First).Prev /= 0 then
1411 if N (L.Last).Next /= 0 then
1415 if N (Position.Node).Prev = 0
1416 and then Position.Node /= L.First
1421 if N (Position.Node).Next = 0
1422 and then Position.Node /= L.Last
1427 if L.Length = 1 then
1428 return L.First = L.Last;
1431 if L.First = L.Last then
1435 if N (L.First).Next = 0 then
1439 if N (L.Last).Prev = 0 then
1443 if N (N (L.First).Next).Prev /= L.First then
1447 if N (N (L.Last).Prev).Next /= L.Last then
1451 if L.Length = 2 then
1452 if N (L.First).Next /= L.Last then
1456 if N (L.Last).Prev /= L.First then
1463 if N (L.First).Next = L.Last then
1467 if N (L.Last).Prev = L.First then
1471 if Position.Node = L.First then
1475 if Position.Node = L.Last then
1479 if N (Position.Node).Next = 0 then
1483 if N (Position.Node).Prev = 0 then
1487 if N (N (Position.Node).Next).Prev /= Position.Node then
1491 if N (N (Position.Node).Prev).Next /= Position.Node then
1495 if L.Length = 3 then
1496 if N (L.First).Next /= Position.Node then
1500 if N (L.Last).Prev /= Position.Node then
1509 end Ada.Containers.Restricted_Doubly_Linked_Lists;