1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . --
6 -- I N D E F I N I T E _ D O U B L Y _ L I N K E D _ L I S T S --
10 -- Copyright (C) 2004-2005 Free Software Foundation, Inc. --
12 -- This specification is derived from the Ada Reference Manual for use with --
13 -- GNAT. The copyright notice above, and the license provisions that follow --
14 -- apply solely to the contents of the part following the private keyword. --
16 -- GNAT is free software; you can redistribute it and/or modify it under --
17 -- terms of the GNU General Public License as published by the Free Soft- --
18 -- ware Foundation; either version 2, or (at your option) any later ver- --
19 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
20 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
21 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
22 -- for more details. You should have received a copy of the GNU General --
23 -- Public License distributed with GNAT; see file COPYING. If not, write --
24 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
25 -- Boston, MA 02110-1301, USA. --
27 -- As a special exception, if other files instantiate generics from this --
28 -- unit, or you link this unit with other files to produce an executable, --
29 -- this unit does not by itself cause the resulting executable to be --
30 -- covered by the GNU General Public License. This exception does not --
31 -- however invalidate any other reasons why the executable file might be --
32 -- covered by the GNU Public License. --
34 -- This unit was originally developed by Matthew J Heaney. --
35 ------------------------------------------------------------------------------
37 with System; use type System.Address;
38 with Ada.Unchecked_Deallocation;
40 package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
43 new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
45 -----------------------
46 -- Local Subprograms --
47 -----------------------
49 procedure Free (X : in out Node_Access);
51 procedure Insert_Internal
52 (Container : in out List;
54 New_Node : Node_Access);
56 function Vet (Position : Cursor) return Boolean;
62 function "=" (Left, Right : List) return Boolean is
67 if Left'Address = Right'Address then
71 if Left.Length /= Right.Length then
77 for J in 1 .. Left.Length loop
78 if L.Element.all /= R.Element.all then
93 procedure Adjust (Container : in out List) is
94 Src : Node_Access := Container.First;
99 pragma Assert (Container.Last = null);
100 pragma Assert (Container.Length = 0);
101 pragma Assert (Container.Busy = 0);
102 pragma Assert (Container.Lock = 0);
106 pragma Assert (Container.First.Prev = null);
107 pragma Assert (Container.Last.Next = null);
108 pragma Assert (Container.Length > 0);
110 Container.First := null;
111 Container.Last := null;
112 Container.Length := 0;
117 Element : Element_Access := new Element_Type'(Src.Element.all);
119 Dst := new Node_Type'(Element, null, null);
126 Container.First := Dst;
127 Container.Last := Dst;
128 Container.Length := 1;
131 while Src /= null loop
133 Element : Element_Access := new Element_Type'(Src.Element.all);
135 Dst := new Node_Type'(Element, null, Prev => Container.Last);
142 Container.Last.Next := Dst;
143 Container.Last := Dst;
144 Container.Length := Container.Length + 1;
155 (Container : in out List;
156 New_Item : Element_Type;
157 Count : Count_Type := 1)
160 Insert (Container, No_Element, New_Item, Count);
167 procedure Clear (Container : in out List) is
171 if Container.Length = 0 then
172 pragma Assert (Container.First = null);
173 pragma Assert (Container.Last = null);
174 pragma Assert (Container.Busy = 0);
175 pragma Assert (Container.Lock = 0);
179 pragma Assert (Container.First.Prev = null);
180 pragma Assert (Container.Last.Next = null);
182 if Container.Busy > 0 then
186 while Container.Length > 1 loop
187 X := Container.First;
188 pragma Assert (X.Next.Prev = Container.First);
190 Container.First := X.Next;
191 Container.First.Prev := null;
193 Container.Length := Container.Length - 1;
198 X := Container.First;
199 pragma Assert (X = Container.Last);
201 Container.First := null;
202 Container.Last := null;
203 Container.Length := 0;
214 Item : Element_Type) return Boolean is
216 return Find (Container, Item) /= No_Element;
224 (Container : in out List;
225 Position : in out Cursor;
226 Count : Count_Type := 1)
231 pragma Assert (Vet (Position), "bad cursor in Delete");
233 if Position.Node = null then
234 raise Constraint_Error;
237 if Position.Container /= Container'Unrestricted_Access then
241 if Position.Node = Container.First then
242 Delete_First (Container, Count);
243 Position := First (Container);
251 if Container.Busy > 0 then
255 for Index in 1 .. Count loop
257 Container.Length := Container.Length - 1;
259 if X = Container.Last then
260 Position := No_Element;
262 Container.Last := X.Prev;
263 Container.Last.Next := null;
269 Position.Node := X.Next;
271 X.Next.Prev := X.Prev;
272 X.Prev.Next := X.Next;
282 procedure Delete_First
283 (Container : in out List;
284 Count : Count_Type := 1)
289 if Count >= Container.Length then
298 if Container.Busy > 0 then
302 for I in 1 .. Count loop
303 X := Container.First;
304 pragma Assert (X.Next.Prev = Container.First);
306 Container.First := X.Next;
307 Container.First.Prev := null;
309 Container.Length := Container.Length - 1;
319 procedure Delete_Last
320 (Container : in out List;
321 Count : Count_Type := 1)
326 if Count >= Container.Length then
335 if Container.Busy > 0 then
339 for I in 1 .. Count loop
341 pragma Assert (X.Prev.Next = Container.Last);
343 Container.Last := X.Prev;
344 Container.Last.Next := null;
346 Container.Length := Container.Length - 1;
356 function Element (Position : Cursor) return Element_Type is
358 pragma Assert (Vet (Position), "bad cursor in Element");
360 if Position.Node = null then
361 raise Constraint_Error;
364 return Position.Node.Element.all;
374 Position : Cursor := No_Element) return Cursor
376 Node : Node_Access := Position.Node;
380 Node := Container.First;
383 pragma Assert (Vet (Position), "bad cursor in Find");
385 if Position.Container /= Container'Unrestricted_Access then
390 while Node /= null loop
391 if Node.Element.all = Item then
392 return Cursor'(Container'Unchecked_Access, Node);
405 function First (Container : List) return Cursor is
407 if Container.First = null then
411 return Cursor'(Container'Unchecked_Access, Container.First);
418 function First_Element (Container : List) return Element_Type is
420 if Container.First = null then
421 raise Constraint_Error;
424 return Container.First.Element.all;
431 procedure Free (X : in out Node_Access) is
432 procedure Deallocate is
433 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
451 ---------------------
452 -- Generic_Sorting --
453 ---------------------
455 package body Generic_Sorting is
461 function Is_Sorted (Container : List) return Boolean is
462 Node : Node_Access := Container.First;
465 for I in 2 .. Container.Length loop
466 if Node.Next.Element.all < Node.Element.all then
481 (Target : in out List;
482 Source : in out List)
488 if Target'Address = Source'Address then
493 or else Source.Busy > 0
498 LI := First (Target);
499 RI := First (Source);
500 while RI.Node /= null loop
501 if LI.Node = null then
502 Splice (Target, No_Element, Source);
506 if RI.Node.Element.all < LI.Node.Element.all then
510 RI.Node := RI.Node.Next;
511 Splice (Target, LI, Source, RJ);
515 LI.Node := LI.Node.Next;
524 procedure Sort (Container : in out List) is
525 procedure Partition (Pivot : Node_Access; Back : Node_Access);
527 procedure Sort (Front, Back : Node_Access);
533 procedure Partition (Pivot : Node_Access; Back : Node_Access) is
534 Node : Node_Access := Pivot.Next;
537 while Node /= Back loop
538 if Node.Element.all < Pivot.Element.all then
540 Prev : constant Node_Access := Node.Prev;
541 Next : constant Node_Access := Node.Next;
546 Container.Last := Prev;
552 Node.Prev := Pivot.Prev;
556 if Node.Prev = null then
557 Container.First := Node;
559 Node.Prev.Next := Node;
575 procedure Sort (Front, Back : Node_Access) is
580 Pivot := Container.First;
585 if Pivot /= Back then
586 Partition (Pivot, Back);
592 -- Start of processing for Sort
595 if Container.Length <= 1 then
599 pragma Assert (Container.First.Prev = null);
600 pragma Assert (Container.Last.Next = null);
602 if Container.Busy > 0 then
606 Sort (Front => null, Back => null);
608 pragma Assert (Container.First.Prev = null);
609 pragma Assert (Container.Last.Next = null);
618 function Has_Element (Position : Cursor) return Boolean is
620 pragma Assert (Vet (Position), "bad cursor in Has_Element");
621 return Position.Node /= null;
629 (Container : in out List;
631 New_Item : Element_Type;
632 Position : out Cursor;
633 Count : Count_Type := 1)
635 New_Node : Node_Access;
638 pragma Assert (Vet (Before), "bad cursor in Insert");
640 if Before.Container /= null
641 and then Before.Container /= Container'Unrestricted_Access
651 if Container.Length > Count_Type'Last - Count then
652 raise Constraint_Error;
655 if Container.Busy > 0 then
660 Element : Element_Access := new Element_Type'(New_Item);
662 New_Node := new Node_Type'(Element, null, null);
669 Insert_Internal (Container, Before.Node, New_Node);
670 Position := Cursor'(Container'Unchecked_Access, New_Node);
672 for J in Count_Type'(2) .. Count loop
675 Element : Element_Access := new Element_Type'(New_Item);
677 New_Node := new Node_Type'(Element, null, null);
684 Insert_Internal (Container, Before.Node, New_Node);
689 (Container : in out List;
691 New_Item : Element_Type;
692 Count : Count_Type := 1)
696 Insert (Container, Before, New_Item, Position, Count);
699 ---------------------
700 -- Insert_Internal --
701 ---------------------
703 procedure Insert_Internal
704 (Container : in out List;
705 Before : Node_Access;
706 New_Node : Node_Access)
709 if Container.Length = 0 then
710 pragma Assert (Before = null);
711 pragma Assert (Container.First = null);
712 pragma Assert (Container.Last = null);
714 Container.First := New_Node;
715 Container.Last := New_Node;
717 elsif Before = null then
718 pragma Assert (Container.Last.Next = null);
720 Container.Last.Next := New_Node;
721 New_Node.Prev := Container.Last;
723 Container.Last := New_Node;
725 elsif Before = Container.First then
726 pragma Assert (Container.First.Prev = null);
728 Container.First.Prev := New_Node;
729 New_Node.Next := Container.First;
731 Container.First := New_Node;
734 pragma Assert (Container.First.Prev = null);
735 pragma Assert (Container.Last.Next = null);
737 New_Node.Next := Before;
738 New_Node.Prev := Before.Prev;
740 Before.Prev.Next := New_Node;
741 Before.Prev := New_Node;
744 Container.Length := Container.Length + 1;
751 function Is_Empty (Container : List) return Boolean is
753 return Container.Length = 0;
762 Process : not null access procedure (Position : in Cursor))
764 C : List renames Container'Unrestricted_Access.all;
765 B : Natural renames C.Busy;
767 Node : Node_Access := Container.First;
773 while Node /= null loop
774 Process (Cursor'(Container'Unchecked_Access, Node));
790 function Last (Container : List) return Cursor is
792 if Container.Last = null then
796 return Cursor'(Container'Unchecked_Access, Container.Last);
803 function Last_Element (Container : List) return Element_Type is
805 if Container.Last = null then
806 raise Constraint_Error;
809 return Container.Last.Element.all;
816 function Length (Container : List) return Count_Type is
818 return Container.Length;
825 procedure Move (Target : in out List; Source : in out List) is
827 if Target'Address = Source'Address then
831 if Source.Busy > 0 then
837 Target.First := Source.First;
838 Source.First := null;
840 Target.Last := Source.Last;
843 Target.Length := Source.Length;
851 procedure Next (Position : in out Cursor) is
853 pragma Assert (Vet (Position), "bad cursor in procedure Next");
855 if Position.Node = null then
859 Position.Node := Position.Node.Next;
861 if Position.Node = null then
862 Position.Container := null;
866 function Next (Position : Cursor) return Cursor is
868 pragma Assert (Vet (Position), "bad cursor in function Next");
870 if Position.Node = null then
875 Next_Node : constant Node_Access := Position.Node.Next;
877 if Next_Node = null then
881 return Cursor'(Position.Container, Next_Node);
890 (Container : in out List;
891 New_Item : Element_Type;
892 Count : Count_Type := 1)
895 Insert (Container, First (Container), New_Item, Count);
902 procedure Previous (Position : in out Cursor) is
904 pragma Assert (Vet (Position), "bad cursor in procedure Previous");
906 if Position.Node = null then
910 Position.Node := Position.Node.Prev;
912 if Position.Node = null then
913 Position.Container := null;
917 function Previous (Position : Cursor) return Cursor is
919 pragma Assert (Vet (Position), "bad cursor in function Previous");
921 if Position.Node = null then
926 Prev_Node : constant Node_Access := Position.Node.Prev;
928 if Prev_Node = null then
932 return Cursor'(Position.Container, Prev_Node);
940 procedure Query_Element
942 Process : not null access procedure (Element : in Element_Type))
945 pragma Assert (Vet (Position), "bad cursor in Query_Element");
947 if Position.Node = null then
948 raise Constraint_Error;
952 C : List renames Position.Container.all'Unrestricted_Access.all;
953 B : Natural renames C.Busy;
954 L : Natural renames C.Lock;
961 Process (Position.Node.Element.all);
979 (Stream : access Root_Stream_Type'Class;
988 Count_Type'Base'Read (Stream, N);
995 Element : Element_Access :=
996 new Element_Type'(Element_Type'Input (Stream));
998 Dst := new Node_Type'(Element, null, null);
1009 while Item.Length < N loop
1011 Element : Element_Access :=
1012 new Element_Type'(Element_Type'Input (Stream));
1014 Dst := new Node_Type'(Element, Next => null, Prev => Item.Last);
1021 Item.Last.Next := Dst;
1023 Item.Length := Item.Length + 1;
1027 ---------------------
1028 -- Replace_Element --
1029 ---------------------
1031 procedure Replace_Element
1036 pragma Assert (Vet (Position), "bad cursor in Replace_Element");
1038 if Position.Container = null then
1039 raise Constraint_Error;
1042 if Position.Container.Lock > 0 then
1043 raise Program_Error;
1047 X : Element_Access := Position.Node.Element;
1049 Position.Node.Element := new Element_Type'(By);
1052 end Replace_Element;
1058 function Reverse_Find
1060 Item : Element_Type;
1061 Position : Cursor := No_Element) return Cursor
1063 Node : Node_Access := Position.Node;
1067 Node := Container.Last;
1070 pragma Assert (Vet (Position), "bad cursor in Reverse_Find");
1072 if Position.Container /= Container'Unrestricted_Access then
1073 raise Program_Error;
1077 while Node /= null loop
1078 if Node.Element.all = Item then
1079 return Cursor'(Container'Unchecked_Access, Node);
1088 ---------------------
1089 -- Reverse_Iterate --
1090 ---------------------
1092 procedure Reverse_Iterate
1094 Process : not null access procedure (Position : in Cursor))
1096 C : List renames Container'Unrestricted_Access.all;
1097 B : Natural renames C.Busy;
1099 Node : Node_Access := Container.Last;
1105 while Node /= null loop
1106 Process (Cursor'(Container'Unchecked_Access, Node));
1116 end Reverse_Iterate;
1122 procedure Reverse_List (Container : in out List) is
1123 I : Node_Access := Container.First;
1124 J : Node_Access := Container.Last;
1126 procedure Swap (L, R : Node_Access);
1132 procedure Swap (L, R : Node_Access) is
1133 LN : constant Node_Access := L.Next;
1134 LP : constant Node_Access := L.Prev;
1136 RN : constant Node_Access := R.Next;
1137 RP : constant Node_Access := R.Prev;
1152 pragma Assert (RP = L);
1166 -- Start of processing for Reverse_List
1169 if Container.Length <= 1 then
1173 pragma Assert (Container.First.Prev = null);
1174 pragma Assert (Container.Last.Next = null);
1176 if Container.Busy > 0 then
1177 raise Program_Error;
1180 Container.First := J;
1181 Container.Last := I;
1183 Swap (L => I, R => J);
1191 Swap (L => J, R => I);
1200 pragma Assert (Container.First.Prev = null);
1201 pragma Assert (Container.Last.Next = null);
1209 (Target : in out List;
1211 Source : in out List)
1214 pragma Assert (Vet (Before), "bad cursor in Splice");
1216 if Before.Container /= null
1217 and then Before.Container /= Target'Unrestricted_Access
1219 raise Program_Error;
1222 if Target'Address = Source'Address
1223 or else Source.Length = 0
1228 pragma Assert (Source.First.Prev = null);
1229 pragma Assert (Source.Last.Next = null);
1231 if Target.Length > Count_Type'Last - Source.Length then
1232 raise Constraint_Error;
1236 or else Source.Busy > 0
1238 raise Program_Error;
1241 if Target.Length = 0 then
1242 pragma Assert (Before = No_Element);
1243 pragma Assert (Target.First = null);
1244 pragma Assert (Target.Last = null);
1246 Target.First := Source.First;
1247 Target.Last := Source.Last;
1249 elsif Before.Node = null then
1250 pragma Assert (Target.Last.Next = null);
1252 Target.Last.Next := Source.First;
1253 Source.First.Prev := Target.Last;
1255 Target.Last := Source.Last;
1257 elsif Before.Node = Target.First then
1258 pragma Assert (Target.First.Prev = null);
1260 Source.Last.Next := Target.First;
1261 Target.First.Prev := Source.Last;
1263 Target.First := Source.First;
1266 pragma Assert (Target.Length >= 2);
1267 Before.Node.Prev.Next := Source.First;
1268 Source.First.Prev := Before.Node.Prev;
1270 Before.Node.Prev := Source.Last;
1271 Source.Last.Next := Before.Node;
1274 Source.First := null;
1275 Source.Last := null;
1277 Target.Length := Target.Length + Source.Length;
1282 (Target : in out List;
1287 pragma Assert (Vet (Before), "bad Before cursor in Splice");
1288 pragma Assert (Vet (Position), "bad Position cursor in Splice");
1290 if Before.Container /= null
1291 and then Before.Container /= Target'Unchecked_Access
1293 raise Program_Error;
1296 if Position.Node = null then
1297 raise Constraint_Error;
1300 if Position.Container /= Target'Unrestricted_Access then
1301 raise Program_Error;
1304 if Position.Node = Before.Node
1305 or else Position.Node.Next = Before.Node
1310 pragma Assert (Target.Length >= 2);
1312 if Target.Busy > 0 then
1313 raise Program_Error;
1316 if Before.Node = null then
1317 pragma Assert (Position.Node /= Target.Last);
1319 if Position.Node = Target.First then
1320 Target.First := Position.Node.Next;
1321 Target.First.Prev := null;
1323 Position.Node.Prev.Next := Position.Node.Next;
1324 Position.Node.Next.Prev := Position.Node.Prev;
1327 Target.Last.Next := Position.Node;
1328 Position.Node.Prev := Target.Last;
1330 Target.Last := Position.Node;
1331 Target.Last.Next := null;
1336 if Before.Node = Target.First then
1337 pragma Assert (Position.Node /= Target.First);
1339 if Position.Node = Target.Last then
1340 Target.Last := Position.Node.Prev;
1341 Target.Last.Next := null;
1343 Position.Node.Prev.Next := Position.Node.Next;
1344 Position.Node.Next.Prev := Position.Node.Prev;
1347 Target.First.Prev := Position.Node;
1348 Position.Node.Next := Target.First;
1350 Target.First := Position.Node;
1351 Target.First.Prev := null;
1356 if Position.Node = Target.First then
1357 Target.First := Position.Node.Next;
1358 Target.First.Prev := null;
1360 elsif Position.Node = Target.Last then
1361 Target.Last := Position.Node.Prev;
1362 Target.Last.Next := null;
1365 Position.Node.Prev.Next := Position.Node.Next;
1366 Position.Node.Next.Prev := Position.Node.Prev;
1369 Before.Node.Prev.Next := Position.Node;
1370 Position.Node.Prev := Before.Node.Prev;
1372 Before.Node.Prev := Position.Node;
1373 Position.Node.Next := Before.Node;
1375 pragma Assert (Target.First.Prev = null);
1376 pragma Assert (Target.Last.Next = null);
1380 (Target : in out List;
1382 Source : in out List;
1383 Position : in out Cursor)
1386 if Target'Address = Source'Address then
1387 Splice (Target, Before, Position);
1391 pragma Assert (Vet (Before), "bad Before cursor in Splice");
1392 pragma Assert (Vet (Position), "bad Position cursor in Splice");
1394 if Before.Container /= null
1395 and then Before.Container /= Target'Unrestricted_Access
1397 raise Program_Error;
1400 if Position.Node = null then
1401 raise Constraint_Error;
1404 if Position.Container /= Source'Unrestricted_Access then
1405 raise Program_Error;
1408 if Target.Length = Count_Type'Last then
1409 raise Constraint_Error;
1413 or else Source.Busy > 0
1415 raise Program_Error;
1418 if Position.Node = Source.First then
1419 Source.First := Position.Node.Next;
1421 if Position.Node = Source.Last then
1422 pragma Assert (Source.First = null);
1423 pragma Assert (Source.Length = 1);
1424 Source.Last := null;
1427 Source.First.Prev := null;
1430 elsif Position.Node = Source.Last then
1431 pragma Assert (Source.Length >= 2);
1432 Source.Last := Position.Node.Prev;
1433 Source.Last.Next := null;
1436 pragma Assert (Source.Length >= 3);
1437 Position.Node.Prev.Next := Position.Node.Next;
1438 Position.Node.Next.Prev := Position.Node.Prev;
1441 if Target.Length = 0 then
1442 pragma Assert (Before = No_Element);
1443 pragma Assert (Target.First = null);
1444 pragma Assert (Target.Last = null);
1446 Target.First := Position.Node;
1447 Target.Last := Position.Node;
1449 Target.First.Prev := null;
1450 Target.Last.Next := null;
1452 elsif Before.Node = null then
1453 pragma Assert (Target.Last.Next = null);
1454 Target.Last.Next := Position.Node;
1455 Position.Node.Prev := Target.Last;
1457 Target.Last := Position.Node;
1458 Target.Last.Next := null;
1460 elsif Before.Node = Target.First then
1461 pragma Assert (Target.First.Prev = null);
1462 Target.First.Prev := Position.Node;
1463 Position.Node.Next := Target.First;
1465 Target.First := Position.Node;
1466 Target.First.Prev := null;
1469 pragma Assert (Target.Length >= 2);
1470 Before.Node.Prev.Next := Position.Node;
1471 Position.Node.Prev := Before.Node.Prev;
1473 Before.Node.Prev := Position.Node;
1474 Position.Node.Next := Before.Node;
1477 Target.Length := Target.Length + 1;
1478 Source.Length := Source.Length - 1;
1480 Position.Container := Target'Unchecked_Access;
1487 procedure Swap (I, J : Cursor) is
1489 pragma Assert (Vet (I), "bad I cursor in Swap");
1490 pragma Assert (Vet (J), "bad J cursor in Swap");
1493 or else J.Node = null
1495 raise Constraint_Error;
1498 if I.Container /= J.Container then
1499 raise Program_Error;
1502 if I.Node = J.Node then
1506 if I.Container.Lock > 0 then
1507 raise Program_Error;
1511 EI_Copy : constant Element_Access := I.Node.Element;
1513 I.Node.Element := J.Node.Element;
1514 J.Node.Element := EI_Copy;
1522 procedure Swap_Links
1523 (Container : in out List;
1527 pragma Assert (Vet (I), "bad I cursor in Swap_Links");
1528 pragma Assert (Vet (J), "bad J cursor in Swap_Links");
1531 or else J.Node = null
1533 raise Constraint_Error;
1536 if I.Container /= Container'Unrestricted_Access
1537 or else I.Container /= J.Container
1539 raise Program_Error;
1542 if I.Node = J.Node then
1546 if Container.Busy > 0 then
1547 raise Program_Error;
1551 I_Next : constant Cursor := Next (I);
1555 Splice (Container, Before => I, Position => J);
1559 J_Next : constant Cursor := Next (J);
1562 Splice (Container, Before => J, Position => I);
1565 pragma Assert (Container.Length >= 3);
1567 Splice (Container, Before => I_Next, Position => J);
1568 Splice (Container, Before => J_Next, Position => I);
1574 pragma Assert (Container.First.Prev = null);
1575 pragma Assert (Container.Last.Next = null);
1578 --------------------
1579 -- Update_Element --
1580 --------------------
1582 procedure Update_Element
1584 Process : not null access procedure (Element : in out Element_Type))
1587 pragma Assert (Vet (Position), "bad cursor in Update_Element");
1589 if Position.Node = null then
1590 raise Constraint_Error;
1594 C : List renames Position.Container.all'Unrestricted_Access.all;
1595 B : Natural renames C.Busy;
1596 L : Natural renames C.Lock;
1603 Process (Position.Node.Element.all);
1620 function Vet (Position : Cursor) return Boolean is
1622 if Position.Node = null then
1623 return Position.Container = null;
1626 if Position.Container = null then
1630 if Position.Node.Next = Position.Node then
1634 if Position.Node.Prev = Position.Node then
1638 if Position.Node.Element = null then
1643 L : List renames Position.Container.all;
1645 if L.Length = 0 then
1649 if L.First = null then
1653 if L.Last = null then
1657 if L.First.Prev /= null then
1661 if L.Last.Next /= null then
1665 if Position.Node.Prev = null
1666 and then Position.Node /= L.First
1671 if Position.Node.Next = null
1672 and then Position.Node /= L.Last
1677 if L.Length = 1 then
1678 return L.First = L.Last;
1681 if L.First = L.Last then
1685 if L.First.Next = null then
1689 if L.Last.Prev = null then
1693 if L.First.Next.Prev /= L.First then
1697 if L.Last.Prev.Next /= L.Last then
1701 if L.Length = 2 then
1702 if L.First.Next /= L.Last then
1706 if L.Last.Prev /= L.First then
1713 if L.First.Next = L.Last then
1717 if L.Last.Prev = L.First then
1721 if Position.Node = L.First then
1725 if Position.Node = L.Last then
1729 if Position.Node.Next = null then
1733 if Position.Node.Prev = null then
1737 if Position.Node.Next.Prev /= Position.Node then
1741 if Position.Node.Prev.Next /= Position.Node then
1745 if L.Length = 3 then
1746 if L.First.Next /= Position.Node then
1750 if L.Last.Prev /= Position.Node then
1764 (Stream : access Root_Stream_Type'Class;
1767 Node : Node_Access := Item.First;
1770 Count_Type'Base'Write (Stream, Item.Length);
1772 while Node /= null loop
1773 Element_Type'Output (Stream, Node.Element.all); -- X.all
1778 end Ada.Containers.Indefinite_Doubly_Linked_Lists;