1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.RESTRICTED_DOUBLY_LINKED_LISTS --
9 -- Copyright (C) 2004-2016, 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 3, 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. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- This unit was originally developed by Matthew J Heaney. --
28 ------------------------------------------------------------------------------
30 with System; use type System.Address;
32 package body Ada.Containers.Restricted_Doubly_Linked_Lists is
34 -----------------------
35 -- Local Subprograms --
36 -----------------------
39 (Container : in out List'Class;
40 New_Item : Element_Type;
41 New_Node : out Count_Type);
44 (Container : in out List'Class;
47 procedure Insert_Internal
48 (Container : in out List'Class;
50 New_Node : Count_Type);
52 function Vet (Position : Cursor) return Boolean;
58 function "=" (Left, Right : List) return Boolean is
59 LN : Node_Array renames Left.Nodes;
60 RN : Node_Array renames Right.Nodes;
62 LI : Count_Type := Left.First;
63 RI : Count_Type := Right.First;
66 if Left'Address = Right'Address then
70 if Left.Length /= Right.Length then
74 for J in 1 .. Left.Length loop
75 if LN (LI).Element /= RN (RI).Element then
91 (Container : in out List'Class;
92 New_Item : Element_Type;
93 New_Node : out Count_Type)
95 N : Node_Array renames Container.Nodes;
98 if Container.Free >= 0 then
99 New_Node := Container.Free;
100 N (New_Node).Element := New_Item;
101 Container.Free := N (New_Node).Next;
104 New_Node := abs Container.Free;
105 N (New_Node).Element := New_Item;
106 Container.Free := Container.Free - 1;
115 (Container : in out List;
116 New_Item : Element_Type;
117 Count : Count_Type := 1)
120 Insert (Container, No_Element, New_Item, Count);
127 procedure Assign (Target : in out List; Source : List) is
129 if Target'Address = Source'Address then
133 if Target.Capacity < Source.Length then
134 raise Constraint_Error; -- ???
140 N : Node_Array renames Source.Nodes;
141 J : Count_Type := Source.First;
145 Append (Target, N (J).Element);
155 procedure Clear (Container : in out List) is
156 N : Node_Array renames Container.Nodes;
160 if Container.Length = 0 then
161 pragma Assert (Container.First = 0);
162 pragma Assert (Container.Last = 0);
163 -- pragma Assert (Container.Busy = 0);
164 -- pragma Assert (Container.Lock = 0);
168 pragma Assert (Container.First >= 1);
169 pragma Assert (Container.Last >= 1);
170 pragma Assert (N (Container.First).Prev = 0);
171 pragma Assert (N (Container.Last).Next = 0);
173 -- if Container.Busy > 0 then
174 -- raise Program_Error;
177 while Container.Length > 1 loop
178 X := Container.First;
180 Container.First := N (X).Next;
181 N (Container.First).Prev := 0;
183 Container.Length := Container.Length - 1;
188 X := Container.First;
190 Container.First := 0;
192 Container.Length := 0;
203 Item : Element_Type) return Boolean
206 return Find (Container, Item) /= No_Element;
214 (Container : in out List;
215 Position : in out Cursor;
216 Count : Count_Type := 1)
218 N : Node_Array renames Container.Nodes;
222 if Position.Node = 0 then
223 raise Constraint_Error;
226 if Position.Container /= Container'Unrestricted_Access then
230 pragma Assert (Vet (Position), "bad cursor in Delete");
232 if Position.Node = Container.First then
233 Delete_First (Container, Count);
234 Position := No_Element;
239 Position := No_Element;
243 -- if Container.Busy > 0 then
244 -- raise Program_Error;
247 pragma Assert (Container.First >= 1);
248 pragma Assert (Container.Last >= 1);
249 pragma Assert (N (Container.First).Prev = 0);
250 pragma Assert (N (Container.Last).Next = 0);
252 for Index in 1 .. Count loop
253 pragma Assert (Container.Length >= 2);
256 Container.Length := Container.Length - 1;
258 if X = Container.Last then
259 Position := No_Element;
261 Container.Last := N (X).Prev;
262 N (Container.Last).Next := 0;
268 Position.Node := N (X).Next;
270 N (N (X).Next).Prev := N (X).Prev;
271 N (N (X).Prev).Next := N (X).Next;
276 Position := No_Element;
283 procedure Delete_First
284 (Container : in out List;
285 Count : Count_Type := 1)
287 N : Node_Array renames Container.Nodes;
291 if Count >= Container.Length then
300 -- if Container.Busy > 0 then
301 -- raise Program_Error;
304 for I in 1 .. Count loop
305 X := Container.First;
306 pragma Assert (N (N (X).Next).Prev = Container.First);
308 Container.First := N (X).Next;
309 N (Container.First).Prev := 0;
311 Container.Length := Container.Length - 1;
321 procedure Delete_Last
322 (Container : in out List;
323 Count : Count_Type := 1)
325 N : Node_Array renames Container.Nodes;
329 if Count >= Container.Length then
338 -- if Container.Busy > 0 then
339 -- raise Program_Error;
342 for I in 1 .. Count loop
344 pragma Assert (N (N (X).Prev).Next = Container.Last);
346 Container.Last := N (X).Prev;
347 N (Container.Last).Next := 0;
349 Container.Length := Container.Length - 1;
359 function Element (Position : Cursor) return Element_Type is
361 if Position.Node = 0 then
362 raise Constraint_Error;
365 pragma Assert (Vet (Position), "bad cursor in Element");
368 N : Node_Array renames Position.Container.Nodes;
370 return N (Position.Node).Element;
381 Position : Cursor := No_Element) return Cursor
383 Nodes : Node_Array renames Container.Nodes;
384 Node : Count_Type := Position.Node;
388 Node := Container.First;
391 if Position.Container /= Container'Unrestricted_Access then
395 pragma Assert (Vet (Position), "bad cursor in Find");
399 if Nodes (Node).Element = Item then
400 return Cursor'(Container'Unrestricted_Access, Node);
403 Node := Nodes (Node).Next;
413 function First (Container : List) return Cursor is
415 if Container.First = 0 then
419 return Cursor'(Container'Unrestricted_Access, Container.First);
426 function First_Element (Container : List) return Element_Type is
427 N : Node_Array renames Container.Nodes;
430 if Container.First = 0 then
431 raise Constraint_Error;
434 return N (Container.First).Element;
442 (Container : in out List'Class;
445 pragma Assert (X > 0);
446 pragma Assert (X <= Container.Capacity);
448 N : Node_Array renames Container.Nodes;
451 N (X).Prev := -1; -- Node is deallocated (not on active list)
453 if Container.Free >= 0 then
454 N (X).Next := Container.Free;
457 elsif X + 1 = abs Container.Free then
458 N (X).Next := 0; -- Not strictly necessary, but marginally safer
459 Container.Free := Container.Free + 1;
462 Container.Free := abs Container.Free;
464 if Container.Free > Container.Capacity then
468 for I in Container.Free .. Container.Capacity - 1 loop
472 N (Container.Capacity).Next := 0;
475 N (X).Next := Container.Free;
480 ---------------------
481 -- Generic_Sorting --
482 ---------------------
484 package body Generic_Sorting is
490 function Is_Sorted (Container : List) return Boolean is
491 Nodes : Node_Array renames Container.Nodes;
492 Node : Count_Type := Container.First;
495 for I in 2 .. Container.Length loop
496 if Nodes (Nodes (Node).Next).Element < Nodes (Node).Element then
500 Node := Nodes (Node).Next;
510 procedure Sort (Container : in out List) is
511 N : Node_Array renames Container.Nodes;
513 procedure Partition (Pivot, Back : Count_Type);
514 procedure Sort (Front, Back : Count_Type);
520 procedure Partition (Pivot, Back : Count_Type) is
521 Node : Count_Type := N (Pivot).Next;
524 while Node /= Back loop
525 if N (Node).Element < N (Pivot).Element then
527 Prev : constant Count_Type := N (Node).Prev;
528 Next : constant Count_Type := N (Node).Next;
531 N (Prev).Next := Next;
534 Container.Last := Prev;
536 N (Next).Prev := Prev;
539 N (Node).Next := Pivot;
540 N (Node).Prev := N (Pivot).Prev;
542 N (Pivot).Prev := Node;
544 if N (Node).Prev = 0 then
545 Container.First := Node;
547 N (N (Node).Prev).Next := Node;
554 Node := N (Node).Next;
563 procedure Sort (Front, Back : Count_Type) is
564 Pivot : constant Count_Type :=
565 (if Front = 0 then Container.First else N (Front).Next);
567 if Pivot /= Back then
568 Partition (Pivot, Back);
574 -- Start of processing for Sort
577 if Container.Length <= 1 then
581 pragma Assert (N (Container.First).Prev = 0);
582 pragma Assert (N (Container.Last).Next = 0);
584 -- if Container.Busy > 0 then
585 -- raise Program_Error;
588 Sort (Front => 0, Back => 0);
590 pragma Assert (N (Container.First).Prev = 0);
591 pragma Assert (N (Container.Last).Next = 0);
600 function Has_Element (Position : Cursor) return Boolean is
602 pragma Assert (Vet (Position), "bad cursor in Has_Element");
603 return Position.Node /= 0;
611 (Container : in out List;
613 New_Item : Element_Type;
614 Position : out Cursor;
615 Count : Count_Type := 1)
617 First_Node : Count_Type;
618 New_Node : Count_Type;
621 if Before.Container /= null then
622 if Before.Container /= Container'Unrestricted_Access then
626 pragma Assert (Vet (Before), "bad cursor in Insert");
634 if Container.Length > Container.Capacity - Count then
635 raise Constraint_Error;
638 -- if Container.Busy > 0 then
639 -- raise Program_Error;
642 Allocate (Container, New_Item, New_Node);
643 First_Node := New_Node;
644 Insert_Internal (Container, Before.Node, New_Node);
646 for Index in 2 .. Count loop
647 Allocate (Container, New_Item, New_Node);
648 Insert_Internal (Container, Before.Node, New_Node);
651 Position := Cursor'(Container'Unrestricted_Access, First_Node);
655 (Container : in out List;
657 New_Item : Element_Type;
658 Count : Count_Type := 1)
661 pragma Unreferenced (Position);
663 Insert (Container, Before, New_Item, Position, Count);
667 (Container : in out List;
669 Position : out Cursor;
670 Count : Count_Type := 1)
672 New_Item : Element_Type; -- Do we need to reinit node ???
673 pragma Warnings (Off, New_Item);
676 Insert (Container, Before, New_Item, Position, Count);
679 ---------------------
680 -- Insert_Internal --
681 ---------------------
683 procedure Insert_Internal
684 (Container : in out List'Class;
686 New_Node : Count_Type)
688 N : Node_Array renames Container.Nodes;
691 if Container.Length = 0 then
692 pragma Assert (Before = 0);
693 pragma Assert (Container.First = 0);
694 pragma Assert (Container.Last = 0);
696 Container.First := New_Node;
697 Container.Last := New_Node;
699 N (Container.First).Prev := 0;
700 N (Container.Last).Next := 0;
702 elsif Before = 0 then
703 pragma Assert (N (Container.Last).Next = 0);
705 N (Container.Last).Next := New_Node;
706 N (New_Node).Prev := Container.Last;
708 Container.Last := New_Node;
709 N (Container.Last).Next := 0;
711 elsif Before = Container.First then
712 pragma Assert (N (Container.First).Prev = 0);
714 N (Container.First).Prev := New_Node;
715 N (New_Node).Next := Container.First;
717 Container.First := New_Node;
718 N (Container.First).Prev := 0;
721 pragma Assert (N (Container.First).Prev = 0);
722 pragma Assert (N (Container.Last).Next = 0);
724 N (New_Node).Next := Before;
725 N (New_Node).Prev := N (Before).Prev;
727 N (N (Before).Prev).Next := New_Node;
728 N (Before).Prev := New_Node;
731 Container.Length := Container.Length + 1;
738 function Is_Empty (Container : List) return Boolean is
740 return Container.Length = 0;
749 Process : not null access procedure (Position : Cursor))
751 C : List renames Container'Unrestricted_Access.all;
752 N : Node_Array renames C.Nodes;
753 -- B : Natural renames C.Busy;
755 Node : Count_Type := Container.First;
757 Index : Count_Type := 0;
758 Index_Max : constant Count_Type := Container.Length;
761 if Index_Max = 0 then
762 pragma Assert (Node = 0);
767 pragma Assert (Node /= 0);
769 Process (Cursor'(C'Unchecked_Access, Node));
770 pragma Assert (Container.Length = Index_Max);
771 pragma Assert (N (Node).Prev /= -1);
773 Node := N (Node).Next;
776 if Index = Index_Max then
777 pragma Assert (Node = 0);
787 function Last (Container : List) return Cursor is
789 if Container.Last = 0 then
793 return Cursor'(Container'Unrestricted_Access, Container.Last);
800 function Last_Element (Container : List) return Element_Type is
801 N : Node_Array renames Container.Nodes;
804 if Container.Last = 0 then
805 raise Constraint_Error;
808 return N (Container.Last).Element;
815 function Length (Container : List) return Count_Type is
817 return Container.Length;
824 procedure Next (Position : in out Cursor) is
826 Position := Next (Position);
829 function Next (Position : Cursor) return Cursor is
831 if Position.Node = 0 then
835 pragma Assert (Vet (Position), "bad cursor in Next");
838 Nodes : Node_Array renames Position.Container.Nodes;
839 Node : constant Count_Type := Nodes (Position.Node).Next;
846 return Cursor'(Position.Container, Node);
855 (Container : in out List;
856 New_Item : Element_Type;
857 Count : Count_Type := 1)
860 Insert (Container, First (Container), New_Item, Count);
867 procedure Previous (Position : in out Cursor) is
869 Position := Previous (Position);
872 function Previous (Position : Cursor) return Cursor is
874 if Position.Node = 0 then
878 pragma Assert (Vet (Position), "bad cursor in Previous");
881 Nodes : Node_Array renames Position.Container.Nodes;
882 Node : constant Count_Type := Nodes (Position.Node).Prev;
888 return Cursor'(Position.Container, Node);
896 procedure Query_Element
898 Process : not null access procedure (Element : Element_Type))
901 if Position.Node = 0 then
902 raise Constraint_Error;
905 pragma Assert (Vet (Position), "bad cursor in Query_Element");
908 C : List renames Position.Container.all'Unrestricted_Access.all;
909 N : Node_Type renames C.Nodes (Position.Node);
913 pragma Assert (N.Prev >= 0);
917 ---------------------
918 -- Replace_Element --
919 ---------------------
921 procedure Replace_Element
922 (Container : in out List;
924 New_Item : Element_Type)
927 if Position.Container = null then
928 raise Constraint_Error;
931 if Position.Container /= Container'Unrestricted_Access then
935 -- if Container.Lock > 0 then
936 -- raise Program_Error;
939 pragma Assert (Vet (Position), "bad cursor in Replace_Element");
942 N : Node_Array renames Container.Nodes;
944 N (Position.Node).Element := New_Item;
948 ----------------------
949 -- Reverse_Elements --
950 ----------------------
952 procedure Reverse_Elements (Container : in out List) is
953 N : Node_Array renames Container.Nodes;
954 I : Count_Type := Container.First;
955 J : Count_Type := Container.Last;
957 procedure Swap (L, R : Count_Type);
963 procedure Swap (L, R : Count_Type) is
964 LN : constant Count_Type := N (L).Next;
965 LP : constant Count_Type := N (L).Prev;
967 RN : constant Count_Type := N (R).Next;
968 RP : constant Count_Type := N (R).Prev;
983 pragma Assert (RP = L);
997 -- Start of processing for Reverse_Elements
1000 if Container.Length <= 1 then
1004 pragma Assert (N (Container.First).Prev = 0);
1005 pragma Assert (N (Container.Last).Next = 0);
1007 -- if Container.Busy > 0 then
1008 -- raise Program_Error;
1011 Container.First := J;
1012 Container.Last := I;
1014 Swap (L => I, R => J);
1022 Swap (L => J, R => I);
1031 pragma Assert (N (Container.First).Prev = 0);
1032 pragma Assert (N (Container.Last).Next = 0);
1033 end Reverse_Elements;
1039 function Reverse_Find
1041 Item : Element_Type;
1042 Position : Cursor := No_Element) return Cursor
1044 N : Node_Array renames Container.Nodes;
1045 Node : Count_Type := Position.Node;
1049 Node := Container.Last;
1052 if Position.Container /= Container'Unrestricted_Access then
1053 raise Program_Error;
1056 pragma Assert (Vet (Position), "bad cursor in Reverse_Find");
1059 while Node /= 0 loop
1060 if N (Node).Element = Item then
1061 return Cursor'(Container'Unrestricted_Access, Node);
1064 Node := N (Node).Prev;
1070 ---------------------
1071 -- Reverse_Iterate --
1072 ---------------------
1074 procedure Reverse_Iterate
1076 Process : not null access procedure (Position : Cursor))
1078 C : List renames Container'Unrestricted_Access.all;
1079 N : Node_Array renames C.Nodes;
1080 -- B : Natural renames C.Busy;
1082 Node : Count_Type := Container.Last;
1084 Index : Count_Type := 0;
1085 Index_Max : constant Count_Type := Container.Length;
1088 if Index_Max = 0 then
1089 pragma Assert (Node = 0);
1094 pragma Assert (Node > 0);
1096 Process (Cursor'(C'Unchecked_Access, Node));
1097 pragma Assert (Container.Length = Index_Max);
1098 pragma Assert (N (Node).Prev /= -1);
1100 Node := N (Node).Prev;
1103 if Index = Index_Max then
1104 pragma Assert (Node = 0);
1108 end Reverse_Iterate;
1115 (Container : in out List;
1117 Position : in out Cursor)
1119 N : Node_Array renames Container.Nodes;
1122 if Before.Container /= null then
1123 if Before.Container /= Container'Unrestricted_Access then
1124 raise Program_Error;
1127 pragma Assert (Vet (Before), "bad Before cursor in Splice");
1130 if Position.Node = 0 then
1131 raise Constraint_Error;
1134 if Position.Container /= Container'Unrestricted_Access then
1135 raise Program_Error;
1138 pragma Assert (Vet (Position), "bad Position cursor in Splice");
1140 if Position.Node = Before.Node
1141 or else N (Position.Node).Next = Before.Node
1146 pragma Assert (Container.Length >= 2);
1148 -- if Container.Busy > 0 then
1149 -- raise Program_Error;
1152 if Before.Node = 0 then
1153 pragma Assert (Position.Node /= Container.Last);
1155 if Position.Node = Container.First then
1156 Container.First := N (Position.Node).Next;
1157 N (Container.First).Prev := 0;
1160 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1161 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1164 N (Container.Last).Next := Position.Node;
1165 N (Position.Node).Prev := Container.Last;
1167 Container.Last := Position.Node;
1168 N (Container.Last).Next := 0;
1173 if Before.Node = Container.First then
1174 pragma Assert (Position.Node /= Container.First);
1176 if Position.Node = Container.Last then
1177 Container.Last := N (Position.Node).Prev;
1178 N (Container.Last).Next := 0;
1181 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1182 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1185 N (Container.First).Prev := Position.Node;
1186 N (Position.Node).Next := Container.First;
1188 Container.First := Position.Node;
1189 N (Container.First).Prev := 0;
1194 if Position.Node = Container.First then
1195 Container.First := N (Position.Node).Next;
1196 N (Container.First).Prev := 0;
1198 elsif Position.Node = Container.Last then
1199 Container.Last := N (Position.Node).Prev;
1200 N (Container.Last).Next := 0;
1203 N (N (Position.Node).Prev).Next := N (Position.Node).Next;
1204 N (N (Position.Node).Next).Prev := N (Position.Node).Prev;
1207 N (N (Before.Node).Prev).Next := Position.Node;
1208 N (Position.Node).Prev := N (Before.Node).Prev;
1210 N (Before.Node).Prev := Position.Node;
1211 N (Position.Node).Next := Before.Node;
1213 pragma Assert (N (Container.First).Prev = 0);
1214 pragma Assert (N (Container.Last).Next = 0);
1222 (Container : in out List;
1229 raise Constraint_Error;
1232 if I.Container /= Container'Unrestricted_Access
1233 or else J.Container /= Container'Unrestricted_Access
1235 raise Program_Error;
1238 if I.Node = J.Node then
1242 -- if Container.Lock > 0 then
1243 -- raise Program_Error;
1246 pragma Assert (Vet (I), "bad I cursor in Swap");
1247 pragma Assert (Vet (J), "bad J cursor in Swap");
1250 N : Node_Array renames Container.Nodes;
1252 EI : Element_Type renames N (I.Node).Element;
1253 EJ : Element_Type renames N (J.Node).Element;
1255 EI_Copy : constant Element_Type := EI;
1267 procedure Swap_Links
1268 (Container : in out List;
1275 raise Constraint_Error;
1278 if I.Container /= Container'Unrestricted_Access
1279 or else I.Container /= J.Container
1281 raise Program_Error;
1284 if I.Node = J.Node then
1288 -- if Container.Busy > 0 then
1289 -- raise Program_Error;
1292 pragma Assert (Vet (I), "bad I cursor in Swap_Links");
1293 pragma Assert (Vet (J), "bad J cursor in Swap_Links");
1296 I_Next : constant Cursor := Next (I);
1298 J_Copy : Cursor := J;
1299 pragma Warnings (Off, J_Copy);
1303 Splice (Container, Before => I, Position => J_Copy);
1307 J_Next : constant Cursor := Next (J);
1309 I_Copy : Cursor := I;
1310 pragma Warnings (Off, I_Copy);
1314 Splice (Container, Before => J, Position => I_Copy);
1317 pragma Assert (Container.Length >= 3);
1319 Splice (Container, Before => I_Next, Position => J_Copy);
1320 Splice (Container, Before => J_Next, Position => I_Copy);
1327 --------------------
1328 -- Update_Element --
1329 --------------------
1331 procedure Update_Element
1332 (Container : in out List;
1334 Process : not null access procedure (Element : in out Element_Type))
1337 if Position.Node = 0 then
1338 raise Constraint_Error;
1341 if Position.Container /= Container'Unrestricted_Access then
1342 raise Program_Error;
1345 pragma Assert (Vet (Position), "bad cursor in Update_Element");
1348 N : Node_Type renames Container.Nodes (Position.Node);
1351 Process (N.Element);
1352 pragma Assert (N.Prev >= 0);
1360 function Vet (Position : Cursor) return Boolean is
1362 if Position.Node = 0 then
1363 return Position.Container = null;
1366 if Position.Container = null then
1371 L : List renames Position.Container.all;
1372 N : Node_Array renames L.Nodes;
1375 if L.Length = 0 then
1387 if Position.Node > L.Capacity then
1391 if N (Position.Node).Prev < 0
1392 or else N (Position.Node).Prev > L.Capacity
1397 if N (Position.Node).Next > L.Capacity then
1401 if N (L.First).Prev /= 0 then
1405 if N (L.Last).Next /= 0 then
1409 if N (Position.Node).Prev = 0
1410 and then Position.Node /= L.First
1415 if N (Position.Node).Next = 0
1416 and then Position.Node /= L.Last
1421 if L.Length = 1 then
1422 return L.First = L.Last;
1425 if L.First = L.Last then
1429 if N (L.First).Next = 0 then
1433 if N (L.Last).Prev = 0 then
1437 if N (N (L.First).Next).Prev /= L.First then
1441 if N (N (L.Last).Prev).Next /= L.Last then
1445 if L.Length = 2 then
1446 if N (L.First).Next /= L.Last then
1450 if N (L.Last).Prev /= L.First then
1457 if N (L.First).Next = L.Last then
1461 if N (L.Last).Prev = L.First then
1465 if Position.Node = L.First then
1469 if Position.Node = L.Last then
1473 if N (Position.Node).Next = 0 then
1477 if N (Position.Node).Prev = 0 then
1481 if N (N (Position.Node).Next).Prev /= Position.Node then
1485 if N (N (Position.Node).Prev).Next /= Position.Node then
1489 if L.Length = 3 then
1490 if N (L.First).Next /= Position.Node then
1494 if N (L.Last).Prev /= Position.Node then
1503 end Ada.Containers.Restricted_Doubly_Linked_Lists;