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 (Node_Type, Node_Access);
46 new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
48 -----------------------
49 -- Local Subprograms --
50 -----------------------
52 procedure Insert_Internal
53 (Container : in out List;
55 New_Node : Node_Access);
61 function "=" (Left, Right : List) return Boolean is
66 if Left'Address = Right'Address then
70 if Left.Length /= Right.Length then
76 for J in 1 .. Left.Length loop
77 if L.Element.all /= R.Element.all then
92 procedure Adjust (Container : in out List) is
93 Src : Node_Access := Container.First;
98 pragma Assert (Container.Last = null);
99 pragma Assert (Container.Length = 0);
100 pragma Assert (Container.Busy = 0);
101 pragma Assert (Container.Lock = 0);
105 pragma Assert (Container.First.Prev = null);
106 pragma Assert (Container.Last.Next = null);
107 pragma Assert (Container.Length > 0);
109 Container.First := null;
110 Container.Last := null;
111 Container.Length := 0;
116 Element : Element_Access := new Element_Type'(Src.Element.all);
118 Dst := new Node_Type'(Element, null, null);
125 Container.First := Dst;
126 Container.Last := Dst;
127 Container.Length := 1;
130 while Src /= null loop
132 Element : Element_Access := new Element_Type'(Src.Element.all);
134 Dst := new Node_Type'(Element, null, Prev => Container.Last);
141 Container.Last.Next := Dst;
142 Container.Last := Dst;
143 Container.Length := Container.Length + 1;
154 (Container : in out List;
155 New_Item : Element_Type;
156 Count : Count_Type := 1)
159 Insert (Container, No_Element, New_Item, Count);
166 procedure Clear (Container : in out List) is
170 if Container.Length = 0 then
171 pragma Assert (Container.First = null);
172 pragma Assert (Container.Last = null);
173 pragma Assert (Container.Busy = 0);
174 pragma Assert (Container.Lock = 0);
178 pragma Assert (Container.First.Prev = null);
179 pragma Assert (Container.Last.Next = null);
181 if Container.Busy > 0 then
185 while Container.Length > 1 loop
186 X := Container.First;
187 pragma Assert (X.Next.Prev = Container.First);
189 Container.First := X.Next;
190 Container.First.Prev := null;
191 Container.Length := Container.Length - 1;
193 X.Next := null; -- prevent mischief
207 X := Container.First;
208 pragma Assert (X = Container.Last);
210 Container.First := null;
211 Container.Last := null;
212 Container.Length := 0;
232 Item : Element_Type) return Boolean is
234 return Find (Container, Item) /= No_Element;
242 (Container : in out List;
243 Position : in out Cursor;
244 Count : Count_Type := 1)
249 if Position.Node = null then
250 raise Constraint_Error;
253 if Position.Container /= List_Access'(Container'Unchecked_Access) then
257 pragma Assert (Container.Length > 0);
258 pragma Assert (Container.First.Prev = null);
259 pragma Assert (Container.Last.Next = null);
261 pragma Assert (Position.Node.Element /= null);
262 pragma Assert (Position.Node.Prev = null
263 or else Position.Node.Prev.Next = Position.Node);
264 pragma Assert (Position.Node.Next = null
265 or else Position.Node.Next.Prev = Position.Node);
266 pragma Assert (Position.Node.Prev /= null
267 or else Position.Node = Container.First);
268 pragma Assert (Position.Node.Next /= null
269 or else Position.Node = Container.Last);
271 if Position.Node = Container.First then
272 Delete_First (Container, Count);
273 Position := First (Container);
281 if Container.Busy > 0 then
285 for Index in 1 .. Count loop
287 Container.Length := Container.Length - 1;
289 if X = Container.Last then
290 Position := No_Element;
292 Container.Last := X.Prev;
293 Container.Last.Next := null;
295 X.Prev := null; -- prevent mischief
310 Position.Node := X.Next;
312 X.Next.Prev := X.Prev;
313 X.Prev.Next := X.Next;
335 procedure Delete_First
336 (Container : in out List;
337 Count : Count_Type := 1)
342 if Count >= Container.Length then
351 if Container.Busy > 0 then
355 for I in 1 .. Count loop
356 X := Container.First;
357 pragma Assert (X.Next.Prev = Container.First);
359 Container.First := X.Next;
360 Container.First.Prev := null;
362 Container.Length := Container.Length - 1;
364 X.Next := null; -- prevent mischief
383 procedure Delete_Last
384 (Container : in out List;
385 Count : Count_Type := 1)
390 if Count >= Container.Length then
399 if Container.Busy > 0 then
403 for I in 1 .. Count loop
405 pragma Assert (X.Prev.Next = Container.Last);
407 Container.Last := X.Prev;
408 Container.Last.Next := null;
410 Container.Length := Container.Length - 1;
412 X.Prev := null; -- prevent mischief
431 function Element (Position : Cursor) return Element_Type is
433 pragma Assert (Position.Container /= null);
434 pragma Assert (Position.Container.Length > 0);
435 pragma Assert (Position.Container.First.Prev = null);
436 pragma Assert (Position.Container.Last.Next = null);
438 pragma Assert (Position.Node /= null);
439 pragma Assert (Position.Node.Element /= null);
440 pragma Assert (Position.Node.Prev = null
441 or else Position.Node.Prev.Next = Position.Node);
442 pragma Assert (Position.Node.Next = null
443 or else Position.Node.Next.Prev = Position.Node);
444 pragma Assert (Position.Node.Prev /= null
445 or else Position.Node = Position.Container.First);
446 pragma Assert (Position.Node.Next /= null
447 or else Position.Node = Position.Container.Last);
449 return Position.Node.Element.all;
459 Position : Cursor := No_Element) return Cursor
461 Node : Node_Access := Position.Node;
465 Node := Container.First;
468 if Position.Container /= List_Access'(Container'Unchecked_Access) then
472 pragma Assert (Container.Length > 0);
473 pragma Assert (Container.First.Prev = null);
474 pragma Assert (Container.Last.Next = null);
476 pragma Assert (Position.Node.Element /= null);
477 pragma Assert (Position.Node.Prev = null
478 or else Position.Node.Prev.Next = Position.Node);
479 pragma Assert (Position.Node.Next = null
480 or else Position.Node.Next.Prev = Position.Node);
481 pragma Assert (Position.Node.Prev /= null
482 or else Position.Node = Container.First);
483 pragma Assert (Position.Node.Next /= null
484 or else Position.Node = Container.Last);
487 while Node /= null loop
488 if Node.Element.all = Item then
489 return Cursor'(Container'Unchecked_Access, Node);
502 function First (Container : List) return Cursor is
504 if Container.First = null then
508 return Cursor'(Container'Unchecked_Access, Container.First);
515 function First_Element (Container : List) return Element_Type is
517 return Container.First.Element.all;
520 ---------------------
521 -- Generic_Sorting --
522 ---------------------
524 package body Generic_Sorting is
530 function Is_Sorted (Container : List) return Boolean is
531 Node : Node_Access := Container.First;
534 for I in 2 .. Container.Length loop
535 if Node.Next.Element.all < Node.Element.all then
550 (Target : in out List;
551 Source : in out List)
557 if Target'Address = Source'Address then
562 or else Source.Busy > 0
567 LI := First (Target);
568 RI := First (Source);
569 while RI.Node /= null loop
570 if LI.Node = null then
571 Splice (Target, No_Element, Source);
575 if RI.Node.Element.all < LI.Node.Element.all then
579 RI.Node := RI.Node.Next;
580 Splice (Target, LI, Source, RJ);
584 LI.Node := LI.Node.Next;
593 procedure Sort (Container : in out List) is
594 procedure Partition (Pivot : Node_Access; Back : Node_Access);
596 procedure Sort (Front, Back : Node_Access);
602 procedure Partition (Pivot : Node_Access; Back : Node_Access) is
603 Node : Node_Access := Pivot.Next;
606 while Node /= Back loop
607 if Node.Element.all < Pivot.Element.all then
609 Prev : constant Node_Access := Node.Prev;
610 Next : constant Node_Access := Node.Next;
615 Container.Last := Prev;
621 Node.Prev := Pivot.Prev;
625 if Node.Prev = null then
626 Container.First := Node;
628 Node.Prev.Next := Node;
644 procedure Sort (Front, Back : Node_Access) is
649 Pivot := Container.First;
654 if Pivot /= Back then
655 Partition (Pivot, Back);
661 -- Start of processing for Sort
664 if Container.Length <= 1 then
668 pragma Assert (Container.First.Prev = null);
669 pragma Assert (Container.Last.Next = null);
671 if Container.Busy > 0 then
675 Sort (Front => null, Back => null);
677 pragma Assert (Container.First.Prev = null);
678 pragma Assert (Container.Last.Next = null);
687 function Has_Element (Position : Cursor) return Boolean is
689 if Position.Node = null then
690 pragma Assert (Position.Container = null);
694 pragma Assert (Position.Container /= null);
695 pragma Assert (Position.Container.Length > 0);
696 pragma Assert (Position.Container.First.Prev = null);
697 pragma Assert (Position.Container.Last.Next = null);
699 pragma Assert (Position.Node.Element /= null);
700 pragma Assert (Position.Node.Prev = null
701 or else Position.Node.Prev.Next = Position.Node);
702 pragma Assert (Position.Node.Next = null
703 or else Position.Node.Next.Prev = Position.Node);
704 pragma Assert (Position.Node.Prev /= null
705 or else Position.Node = Position.Container.First);
706 pragma Assert (Position.Node.Next /= null
707 or else Position.Node = Position.Container.Last);
717 (Container : in out List;
719 New_Item : Element_Type;
720 Position : out Cursor;
721 Count : Count_Type := 1)
723 New_Node : Node_Access;
726 if Before.Node /= null then
727 if Before.Container /= List_Access'(Container'Unchecked_Access) then
731 pragma Assert (Container.Length > 0);
732 pragma Assert (Container.First.Prev = null);
733 pragma Assert (Container.Last.Next = null);
735 pragma Assert (Before.Node.Element /= null);
736 pragma Assert (Before.Node.Prev = null
737 or else Before.Node.Prev.Next = Before.Node);
738 pragma Assert (Before.Node.Next = null
739 or else Before.Node.Next.Prev = Before.Node);
740 pragma Assert (Before.Node.Prev /= null
741 or else Before.Node = Container.First);
742 pragma Assert (Before.Node.Next /= null
743 or else Before.Node = Container.Last);
751 if Container.Length > Count_Type'Last - Count then
752 raise Constraint_Error;
755 if Container.Busy > 0 then
760 Element : Element_Access := new Element_Type'(New_Item);
762 New_Node := new Node_Type'(Element, null, null);
769 Insert_Internal (Container, Before.Node, New_Node);
770 Position := Cursor'(Container'Unchecked_Access, New_Node);
772 for J in Count_Type'(2) .. Count loop
775 Element : Element_Access := new Element_Type'(New_Item);
777 New_Node := new Node_Type'(Element, null, null);
784 Insert_Internal (Container, Before.Node, New_Node);
789 (Container : in out List;
791 New_Item : Element_Type;
792 Count : Count_Type := 1)
796 Insert (Container, Before, New_Item, Position, Count);
799 ---------------------
800 -- Insert_Internal --
801 ---------------------
803 procedure Insert_Internal
804 (Container : in out List;
805 Before : Node_Access;
806 New_Node : Node_Access)
809 if Container.Length = 0 then
810 pragma Assert (Before = null);
811 pragma Assert (Container.First = null);
812 pragma Assert (Container.Last = null);
814 Container.First := New_Node;
815 Container.Last := New_Node;
817 elsif Before = null then
818 pragma Assert (Container.Last.Next = null);
820 Container.Last.Next := New_Node;
821 New_Node.Prev := Container.Last;
823 Container.Last := New_Node;
825 elsif Before = Container.First then
826 pragma Assert (Container.First.Prev = null);
828 Container.First.Prev := New_Node;
829 New_Node.Next := Container.First;
831 Container.First := New_Node;
834 pragma Assert (Container.First.Prev = null);
835 pragma Assert (Container.Last.Next = null);
837 New_Node.Next := Before;
838 New_Node.Prev := Before.Prev;
840 Before.Prev.Next := New_Node;
841 Before.Prev := New_Node;
844 Container.Length := Container.Length + 1;
851 function Is_Empty (Container : List) return Boolean is
853 return Container.Length = 0;
862 Process : not null access procedure (Position : in Cursor))
864 C : List renames Container'Unrestricted_Access.all;
865 B : Natural renames C.Busy;
867 Node : Node_Access := Container.First;
873 while Node /= null loop
874 Process (Cursor'(Container'Unchecked_Access, Node));
890 procedure Move (Target : in out List; Source : in out List) is
892 if Target'Address = Source'Address then
896 if Source.Busy > 0 then
902 Target.First := Source.First;
903 Source.First := null;
905 Target.Last := Source.Last;
908 Target.Length := Source.Length;
916 function Last (Container : List) return Cursor is
918 if Container.Last = null then
922 return Cursor'(Container'Unchecked_Access, Container.Last);
929 function Last_Element (Container : List) return Element_Type is
931 return Container.Last.Element.all;
938 function Length (Container : List) return Count_Type is
940 return Container.Length;
947 procedure Next (Position : in out Cursor) is
949 if Position.Node = null then
950 pragma Assert (Position.Container = null);
954 pragma Assert (Position.Container /= null);
955 pragma Assert (Position.Container.Length > 0);
956 pragma Assert (Position.Container.First.Prev = null);
957 pragma Assert (Position.Container.Last.Next = null);
959 pragma Assert (Position.Node.Element /= null);
960 pragma Assert (Position.Node.Prev = null
961 or else Position.Node.Prev.Next = Position.Node);
962 pragma Assert (Position.Node.Next = null
963 or else Position.Node.Next.Prev = Position.Node);
964 pragma Assert (Position.Node.Prev /= null
965 or else Position.Node = Position.Container.First);
966 pragma Assert (Position.Node.Next /= null
967 or else Position.Node = Position.Container.Last);
969 Position.Node := Position.Node.Next;
971 if Position.Node = null then
972 Position.Container := null;
976 function Next (Position : Cursor) return Cursor is
978 if Position.Node = null then
979 pragma Assert (Position.Container = null);
983 pragma Assert (Position.Container /= null);
984 pragma Assert (Position.Container.Length > 0);
985 pragma Assert (Position.Container.First.Prev = null);
986 pragma Assert (Position.Container.Last.Next = null);
988 pragma Assert (Position.Node.Element /= null);
989 pragma Assert (Position.Node.Prev = null
990 or else Position.Node.Prev.Next = Position.Node);
991 pragma Assert (Position.Node.Next = null
992 or else Position.Node.Next.Prev = Position.Node);
993 pragma Assert (Position.Node.Prev /= null
994 or else Position.Node = Position.Container.First);
995 pragma Assert (Position.Node.Next /= null
996 or else Position.Node = Position.Container.Last);
999 Next_Node : constant Node_Access := Position.Node.Next;
1001 if Next_Node = null then
1005 return Cursor'(Position.Container, Next_Node);
1014 (Container : in out List;
1015 New_Item : Element_Type;
1016 Count : Count_Type := 1)
1019 Insert (Container, First (Container), New_Item, Count);
1026 procedure Previous (Position : in out Cursor) is
1028 if Position.Node = null then
1029 pragma Assert (Position.Container = null);
1033 pragma Assert (Position.Container /= null);
1034 pragma Assert (Position.Container.Length > 0);
1035 pragma Assert (Position.Container.First.Prev = null);
1036 pragma Assert (Position.Container.Last.Next = null);
1038 pragma Assert (Position.Node.Element /= null);
1039 pragma Assert (Position.Node.Prev = null
1040 or else Position.Node.Prev.Next = Position.Node);
1041 pragma Assert (Position.Node.Next = null
1042 or else Position.Node.Next.Prev = Position.Node);
1043 pragma Assert (Position.Node.Prev /= null
1044 or else Position.Node = Position.Container.First);
1045 pragma Assert (Position.Node.Next /= null
1046 or else Position.Node = Position.Container.Last);
1048 Position.Node := Position.Node.Prev;
1050 if Position.Node = null then
1051 Position.Container := null;
1055 function Previous (Position : Cursor) return Cursor is
1057 if Position.Node = null then
1058 pragma Assert (Position.Container = null);
1062 pragma Assert (Position.Container /= null);
1063 pragma Assert (Position.Container.Length > 0);
1064 pragma Assert (Position.Container.First.Prev = null);
1065 pragma Assert (Position.Container.Last.Next = null);
1067 pragma Assert (Position.Node.Element /= null);
1068 pragma Assert (Position.Node.Prev = null
1069 or else Position.Node.Prev.Next = Position.Node);
1070 pragma Assert (Position.Node.Next = null
1071 or else Position.Node.Next.Prev = Position.Node);
1072 pragma Assert (Position.Node.Prev /= null
1073 or else Position.Node = Position.Container.First);
1074 pragma Assert (Position.Node.Next /= null
1075 or else Position.Node = Position.Container.Last);
1078 Prev_Node : constant Node_Access := Position.Node.Prev;
1080 if Prev_Node = null then
1084 return Cursor'(Position.Container, Prev_Node);
1092 procedure Query_Element
1094 Process : not null access procedure (Element : in Element_Type))
1096 pragma Assert (Position.Container /= null);
1097 pragma Assert (Position.Container.Length > 0);
1098 pragma Assert (Position.Container.First.Prev = null);
1099 pragma Assert (Position.Container.Last.Next = null);
1101 pragma Assert (Position.Node /= null);
1102 pragma Assert (Position.Node.Element /= null);
1103 pragma Assert (Position.Node.Prev = null
1104 or else Position.Node.Prev.Next = Position.Node);
1105 pragma Assert (Position.Node.Next = null
1106 or else Position.Node.Next.Prev = Position.Node);
1107 pragma Assert (Position.Node.Prev /= null
1108 or else Position.Node = Position.Container.First);
1109 pragma Assert (Position.Node.Next /= null
1110 or else Position.Node = Position.Container.Last);
1112 E : Element_Type renames Position.Node.Element.all;
1114 C : List renames Position.Container.all'Unrestricted_Access.all;
1115 B : Natural renames C.Busy;
1116 L : Natural renames C.Lock;
1140 (Stream : access Root_Stream_Type'Class;
1143 N : Count_Type'Base;
1149 Count_Type'Base'Read (Stream, N);
1156 Element : Element_Access :=
1157 new Element_Type'(Element_Type'Input (Stream));
1159 Dst := new Node_Type'(Element, null, null);
1170 while Item.Length < N loop
1172 Element : Element_Access :=
1173 new Element_Type'(Element_Type'Input (Stream));
1175 Dst := new Node_Type'(Element, Next => null, Prev => Item.Last);
1182 Item.Last.Next := Dst;
1184 Item.Length := Item.Length + 1;
1188 ---------------------
1189 -- Replace_Element --
1190 ---------------------
1192 procedure Replace_Element
1196 pragma Assert (Position.Container /= null);
1197 pragma Assert (Position.Container.Length > 0);
1198 pragma Assert (Position.Container.First.Prev = null);
1199 pragma Assert (Position.Container.Last.Next = null);
1201 pragma Assert (Position.Node /= null);
1202 pragma Assert (Position.Node.Element /= null);
1203 pragma Assert (Position.Node.Prev = null
1204 or else Position.Node.Prev.Next = Position.Node);
1205 pragma Assert (Position.Node.Next = null
1206 or else Position.Node.Next.Prev = Position.Node);
1207 pragma Assert (Position.Node.Prev /= null
1208 or else Position.Node = Position.Container.First);
1209 pragma Assert (Position.Node.Next /= null
1210 or else Position.Node = Position.Container.Last);
1212 X : Element_Access := Position.Node.Element;
1215 if Position.Container.Lock > 0 then
1216 raise Program_Error;
1219 Position.Node.Element := new Element_Type'(By);
1221 end Replace_Element;
1227 function Reverse_Find
1229 Item : Element_Type;
1230 Position : Cursor := No_Element) return Cursor
1232 Node : Node_Access := Position.Node;
1236 Node := Container.Last;
1239 if Position.Container /= List_Access'(Container'Unchecked_Access) then
1240 raise Program_Error;
1243 pragma Assert (Container.Length > 0);
1244 pragma Assert (Container.First.Prev = null);
1245 pragma Assert (Container.Last.Next = null);
1247 pragma Assert (Position.Node.Element /= null);
1248 pragma Assert (Position.Node.Prev = null
1249 or else Position.Node.Prev.Next = Position.Node);
1250 pragma Assert (Position.Node.Next = null
1251 or else Position.Node.Next.Prev = Position.Node);
1252 pragma Assert (Position.Node.Prev /= null
1253 or else Position.Node = Container.First);
1254 pragma Assert (Position.Node.Next /= null
1255 or else Position.Node = Container.Last);
1258 while Node /= null loop
1259 if Node.Element.all = Item then
1260 return Cursor'(Container'Unchecked_Access, Node);
1269 ---------------------
1270 -- Reverse_Iterate --
1271 ---------------------
1273 procedure Reverse_Iterate
1275 Process : not null access procedure (Position : in Cursor))
1277 C : List renames Container'Unrestricted_Access.all;
1278 B : Natural renames C.Busy;
1280 Node : Node_Access := Container.Last;
1286 while Node /= null loop
1287 Process (Cursor'(Container'Unchecked_Access, Node));
1297 end Reverse_Iterate;
1303 procedure Reverse_List (Container : in out List) is
1304 I : Node_Access := Container.First;
1305 J : Node_Access := Container.Last;
1307 procedure Swap (L, R : Node_Access);
1313 procedure Swap (L, R : Node_Access) is
1314 LN : constant Node_Access := L.Next;
1315 LP : constant Node_Access := L.Prev;
1317 RN : constant Node_Access := R.Next;
1318 RP : constant Node_Access := R.Prev;
1333 pragma Assert (RP = L);
1347 -- Start of processing for Reverse_List
1350 if Container.Length <= 1 then
1354 pragma Assert (Container.First.Prev = null);
1355 pragma Assert (Container.Last.Next = null);
1357 if Container.Busy > 0 then
1358 raise Program_Error;
1361 Container.First := J;
1362 Container.Last := I;
1364 Swap (L => I, R => J);
1372 Swap (L => J, R => I);
1381 pragma Assert (Container.First.Prev = null);
1382 pragma Assert (Container.Last.Next = null);
1390 (Target : in out List;
1392 Source : in out List)
1395 if Before.Node /= null then
1396 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1397 raise Program_Error;
1400 pragma Assert (Target.Length >= 1);
1401 pragma Assert (Target.First.Prev = null);
1402 pragma Assert (Target.Last.Next = null);
1404 pragma Assert (Before.Node.Element /= null);
1405 pragma Assert (Before.Node.Prev = null
1406 or else Before.Node.Prev.Next = Before.Node);
1407 pragma Assert (Before.Node.Next = null
1408 or else Before.Node.Next.Prev = Before.Node);
1409 pragma Assert (Before.Node.Prev /= null
1410 or else Before.Node = Target.First);
1411 pragma Assert (Before.Node.Next /= null
1412 or else Before.Node = Target.Last);
1415 if Target'Address = Source'Address
1416 or else Source.Length = 0
1421 pragma Assert (Source.First.Prev = null);
1422 pragma Assert (Source.Last.Next = null);
1424 if Target.Length > Count_Type'Last - Source.Length then
1425 raise Constraint_Error;
1429 or else Source.Busy > 0
1431 raise Program_Error;
1434 if Target.Length = 0 then
1435 pragma Assert (Before = No_Element);
1436 pragma Assert (Target.First = null);
1437 pragma Assert (Target.Last = null);
1439 Target.First := Source.First;
1440 Target.Last := Source.Last;
1442 elsif Before.Node = null then
1443 pragma Assert (Target.Last.Next = null);
1445 Target.Last.Next := Source.First;
1446 Source.First.Prev := Target.Last;
1448 Target.Last := Source.Last;
1450 elsif Before.Node = Target.First then
1451 pragma Assert (Target.First.Prev = null);
1453 Source.Last.Next := Target.First;
1454 Target.First.Prev := Source.Last;
1456 Target.First := Source.First;
1459 pragma Assert (Target.Length >= 2);
1460 Before.Node.Prev.Next := Source.First;
1461 Source.First.Prev := Before.Node.Prev;
1463 Before.Node.Prev := Source.Last;
1464 Source.Last.Next := Before.Node;
1467 Source.First := null;
1468 Source.Last := null;
1470 Target.Length := Target.Length + Source.Length;
1475 (Target : in out List;
1480 if Before.Node /= null then
1481 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1482 raise Program_Error;
1485 pragma Assert (Target.Length >= 1);
1486 pragma Assert (Target.First.Prev = null);
1487 pragma Assert (Target.Last.Next = null);
1489 pragma Assert (Before.Node.Element /= null);
1490 pragma Assert (Before.Node.Prev = null
1491 or else Before.Node.Prev.Next = Before.Node);
1492 pragma Assert (Before.Node.Next = null
1493 or else Before.Node.Next.Prev = Before.Node);
1494 pragma Assert (Before.Node.Prev /= null
1495 or else Before.Node = Target.First);
1496 pragma Assert (Before.Node.Next /= null
1497 or else Before.Node = Target.Last);
1500 if Position.Node = null then
1501 raise Constraint_Error;
1504 if Position.Container /= List_Access'(Target'Unchecked_Access) then
1505 raise Program_Error;
1508 pragma Assert (Target.Length >= 1);
1509 pragma Assert (Target.First.Prev = null);
1510 pragma Assert (Target.Last.Next = null);
1512 pragma Assert (Position.Node.Element /= null);
1513 pragma Assert (Position.Node.Prev = null
1514 or else Position.Node.Prev.Next = Position.Node);
1515 pragma Assert (Position.Node.Next = null
1516 or else Position.Node.Next.Prev = Position.Node);
1517 pragma Assert (Position.Node.Prev /= null
1518 or else Position.Node = Target.First);
1519 pragma Assert (Position.Node.Next /= null
1520 or else Position.Node = Target.Last);
1522 if Position.Node = Before.Node
1523 or else Position.Node.Next = Before.Node
1528 pragma Assert (Target.Length >= 2);
1530 if Target.Busy > 0 then
1531 raise Program_Error;
1534 if Before.Node = null then
1535 pragma Assert (Position.Node /= Target.Last);
1537 if Position.Node = Target.First then
1538 Target.First := Position.Node.Next;
1539 Target.First.Prev := null;
1541 Position.Node.Prev.Next := Position.Node.Next;
1542 Position.Node.Next.Prev := Position.Node.Prev;
1545 Target.Last.Next := Position.Node;
1546 Position.Node.Prev := Target.Last;
1548 Target.Last := Position.Node;
1549 Target.Last.Next := null;
1554 if Before.Node = Target.First then
1555 pragma Assert (Position.Node /= Target.First);
1557 if Position.Node = Target.Last then
1558 Target.Last := Position.Node.Prev;
1559 Target.Last.Next := null;
1561 Position.Node.Prev.Next := Position.Node.Next;
1562 Position.Node.Next.Prev := Position.Node.Prev;
1565 Target.First.Prev := Position.Node;
1566 Position.Node.Next := Target.First;
1568 Target.First := Position.Node;
1569 Target.First.Prev := null;
1574 if Position.Node = Target.First then
1575 Target.First := Position.Node.Next;
1576 Target.First.Prev := null;
1578 elsif Position.Node = Target.Last then
1579 Target.Last := Position.Node.Prev;
1580 Target.Last.Next := null;
1583 Position.Node.Prev.Next := Position.Node.Next;
1584 Position.Node.Next.Prev := Position.Node.Prev;
1587 Before.Node.Prev.Next := Position.Node;
1588 Position.Node.Prev := Before.Node.Prev;
1590 Before.Node.Prev := Position.Node;
1591 Position.Node.Next := Before.Node;
1593 pragma Assert (Target.First.Prev = null);
1594 pragma Assert (Target.Last.Next = null);
1598 (Target : in out List;
1600 Source : in out List;
1601 Position : in out Cursor)
1604 if Target'Address = Source'Address then
1605 Splice (Target, Before, Position);
1609 if Before.Node /= null then
1610 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1611 raise Program_Error;
1614 pragma Assert (Target.Length >= 1);
1615 pragma Assert (Target.First.Prev = null);
1616 pragma Assert (Target.Last.Next = null);
1618 pragma Assert (Before.Node.Element /= null);
1619 pragma Assert (Before.Node.Prev = null
1620 or else Before.Node.Prev.Next = Before.Node);
1621 pragma Assert (Before.Node.Next = null
1622 or else Before.Node.Next.Prev = Before.Node);
1623 pragma Assert (Before.Node.Prev /= null
1624 or else Before.Node = Target.First);
1625 pragma Assert (Before.Node.Next /= null
1626 or else Before.Node = Target.Last);
1629 if Position.Node = null then
1630 raise Constraint_Error;
1633 if Position.Container /= List_Access'(Source'Unchecked_Access) then
1634 raise Program_Error;
1637 pragma Assert (Source.Length >= 1);
1638 pragma Assert (Source.First.Prev = null);
1639 pragma Assert (Source.Last.Next = null);
1641 pragma Assert (Position.Node.Element /= null);
1642 pragma Assert (Position.Node.Prev = null
1643 or else Position.Node.Prev.Next = Position.Node);
1644 pragma Assert (Position.Node.Next = null
1645 or else Position.Node.Next.Prev = Position.Node);
1646 pragma Assert (Position.Node.Prev /= null
1647 or else Position.Node = Source.First);
1648 pragma Assert (Position.Node.Next /= null
1649 or else Position.Node = Source.Last);
1651 if Target.Length = Count_Type'Last then
1652 raise Constraint_Error;
1656 or else Source.Busy > 0
1658 raise Program_Error;
1661 if Position.Node = Source.First then
1662 Source.First := Position.Node.Next;
1663 Source.First.Prev := null;
1665 if Position.Node = Source.Last then
1666 pragma Assert (Source.First = null);
1667 pragma Assert (Source.Length = 1);
1668 Source.Last := null;
1671 elsif Position.Node = Source.Last then
1672 pragma Assert (Source.Length >= 2);
1673 Source.Last := Position.Node.Prev;
1674 Source.Last.Next := null;
1677 pragma Assert (Source.Length >= 3);
1678 Position.Node.Prev.Next := Position.Node.Next;
1679 Position.Node.Next.Prev := Position.Node.Prev;
1682 if Target.Length = 0 then
1683 pragma Assert (Before = No_Element);
1684 pragma Assert (Target.First = null);
1685 pragma Assert (Target.Last = null);
1687 Target.First := Position.Node;
1688 Target.Last := Position.Node;
1690 Target.First.Prev := null;
1691 Target.Last.Next := null;
1693 elsif Before.Node = null then
1694 pragma Assert (Target.Last.Next = null);
1695 Target.Last.Next := Position.Node;
1696 Position.Node.Prev := Target.Last;
1698 Target.Last := Position.Node;
1699 Target.Last.Next := null;
1701 elsif Before.Node = Target.First then
1702 pragma Assert (Target.First.Prev = null);
1703 Target.First.Prev := Position.Node;
1704 Position.Node.Next := Target.First;
1706 Target.First := Position.Node;
1707 Target.First.Prev := null;
1710 pragma Assert (Target.Length >= 2);
1711 Before.Node.Prev.Next := Position.Node;
1712 Position.Node.Prev := Before.Node.Prev;
1714 Before.Node.Prev := Position.Node;
1715 Position.Node.Next := Before.Node;
1718 Target.Length := Target.Length + 1;
1719 Source.Length := Source.Length - 1;
1721 Position.Container := Target'Unchecked_Access;
1728 procedure Swap (I, J : Cursor) is
1730 if I.Container = null
1731 or else J.Container = null
1733 raise Constraint_Error;
1736 if I.Container /= J.Container then
1737 raise Program_Error;
1741 C : List renames I.Container.all;
1743 pragma Assert (C.Length > 0);
1744 pragma Assert (C.First.Prev = null);
1745 pragma Assert (C.Last.Next = null);
1747 pragma Assert (I.Node /= null);
1748 pragma Assert (I.Node.Element /= null);
1749 pragma Assert (I.Node.Prev = null
1750 or else I.Node.Prev.Next = I.Node);
1751 pragma Assert (I.Node.Next = null
1752 or else I.Node.Next.Prev = I.Node);
1753 pragma Assert (I.Node.Prev /= null
1754 or else I.Node = C.First);
1755 pragma Assert (I.Node.Next /= null
1756 or else I.Node = C.Last);
1758 if I.Node = J.Node then
1762 pragma Assert (C.Length > 1);
1763 pragma Assert (J.Node /= null);
1764 pragma Assert (J.Node.Element /= null);
1765 pragma Assert (J.Node.Prev = null
1766 or else J.Node.Prev.Next = J.Node);
1767 pragma Assert (J.Node.Next = null
1768 or else J.Node.Next.Prev = J.Node);
1769 pragma Assert (J.Node.Prev /= null
1770 or else J.Node = C.First);
1771 pragma Assert (J.Node.Next /= null
1772 or else J.Node = C.Last);
1775 raise Program_Error;
1779 EI_Copy : constant Element_Access := I.Node.Element;
1781 I.Node.Element := J.Node.Element;
1782 J.Node.Element := EI_Copy;
1791 procedure Swap_Links
1792 (Container : in out List;
1796 if I.Container = null
1797 or else J.Container = null
1799 raise Constraint_Error;
1802 if I.Container /= List_Access'(Container'Unchecked_Access) then
1803 raise Program_Error;
1806 if J.Container /= I.Container then
1807 raise Program_Error;
1810 pragma Assert (Container.Length >= 1);
1811 pragma Assert (Container.First.Prev = null);
1812 pragma Assert (Container.Last.Next = null);
1814 pragma Assert (I.Node /= null);
1815 pragma Assert (I.Node.Element /= null);
1816 pragma Assert (I.Node.Prev = null
1817 or else I.Node.Prev.Next = I.Node);
1818 pragma Assert (I.Node.Next = null
1819 or else I.Node.Next.Prev = I.Node);
1820 pragma Assert (I.Node.Prev /= null
1821 or else I.Node = Container.First);
1822 pragma Assert (I.Node.Next /= null
1823 or else I.Node = Container.Last);
1825 if I.Node = J.Node then
1829 pragma Assert (Container.Length >= 2);
1830 pragma Assert (J.Node /= null);
1831 pragma Assert (J.Node.Element /= null);
1832 pragma Assert (J.Node.Prev = null
1833 or else J.Node.Prev.Next = J.Node);
1834 pragma Assert (J.Node.Next = null
1835 or else J.Node.Next.Prev = J.Node);
1836 pragma Assert (J.Node.Prev /= null
1837 or else J.Node = Container.First);
1838 pragma Assert (J.Node.Next /= null
1839 or else J.Node = Container.Last);
1841 if Container.Busy > 0 then
1842 raise Program_Error;
1846 I_Next : constant Cursor := Next (I);
1850 Splice (Container, Before => I, Position => J);
1854 J_Next : constant Cursor := Next (J);
1857 Splice (Container, Before => J, Position => I);
1860 pragma Assert (Container.Length >= 3);
1862 Splice (Container, Before => I_Next, Position => J);
1863 Splice (Container, Before => J_Next, Position => I);
1869 pragma Assert (Container.First.Prev = null);
1870 pragma Assert (Container.Last.Next = null);
1873 --------------------
1874 -- Update_Element --
1875 --------------------
1877 procedure Update_Element
1879 Process : not null access procedure (Element : in out Element_Type))
1881 pragma Assert (Position.Container /= null);
1882 pragma Assert (Position.Container.Length > 0);
1883 pragma Assert (Position.Container.First.Prev = null);
1884 pragma Assert (Position.Container.Last.Next = null);
1886 pragma Assert (Position.Node /= null);
1887 pragma Assert (Position.Node.Element /= null);
1888 pragma Assert (Position.Node.Prev = null
1889 or else Position.Node.Prev.Next = Position.Node);
1890 pragma Assert (Position.Node.Next = null
1891 or else Position.Node.Next.Prev = Position.Node);
1892 pragma Assert (Position.Node.Prev /= null
1893 or else Position.Node = Position.Container.First);
1894 pragma Assert (Position.Node.Next /= null
1895 or else Position.Node = Position.Container.Last);
1897 E : Element_Type renames Position.Node.Element.all;
1899 C : List renames Position.Container.all'Unrestricted_Access.all;
1900 B : Natural renames C.Busy;
1901 L : Natural renames C.Lock;
1925 (Stream : access Root_Stream_Type'Class;
1928 Node : Node_Access := Item.First;
1930 Count_Type'Base'Write (Stream, Item.Length);
1931 while Node /= null loop
1932 Element_Type'Output (Stream, Node.Element.all); -- X.all
1937 end Ada.Containers.Indefinite_Doubly_Linked_Lists;