1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.RESTRICTED_DOUBLY_LINKED_LISTS --
9 -- Copyright (C) 2004-2007, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- This unit was originally developed by Matthew J Heaney. --
30 ------------------------------------------------------------------------------
32 with System
; use type System
.Address
;
34 package body Ada
.Containers
.Restricted_Doubly_Linked_Lists
is
36 -----------------------
37 -- Local Subprograms --
38 -----------------------
41 (Container
: in out List
'Class;
42 New_Item
: Element_Type
;
43 New_Node
: out Count_Type
);
46 (Container
: in out List
'Class;
49 procedure Insert_Internal
50 (Container
: in out List
'Class;
52 New_Node
: Count_Type
);
54 function Vet
(Position
: Cursor
) return Boolean;
60 function "=" (Left
, Right
: List
) return Boolean is
61 LN
: Node_Array
renames Left
.Nodes
;
62 RN
: Node_Array
renames Right
.Nodes
;
64 LI
: Count_Type
:= Left
.First
;
65 RI
: Count_Type
:= Right
.First
;
68 if Left
'Address = Right
'Address then
72 if Left
.Length
/= Right
.Length
then
76 for J
in 1 .. Left
.Length
loop
77 if LN
(LI
).Element
/= RN
(RI
).Element
then
93 (Container
: in out List
'Class;
94 New_Item
: Element_Type
;
95 New_Node
: out Count_Type
)
97 N
: Node_Array
renames Container
.Nodes
;
100 if Container
.Free
>= 0 then
101 New_Node
:= Container
.Free
;
102 N
(New_Node
).Element
:= New_Item
;
103 Container
.Free
:= N
(New_Node
).Next
;
106 New_Node
:= abs Container
.Free
;
107 N
(New_Node
).Element
:= New_Item
;
108 Container
.Free
:= Container
.Free
- 1;
117 (Container
: in out List
;
118 New_Item
: Element_Type
;
119 Count
: Count_Type
:= 1)
122 Insert
(Container
, No_Element
, New_Item
, Count
);
129 procedure Assign
(Target
: in out List
; Source
: List
) is
131 if Target
'Address = Source
'Address then
135 if Target
.Capacity
< Source
.Length
then
136 raise Constraint_Error
; -- ???
142 N
: Node_Array
renames Source
.Nodes
;
143 J
: Count_Type
:= Source
.First
;
147 Append
(Target
, N
(J
).Element
);
157 procedure Clear
(Container
: in out List
) is
158 N
: Node_Array
renames Container
.Nodes
;
162 if Container
.Length
= 0 then
163 pragma Assert
(Container
.First
= 0);
164 pragma Assert
(Container
.Last
= 0);
165 -- pragma Assert (Container.Busy = 0);
166 -- pragma Assert (Container.Lock = 0);
170 pragma Assert
(Container
.First
>= 1);
171 pragma Assert
(Container
.Last
>= 1);
172 pragma Assert
(N
(Container
.First
).Prev
= 0);
173 pragma Assert
(N
(Container
.Last
).Next
= 0);
175 -- if Container.Busy > 0 then
176 -- raise Program_Error;
179 while Container
.Length
> 1 loop
180 X
:= Container
.First
;
182 Container
.First
:= N
(X
).Next
;
183 N
(Container
.First
).Prev
:= 0;
185 Container
.Length
:= Container
.Length
- 1;
190 X
:= Container
.First
;
192 Container
.First
:= 0;
194 Container
.Length
:= 0;
205 Item
: Element_Type
) return Boolean
208 return Find
(Container
, Item
) /= No_Element
;
216 (Container
: in out List
;
217 Position
: in out Cursor
;
218 Count
: Count_Type
:= 1)
220 N
: Node_Array
renames Container
.Nodes
;
224 if Position
.Node
= 0 then
225 raise Constraint_Error
;
228 if Position
.Container
/= Container
'Unrestricted_Access then
232 pragma Assert
(Vet
(Position
), "bad cursor in Delete");
234 if Position
.Node
= Container
.First
then
235 Delete_First
(Container
, Count
);
236 Position
:= No_Element
;
241 Position
:= No_Element
;
245 -- if Container.Busy > 0 then
246 -- raise Program_Error;
249 pragma Assert
(Container
.First
>= 1);
250 pragma Assert
(Container
.Last
>= 1);
251 pragma Assert
(N
(Container
.First
).Prev
= 0);
252 pragma Assert
(N
(Container
.Last
).Next
= 0);
254 for Index
in 1 .. Count
loop
255 pragma Assert
(Container
.Length
>= 2);
258 Container
.Length
:= Container
.Length
- 1;
260 if X
= Container
.Last
then
261 Position
:= No_Element
;
263 Container
.Last
:= N
(X
).Prev
;
264 N
(Container
.Last
).Next
:= 0;
270 Position
.Node
:= N
(X
).Next
;
272 N
(N
(X
).Next
).Prev
:= N
(X
).Prev
;
273 N
(N
(X
).Prev
).Next
:= N
(X
).Next
;
278 Position
:= No_Element
;
285 procedure Delete_First
286 (Container
: in out List
;
287 Count
: Count_Type
:= 1)
289 N
: Node_Array
renames Container
.Nodes
;
293 if Count
>= Container
.Length
then
302 -- if Container.Busy > 0 then
303 -- raise Program_Error;
306 for I
in 1 .. Count
loop
307 X
:= Container
.First
;
308 pragma Assert
(N
(N
(X
).Next
).Prev
= Container
.First
);
310 Container
.First
:= N
(X
).Next
;
311 N
(Container
.First
).Prev
:= 0;
313 Container
.Length
:= Container
.Length
- 1;
323 procedure Delete_Last
324 (Container
: in out List
;
325 Count
: Count_Type
:= 1)
327 N
: Node_Array
renames Container
.Nodes
;
331 if Count
>= Container
.Length
then
340 -- if Container.Busy > 0 then
341 -- raise Program_Error;
344 for I
in 1 .. Count
loop
346 pragma Assert
(N
(N
(X
).Prev
).Next
= Container
.Last
);
348 Container
.Last
:= N
(X
).Prev
;
349 N
(Container
.Last
).Next
:= 0;
351 Container
.Length
:= Container
.Length
- 1;
361 function Element
(Position
: Cursor
) return Element_Type
is
363 if Position
.Node
= 0 then
364 raise Constraint_Error
;
367 pragma Assert
(Vet
(Position
), "bad cursor in Element");
370 N
: Node_Array
renames Position
.Container
.Nodes
;
372 return N
(Position
.Node
).Element
;
383 Position
: Cursor
:= No_Element
) return Cursor
385 Nodes
: Node_Array
renames Container
.Nodes
;
386 Node
: Count_Type
:= Position
.Node
;
390 Node
:= Container
.First
;
393 if Position
.Container
/= Container
'Unrestricted_Access then
397 pragma Assert
(Vet
(Position
), "bad cursor in Find");
401 if Nodes
(Node
).Element
= Item
then
402 return Cursor
'(Container'Unrestricted_Access, Node);
405 Node := Nodes (Node).Next;
415 function First (Container : List) return Cursor is
417 if Container.First = 0 then
421 return Cursor'(Container
'Unrestricted_Access, Container
.First
);
428 function First_Element
(Container
: List
) return Element_Type
is
429 N
: Node_Array
renames Container
.Nodes
;
432 if Container
.First
= 0 then
433 raise Constraint_Error
;
436 return N
(Container
.First
).Element
;
444 (Container
: in out List
'Class;
447 pragma Assert
(X
> 0);
448 pragma Assert
(X
<= Container
.Capacity
);
450 N
: Node_Array
renames Container
.Nodes
;
453 N
(X
).Prev
:= -1; -- Node is deallocated (not on active list)
455 if Container
.Free
>= 0 then
456 N
(X
).Next
:= Container
.Free
;
459 elsif X
+ 1 = abs Container
.Free
then
460 N
(X
).Next
:= 0; -- Not strictly necessary, but marginally safer
461 Container
.Free
:= Container
.Free
+ 1;
464 Container
.Free
:= abs Container
.Free
;
466 if Container
.Free
> Container
.Capacity
then
470 for I
in Container
.Free
.. Container
.Capacity
- 1 loop
474 N
(Container
.Capacity
).Next
:= 0;
477 N
(X
).Next
:= Container
.Free
;
482 ---------------------
483 -- Generic_Sorting --
484 ---------------------
486 package body Generic_Sorting
is
492 function Is_Sorted
(Container
: List
) return Boolean is
493 Nodes
: Node_Array
renames Container
.Nodes
;
494 Node
: Count_Type
:= Container
.First
;
497 for I
in 2 .. Container
.Length
loop
498 if Nodes
(Nodes
(Node
).Next
).Element
< Nodes
(Node
).Element
then
502 Node
:= Nodes
(Node
).Next
;
512 procedure Sort
(Container
: in out List
) is
513 N
: Node_Array
renames Container
.Nodes
;
515 procedure Partition
(Pivot
, Back
: Count_Type
);
516 procedure Sort
(Front
, Back
: Count_Type
);
522 procedure Partition
(Pivot
, Back
: Count_Type
) is
523 Node
: Count_Type
:= N
(Pivot
).Next
;
526 while Node
/= Back
loop
527 if N
(Node
).Element
< N
(Pivot
).Element
then
529 Prev
: constant Count_Type
:= N
(Node
).Prev
;
530 Next
: constant Count_Type
:= N
(Node
).Next
;
533 N
(Prev
).Next
:= Next
;
536 Container
.Last
:= Prev
;
538 N
(Next
).Prev
:= Prev
;
541 N
(Node
).Next
:= Pivot
;
542 N
(Node
).Prev
:= N
(Pivot
).Prev
;
544 N
(Pivot
).Prev
:= Node
;
546 if N
(Node
).Prev
= 0 then
547 Container
.First
:= Node
;
549 N
(N
(Node
).Prev
).Next
:= Node
;
556 Node
:= N
(Node
).Next
;
565 procedure Sort
(Front
, Back
: Count_Type
) is
570 Pivot
:= Container
.First
;
572 Pivot
:= N
(Front
).Next
;
575 if Pivot
/= Back
then
576 Partition
(Pivot
, Back
);
582 -- Start of processing for Sort
585 if Container
.Length
<= 1 then
589 pragma Assert
(N
(Container
.First
).Prev
= 0);
590 pragma Assert
(N
(Container
.Last
).Next
= 0);
592 -- if Container.Busy > 0 then
593 -- raise Program_Error;
596 Sort
(Front
=> 0, Back
=> 0);
598 pragma Assert
(N
(Container
.First
).Prev
= 0);
599 pragma Assert
(N
(Container
.Last
).Next
= 0);
608 function Has_Element
(Position
: Cursor
) return Boolean is
610 pragma Assert
(Vet
(Position
), "bad cursor in Has_Element");
611 return Position
.Node
/= 0;
619 (Container
: in out List
;
621 New_Item
: Element_Type
;
622 Position
: out Cursor
;
623 Count
: Count_Type
:= 1)
628 if Before
.Container
/= null then
629 if Before
.Container
/= Container
'Unrestricted_Access then
633 pragma Assert
(Vet
(Before
), "bad cursor in Insert");
641 if Container
.Length
> Container
.Capacity
- Count
then
642 raise Constraint_Error
;
645 -- if Container.Busy > 0 then
646 -- raise Program_Error;
649 Allocate
(Container
, New_Item
, New_Node
=> J
);
650 Insert_Internal
(Container
, Before
.Node
, New_Node
=> J
);
651 Position
:= Cursor
'(Container'Unrestricted_Access, Node => J);
653 for Index in 2 .. Count loop
654 Allocate (Container, New_Item, New_Node => J);
655 Insert_Internal (Container, Before.Node, New_Node => J);
660 (Container : in out List;
662 New_Item : Element_Type;
663 Count : Count_Type := 1)
666 pragma Unreferenced (Position);
668 Insert (Container, Before, New_Item, Position, Count);
672 (Container : in out List;
674 Position : out Cursor;
675 Count : Count_Type := 1)
677 New_Item : Element_Type; -- Do we need to reinit node ???
678 pragma Warnings (Off, New_Item);
681 Insert (Container, Before, New_Item, Position, Count);
684 ---------------------
685 -- Insert_Internal --
686 ---------------------
688 procedure Insert_Internal
689 (Container : in out List'Class;
691 New_Node : Count_Type)
693 N : Node_Array renames Container.Nodes;
696 if Container.Length = 0 then
697 pragma Assert (Before = 0);
698 pragma Assert (Container.First = 0);
699 pragma Assert (Container.Last = 0);
701 Container.First := New_Node;
702 Container.Last := New_Node;
704 N (Container.First).Prev := 0;
705 N (Container.Last).Next := 0;
707 elsif Before = 0 then
708 pragma Assert (N (Container.Last).Next = 0);
710 N (Container.Last).Next := New_Node;
711 N (New_Node).Prev := Container.Last;
713 Container.Last := New_Node;
714 N (Container.Last).Next := 0;
716 elsif Before = Container.First then
717 pragma Assert (N (Container.First).Prev = 0);
719 N (Container.First).Prev := New_Node;
720 N (New_Node).Next := Container.First;
722 Container.First := New_Node;
723 N (Container.First).Prev := 0;
726 pragma Assert (N (Container.First).Prev = 0);
727 pragma Assert (N (Container.Last).Next = 0);
729 N (New_Node).Next := Before;
730 N (New_Node).Prev := N (Before).Prev;
732 N (N (Before).Prev).Next := New_Node;
733 N (Before).Prev := New_Node;
736 Container.Length := Container.Length + 1;
743 function Is_Empty (Container : List) return Boolean is
745 return Container.Length = 0;
754 Process : not null access procedure (Position : Cursor))
756 C : List renames Container'Unrestricted_Access.all;
757 N : Node_Array renames C.Nodes;
758 -- B : Natural renames C.Busy;
760 Node : Count_Type := Container.First;
762 Index : Count_Type := 0;
763 Index_Max : constant Count_Type := Container.Length;
766 if Index_Max = 0 then
767 pragma Assert (Node = 0);
772 pragma Assert (Node /= 0);
774 Process (Cursor'(C
'Unchecked_Access, Node
));
775 pragma Assert
(Container
.Length
= Index_Max
);
776 pragma Assert
(N
(Node
).Prev
/= -1);
778 Node
:= N
(Node
).Next
;
781 if Index
= Index_Max
then
782 pragma Assert
(Node
= 0);
792 function Last
(Container
: List
) return Cursor
is
794 if Container
.Last
= 0 then
798 return Cursor
'(Container'Unrestricted_Access, Container.Last);
805 function Last_Element (Container : List) return Element_Type is
806 N : Node_Array renames Container.Nodes;
809 if Container.Last = 0 then
810 raise Constraint_Error;
813 return N (Container.Last).Element;
820 function Length (Container : List) return Count_Type is
822 return Container.Length;
829 procedure Next (Position : in out Cursor) is
831 Position := Next (Position);
834 function Next (Position : Cursor) return Cursor is
836 if Position.Node = 0 then
840 pragma Assert (Vet (Position), "bad cursor in Next");
843 Nodes : Node_Array renames Position.Container.Nodes;
844 Node : constant Count_Type := Nodes (Position.Node).Next;
851 return Cursor'(Position
.Container
, Node
);
860 (Container
: in out List
;
861 New_Item
: Element_Type
;
862 Count
: Count_Type
:= 1)
865 Insert
(Container
, First
(Container
), New_Item
, Count
);
872 procedure Previous
(Position
: in out Cursor
) is
874 Position
:= Previous
(Position
);
877 function Previous
(Position
: Cursor
) return Cursor
is
879 if Position
.Node
= 0 then
883 pragma Assert
(Vet
(Position
), "bad cursor in Previous");
886 Nodes
: Node_Array
renames Position
.Container
.Nodes
;
887 Node
: constant Count_Type
:= Nodes
(Position
.Node
).Prev
;
893 return Cursor
'(Position.Container, Node);
901 procedure Query_Element
903 Process : not null access procedure (Element : Element_Type))
906 if Position.Node = 0 then
907 raise Constraint_Error;
910 pragma Assert (Vet (Position), "bad cursor in Query_Element");
913 C : List renames Position.Container.all'Unrestricted_Access.all;
914 N : Node_Type renames C.Nodes (Position.Node);
918 pragma Assert (N.Prev >= 0);
922 ---------------------
923 -- Replace_Element --
924 ---------------------
926 procedure Replace_Element
927 (Container : in out List;
929 New_Item : Element_Type)
932 if Position.Container = null then
933 raise Constraint_Error;
936 if Position.Container /= Container'Unrestricted_Access then
940 -- if Container.Lock > 0 then
941 -- raise Program_Error;
944 pragma Assert (Vet (Position), "bad cursor in Replace_Element");
947 N : Node_Array renames Container.Nodes;
949 N (Position.Node).Element := New_Item;
953 ----------------------
954 -- Reverse_Elements --
955 ----------------------
957 procedure Reverse_Elements (Container : in out List) is
958 N : Node_Array renames Container.Nodes;
959 I : Count_Type := Container.First;
960 J : Count_Type := Container.Last;
962 procedure Swap (L, R : Count_Type);
968 procedure Swap (L, R : Count_Type) is
969 LN : constant Count_Type := N (L).Next;
970 LP : constant Count_Type := N (L).Prev;
972 RN : constant Count_Type := N (R).Next;
973 RP : constant Count_Type := N (R).Prev;
988 pragma Assert (RP = L);
1002 -- Start of processing for Reverse_Elements
1005 if Container.Length <= 1 then
1009 pragma Assert (N (Container.First).Prev = 0);
1010 pragma Assert (N (Container.Last).Next = 0);
1012 -- if Container.Busy > 0 then
1013 -- raise Program_Error;
1016 Container.First := J;
1017 Container.Last := I;
1019 Swap (L => I, R => J);
1027 Swap (L => J, R => I);
1036 pragma Assert (N (Container.First).Prev = 0);
1037 pragma Assert (N (Container.Last).Next = 0);
1038 end Reverse_Elements;
1044 function Reverse_Find
1046 Item : Element_Type;
1047 Position : Cursor := No_Element) return Cursor
1049 N : Node_Array renames Container.Nodes;
1050 Node : Count_Type := Position.Node;
1054 Node := Container.Last;
1057 if Position.Container /= Container'Unrestricted_Access then
1058 raise Program_Error;
1061 pragma Assert (Vet (Position), "bad cursor in Reverse_Find");
1064 while Node /= 0 loop
1065 if N (Node).Element = Item then
1066 return Cursor'(Container
'Unrestricted_Access, Node
);
1069 Node
:= N
(Node
).Prev
;
1075 ---------------------
1076 -- Reverse_Iterate --
1077 ---------------------
1079 procedure Reverse_Iterate
1081 Process
: not null access procedure (Position
: Cursor
))
1083 C
: List
renames Container
'Unrestricted_Access.all;
1084 N
: Node_Array
renames C
.Nodes
;
1085 -- B : Natural renames C.Busy;
1087 Node
: Count_Type
:= Container
.Last
;
1089 Index
: Count_Type
:= 0;
1090 Index_Max
: constant Count_Type
:= Container
.Length
;
1093 if Index_Max
= 0 then
1094 pragma Assert
(Node
= 0);
1099 pragma Assert
(Node
> 0);
1101 Process
(Cursor
'(C'Unchecked_Access, Node));
1102 pragma Assert (Container.Length = Index_Max);
1103 pragma Assert (N (Node).Prev /= -1);
1105 Node := N (Node).Prev;
1108 if Index = Index_Max then
1109 pragma Assert (Node = 0);
1113 end Reverse_Iterate;
1120 (Container : in out List;
1122 Position : in out Cursor)
1124 N : Node_Array renames Container.Nodes;
1127 if Before.Container /= null then
1128 if Before.Container /= Container'Unrestricted_Access then
1129 raise Program_Error;
1132 pragma Assert (Vet (Before), "bad Before cursor in Splice");
1135 if Position.Node = 0 then
1136 raise Constraint_Error;
1139 if Position.Container /= Container'Unrestricted_Access then
1140 raise Program_Error;
1143 pragma Assert (Vet (Position), "bad Position cursor in Splice");
1145 if Position.Node = Before.Node
1146 or else N (Position.Node).Next = Before.Node
1151 pragma Assert (Container.Length >= 2);
1153 -- if Container.Busy > 0 then
1154 -- raise Program_Error;
1157 if Before.Node = 0 then
1158 pragma Assert (Position.Node /= Container.Last);
1160 if Position.Node = Container.First then
1161 Container.First := N (Position.Node).Next;
1162 N (Container.First).Prev := 0;
1165 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1166 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1169 N (Container.Last).Next := Position.Node;
1170 N (Position.Node).Prev := Container.Last;
1172 Container.Last := Position.Node;
1173 N (Container.Last).Next := 0;
1178 if Before.Node = Container.First then
1179 pragma Assert (Position.Node /= Container.First);
1181 if Position.Node = Container.Last then
1182 Container.Last := N (Position.Node).Prev;
1183 N (Container.Last).Next := 0;
1186 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1187 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1190 N (Container.First).Prev := Position.Node;
1191 N (Position.Node).Next := Container.First;
1193 Container.First := Position.Node;
1194 N (Container.First).Prev := 0;
1199 if Position.Node = Container.First then
1200 Container.First := N (Position.Node).Next;
1201 N (Container.First).Prev := 0;
1203 elsif Position.Node = Container.Last then
1204 Container.Last := N (Position.Node).Prev;
1205 N (Container.Last).Next := 0;
1208 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1209 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1212 N (N (Before.Node).Prev).Next := Position.Node;
1213 N (Position.Node).Prev := N (Before.Node).Prev;
1215 N (Before.Node).Prev := Position.Node;
1216 N (Position.Node).Next := Before.Node;
1218 pragma Assert (N (Container.First).Prev = 0);
1219 pragma Assert (N (Container.Last).Next = 0);
1227 (Container : in out List;
1234 raise Constraint_Error;
1237 if I.Container /= Container'Unrestricted_Access
1238 or else J.Container /= Container'Unrestricted_Access
1240 raise Program_Error;
1243 if I.Node = J.Node then
1247 -- if Container.Lock > 0 then
1248 -- raise Program_Error;
1251 pragma Assert (Vet (I), "bad I cursor in Swap");
1252 pragma Assert (Vet (J), "bad J cursor in Swap");
1255 N : Node_Array renames Container.Nodes;
1257 EI : Element_Type renames N (I.Node).Element;
1258 EJ : Element_Type renames N (J.Node).Element;
1260 EI_Copy : constant Element_Type := EI;
1272 procedure Swap_Links
1273 (Container : in out List;
1280 raise Constraint_Error;
1283 if I.Container /= Container'Unrestricted_Access
1284 or else I.Container /= J.Container
1286 raise Program_Error;
1289 if I.Node = J.Node then
1293 -- if Container.Busy > 0 then
1294 -- raise Program_Error;
1297 pragma Assert (Vet (I), "bad I cursor in Swap_Links");
1298 pragma Assert (Vet (J), "bad J cursor in Swap_Links");
1301 I_Next : constant Cursor := Next (I);
1303 J_Copy : Cursor := J;
1304 pragma Warnings (Off, J_Copy);
1308 Splice (Container, Before => I, Position => J_Copy);
1312 J_Next : constant Cursor := Next (J);
1314 I_Copy : Cursor := I;
1315 pragma Warnings (Off, I_Copy);
1319 Splice (Container, Before => J, Position => I_Copy);
1322 pragma Assert (Container.Length >= 3);
1324 Splice (Container, Before => I_Next, Position => J_Copy);
1325 Splice (Container, Before => J_Next, Position => I_Copy);
1332 --------------------
1333 -- Update_Element --
1334 --------------------
1336 procedure Update_Element
1337 (Container : in out List;
1339 Process : not null access procedure (Element : in out Element_Type))
1342 if Position.Node = 0 then
1343 raise Constraint_Error;
1346 if Position.Container /= Container'Unrestricted_Access then
1347 raise Program_Error;
1350 pragma Assert (Vet (Position), "bad cursor in Update_Element");
1353 N : Node_Type renames Container.Nodes (Position.Node);
1356 Process (N.Element);
1357 pragma Assert (N.Prev >= 0);
1365 function Vet (Position : Cursor) return Boolean is
1367 if Position.Node = 0 then
1368 return Position.Container = null;
1371 if Position.Container = null then
1376 L : List renames Position.Container.all;
1377 N : Node_Array renames L.Nodes;
1380 if L.Length = 0 then
1392 if Position.Node > L.Capacity then
1396 if N (Position.Node).Prev < 0
1397 or else N (Position.Node).Prev > L.Capacity
1402 if N (Position.Node).Next > L.Capacity then
1406 if N (L.First).Prev /= 0 then
1410 if N (L.Last).Next /= 0 then
1414 if N (Position.Node).Prev = 0
1415 and then Position.Node /= L.First
1420 if N (Position.Node).Next = 0
1421 and then Position.Node /= L.Last
1426 if L.Length = 1 then
1427 return L.First = L.Last;
1430 if L.First = L.Last then
1434 if N (L.First).Next = 0 then
1438 if N (L.Last).Prev = 0 then
1442 if N (N (L.First).Next).Prev /= L.First then
1446 if N (N (L.Last).Prev).Next /= L.Last then
1450 if L.Length = 2 then
1451 if N (L.First).Next /= L.Last then
1455 if N (L.Last).Prev /= L.First then
1462 if N (L.First).Next = L.Last then
1466 if N (L.Last).Prev = L.First then
1470 if Position.Node = L.First then
1474 if Position.Node = L.Last then
1478 if N (Position.Node).Next = 0 then
1482 if N (Position.Node).Prev = 0 then
1486 if N (N (Position.Node).Next).Prev /= Position.Node then
1490 if N (N (Position.Node).Prev).Next /= Position.Node then
1494 if L.Length = 3 then
1495 if N (L.First).Next /= Position.Node then
1499 if N (L.Last).Prev /= Position.Node then
1508 end Ada.Containers.Restricted_Doubly_Linked_Lists;