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-2006, 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)
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);
1303 J_Copy : Cursor := J;
1307 Splice (Container, Before => I, Position => J_Copy);
1311 J_Next : constant Cursor := Next (J);
1312 I_Copy : Cursor := I;
1316 Splice (Container, Before => J, Position => I_Copy);
1319 pragma Assert (Container.Length >= 3);
1321 Splice (Container, Before => I_Next, Position => J_Copy);
1322 Splice (Container, Before => J_Next, Position => I_Copy);
1329 --------------------
1330 -- Update_Element --
1331 --------------------
1333 procedure Update_Element
1334 (Container : in out List;
1336 Process : not null access procedure (Element : in out Element_Type))
1339 if Position.Node = 0 then
1340 raise Constraint_Error;
1343 if Position.Container /= Container'Unrestricted_Access then
1344 raise Program_Error;
1347 pragma Assert (Vet (Position), "bad cursor in Update_Element");
1350 N : Node_Type renames Container.Nodes (Position.Node);
1353 Process (N.Element);
1354 pragma Assert (N.Prev >= 0);
1362 function Vet (Position : Cursor) return Boolean is
1364 if Position.Node = 0 then
1365 return Position.Container = null;
1368 if Position.Container = null then
1373 L : List renames Position.Container.all;
1374 N : Node_Array renames L.Nodes;
1377 if L.Length = 0 then
1389 if Position.Node > L.Capacity then
1393 if N (Position.Node).Prev < 0
1394 or else N (Position.Node).Prev > L.Capacity
1399 if N (Position.Node).Next > L.Capacity then
1403 if N (L.First).Prev /= 0 then
1407 if N (L.Last).Next /= 0 then
1411 if N (Position.Node).Prev = 0
1412 and then Position.Node /= L.First
1417 if N (Position.Node).Next = 0
1418 and then Position.Node /= L.Last
1423 if L.Length = 1 then
1424 return L.First = L.Last;
1427 if L.First = L.Last then
1431 if N (L.First).Next = 0 then
1435 if N (L.Last).Prev = 0 then
1439 if N (N (L.First).Next).Prev /= L.First then
1443 if N (N (L.Last).Prev).Next /= L.Last then
1447 if L.Length = 2 then
1448 if N (L.First).Next /= L.Last then
1452 if N (L.Last).Prev /= L.First then
1459 if N (L.First).Next = L.Last then
1463 if N (L.Last).Prev = L.First then
1467 if Position.Node = L.First then
1471 if Position.Node = L.Last then
1475 if N (Position.Node).Next = 0 then
1479 if N (Position.Node).Prev = 0 then
1483 if N (N (Position.Node).Next).Prev /= Position.Node then
1487 if N (N (Position.Node).Prev).Next /= Position.Node then
1491 if L.Length = 3 then
1492 if N (L.First).Next /= Position.Node then
1496 if N (L.Last).Prev /= Position.Node then
1505 end Ada.Containers.Restricted_Doubly_Linked_Lists;