1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . D O U B L Y _ L I N K E D _ L I S T S --
9 -- Copyright (C) 2004-2005 Free Software Foundation, Inc. --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 2, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
24 -- Boston, MA 02110-1301, USA. --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
33 -- This unit was originally developed by Matthew J Heaney. --
34 ------------------------------------------------------------------------------
36 with System; use type System.Address;
37 with Ada.Unchecked_Deallocation;
39 package body Ada.Containers.Doubly_Linked_Lists is
42 new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
44 -----------------------
45 -- Local Subprograms --
46 -----------------------
48 procedure Insert_Internal
49 (Container : in out List;
51 New_Node : Node_Access);
57 function "=" (Left, Right : List) return Boolean is
58 L : Node_Access := Left.First;
59 R : Node_Access := Right.First;
62 if Left'Address = Right'Address then
66 if Left.Length /= Right.Length then
70 for J in 1 .. Left.Length loop
71 if L.Element /= R.Element then
86 procedure Adjust (Container : in out List) is
87 Src : Node_Access := Container.First;
91 pragma Assert (Container.Last = null);
92 pragma Assert (Container.Length = 0);
93 pragma Assert (Container.Busy = 0);
94 pragma Assert (Container.Lock = 0);
98 pragma Assert (Container.First.Prev = null);
99 pragma Assert (Container.Last.Next = null);
100 pragma Assert (Container.Length > 0);
102 Container.First := null;
103 Container.Last := null;
104 Container.Length := 0;
108 Container.First := new Node_Type'(Src.Element, null, null);
109 Container.Last := Container.First;
110 Container.Length := 1;
114 while Src /= null loop
115 Container.Last.Next := new Node_Type'(Element => Src.Element,
116 Prev => Container.Last,
118 Container.Last := Container.Last.Next;
119 Container.Length := Container.Length + 1;
130 (Container : in out List;
131 New_Item : Element_Type;
132 Count : Count_Type := 1) is
134 Insert (Container, No_Element, New_Item, Count);
141 procedure Clear (Container : in out List) is
145 if Container.Length = 0 then
146 pragma Assert (Container.First = null);
147 pragma Assert (Container.Last = null);
148 pragma Assert (Container.Busy = 0);
149 pragma Assert (Container.Lock = 0);
153 pragma Assert (Container.First.Prev = null);
154 pragma Assert (Container.Last.Next = null);
156 if Container.Busy > 0 then
160 while Container.Length > 1 loop
161 X := Container.First;
162 pragma Assert (X.Next.Prev = Container.First);
164 Container.First := X.Next;
165 X.Next := null; -- prevent mischief
167 Container.First.Prev := null;
168 Container.Length := Container.Length - 1;
173 X := Container.First;
174 pragma Assert (X = Container.Last);
176 Container.First := null;
177 Container.Last := null;
178 Container.Length := 0;
189 Item : Element_Type) return Boolean is
191 return Find (Container, Item) /= No_Element;
199 (Container : in out List;
200 Position : in out Cursor;
201 Count : Count_Type := 1)
206 if Position.Node = null then
207 pragma Assert (Position.Container = null);
208 raise Constraint_Error;
211 if Position.Container /= List_Access'(Container'Unchecked_Access) then
215 pragma Assert (Container.Length > 0);
216 pragma Assert (Container.First.Prev = null);
217 pragma Assert (Container.Last.Next = null);
219 pragma Assert (Position.Node.Prev = null
220 or else Position.Node.Prev.Next = Position.Node);
221 pragma Assert (Position.Node.Next = null
222 or else Position.Node.Next.Prev = Position.Node);
223 pragma Assert (Position.Node.Prev /= null
224 or else Position.Node = Container.First);
225 pragma Assert (Position.Node.Next /= null
226 or else Position.Node = Container.Last);
228 if Position.Node = Container.First then
229 Delete_First (Container, Count);
230 Position := First (Container);
238 if Container.Busy > 0 then
242 for Index in 1 .. Count loop
244 Container.Length := Container.Length - 1;
246 if X = Container.Last then
247 Position := No_Element;
249 Container.Last := X.Prev;
250 Container.Last.Next := null;
252 X.Prev := null; -- prevent mischief
257 Position.Node := X.Next;
259 X.Next.Prev := X.Prev;
260 X.Prev.Next := X.Next;
272 procedure Delete_First
273 (Container : in out List;
274 Count : Count_Type := 1)
279 if Count >= Container.Length then
288 if Container.Busy > 0 then
292 for I in 1 .. Count loop
293 X := Container.First;
294 pragma Assert (X.Next.Prev = Container.First);
296 Container.First := X.Next;
297 Container.First.Prev := null;
299 Container.Length := Container.Length - 1;
301 X.Next := null; -- prevent mischief
310 procedure Delete_Last
311 (Container : in out List;
312 Count : Count_Type := 1)
317 if Count >= Container.Length then
326 if Container.Busy > 0 then
330 for I in 1 .. Count loop
332 pragma Assert (X.Prev.Next = Container.Last);
334 Container.Last := X.Prev;
335 Container.Last.Next := null;
337 Container.Length := Container.Length - 1;
339 X.Prev := null; -- prevent mischief
348 function Element (Position : Cursor) return Element_Type is
350 pragma Assert (Position.Container /= null);
351 pragma Assert (Position.Container.Length > 0);
352 pragma Assert (Position.Container.First.Prev = null);
353 pragma Assert (Position.Container.Last.Next = null);
355 pragma Assert (Position.Node /= null);
356 pragma Assert (Position.Node.Prev = null
357 or else Position.Node.Prev.Next = Position.Node);
358 pragma Assert (Position.Node.Next = null
359 or else Position.Node.Next.Prev = Position.Node);
360 pragma Assert (Position.Node.Prev /= null
361 or else Position.Node = Position.Container.First);
362 pragma Assert (Position.Node.Next /= null
363 or else Position.Node = Position.Container.Last);
365 return Position.Node.Element;
375 Position : Cursor := No_Element) return Cursor
377 Node : Node_Access := Position.Node;
381 Node := Container.First;
383 if Position.Container /= List_Access'(Container'Unchecked_Access) then
387 pragma Assert (Container.Length > 0);
388 pragma Assert (Container.First.Prev = null);
389 pragma Assert (Container.Last.Next = null);
391 pragma Assert (Position.Node.Prev = null
392 or else Position.Node.Prev.Next = Position.Node);
393 pragma Assert (Position.Node.Next = null
394 or else Position.Node.Next.Prev = Position.Node);
395 pragma Assert (Position.Node.Prev /= null
396 or else Position.Node = Container.First);
397 pragma Assert (Position.Node.Next /= null
398 or else Position.Node = Container.Last);
401 while Node /= null loop
402 if Node.Element = Item then
403 return Cursor'(Container'Unchecked_Access, Node);
416 function First (Container : List) return Cursor is
418 if Container.First = null then
422 return Cursor'(Container'Unchecked_Access, Container.First);
429 function First_Element (Container : List) return Element_Type is
431 return Container.First.Element;
434 ---------------------
435 -- Generic_Sorting --
436 ---------------------
438 package body Generic_Sorting is
444 function Is_Sorted (Container : List) return Boolean is
445 Node : Node_Access := Container.First;
448 for I in 2 .. Container.Length loop
449 if Node.Next.Element < Node.Element then
464 (Target : in out List;
465 Source : in out List)
467 LI : Cursor := First (Target);
468 RI : Cursor := First (Source);
471 if Target'Address = Source'Address then
476 or else Source.Busy > 0
481 while RI.Node /= null loop
482 if LI.Node = null then
483 Splice (Target, No_Element, Source);
487 if RI.Node.Element < LI.Node.Element then
491 RI.Node := RI.Node.Next;
492 Splice (Target, LI, Source, RJ);
496 LI.Node := LI.Node.Next;
505 procedure Sort (Container : in out List) is
508 (Pivot : in Node_Access;
509 Back : in Node_Access);
511 procedure Sort (Front, Back : Node_Access);
518 (Pivot : Node_Access;
521 Node : Node_Access := Pivot.Next;
524 while Node /= Back loop
525 if Node.Element < Pivot.Element then
527 Prev : constant Node_Access := Node.Prev;
528 Next : constant Node_Access := Node.Next;
534 Container.Last := Prev;
540 Node.Prev := Pivot.Prev;
544 if Node.Prev = null then
545 Container.First := Node;
547 Node.Prev.Next := Node;
563 procedure Sort (Front, Back : Node_Access) is
568 Pivot := Container.First;
573 if Pivot /= Back then
574 Partition (Pivot, Back);
580 -- Start of processing for Sort
583 if Container.Length <= 1 then
587 pragma Assert (Container.First.Prev = null);
588 pragma Assert (Container.Last.Next = null);
590 if Container.Busy > 0 then
594 Sort (Front => null, Back => null);
596 pragma Assert (Container.First.Prev = null);
597 pragma Assert (Container.Last.Next = null);
606 function Has_Element (Position : Cursor) return Boolean is
608 if Position.Node = null then
609 pragma Assert (Position.Container = null);
613 pragma Assert (Position.Container /= null);
614 pragma Assert (Position.Container.Length > 0);
615 pragma Assert (Position.Container.First.Prev = null);
616 pragma Assert (Position.Container.Last.Next = null);
618 pragma Assert (Position.Node.Prev = null
619 or else Position.Node.Prev.Next = Position.Node);
620 pragma Assert (Position.Node.Next = null
621 or else Position.Node.Next.Prev = Position.Node);
622 pragma Assert (Position.Node.Prev /= null
623 or else Position.Node = Position.Container.First);
624 pragma Assert (Position.Node.Next /= null
625 or else Position.Node = Position.Container.Last);
635 (Container : in out List;
637 New_Item : Element_Type;
638 Position : out Cursor;
639 Count : Count_Type := 1)
641 New_Node : Node_Access;
644 if Before.Node /= null then
645 if Before.Container /= List_Access'(Container'Unchecked_Access) then
649 pragma Assert (Container.Length > 0);
650 pragma Assert (Container.First.Prev = null);
651 pragma Assert (Container.Last.Next = null);
653 pragma Assert (Before.Node.Prev = null
654 or else Before.Node.Prev.Next = Before.Node);
655 pragma Assert (Before.Node.Next = null
656 or else Before.Node.Next.Prev = Before.Node);
657 pragma Assert (Before.Node.Prev /= null
658 or else Before.Node = Container.First);
659 pragma Assert (Before.Node.Next /= null
660 or else Before.Node = Container.Last);
668 if Container.Length > Count_Type'Last - Count then
669 raise Constraint_Error;
672 if Container.Busy > 0 then
676 New_Node := new Node_Type'(New_Item, null, null);
677 Insert_Internal (Container, Before.Node, New_Node);
679 Position := Cursor'(Container'Unchecked_Access, New_Node);
681 for J in Count_Type'(2) .. Count loop
682 New_Node := new Node_Type'(New_Item, null, null);
683 Insert_Internal (Container, Before.Node, New_Node);
688 (Container : in out List;
690 New_Item : Element_Type;
691 Count : Count_Type := 1)
695 Insert (Container, Before, New_Item, Position, Count);
699 (Container : in out List;
701 Position : out Cursor;
702 Count : Count_Type := 1)
704 New_Node : Node_Access;
707 if Before.Node /= null then
708 if Before.Container /= List_Access'(Container'Unchecked_Access) then
712 pragma Assert (Container.Length > 0);
713 pragma Assert (Container.First.Prev = null);
714 pragma Assert (Container.Last.Next = null);
716 pragma Assert (Before.Node.Prev = null
717 or else Before.Node.Prev.Next = Before.Node);
718 pragma Assert (Before.Node.Next = null
719 or else Before.Node.Next.Prev = Before.Node);
720 pragma Assert (Before.Node.Prev /= null
721 or else Before.Node = Container.First);
722 pragma Assert (Before.Node.Next /= null
723 or else Before.Node = Container.Last);
731 if Container.Length > Count_Type'Last - Count then
732 raise Constraint_Error;
735 if Container.Busy > 0 then
739 New_Node := new Node_Type;
740 Insert_Internal (Container, Before.Node, New_Node);
742 Position := Cursor'(Container'Unchecked_Access, New_Node);
744 for J in Count_Type'(2) .. Count loop
745 New_Node := new Node_Type;
746 Insert_Internal (Container, Before.Node, New_Node);
750 ---------------------
751 -- Insert_Internal --
752 ---------------------
754 procedure Insert_Internal
755 (Container : in out List;
756 Before : Node_Access;
757 New_Node : Node_Access)
760 if Container.Length = 0 then
761 pragma Assert (Before = null);
762 pragma Assert (Container.First = null);
763 pragma Assert (Container.Last = null);
765 Container.First := New_Node;
766 Container.Last := New_Node;
768 elsif Before = null then
769 pragma Assert (Container.Last.Next = null);
771 Container.Last.Next := New_Node;
772 New_Node.Prev := Container.Last;
774 Container.Last := New_Node;
776 elsif Before = Container.First then
777 pragma Assert (Container.First.Prev = null);
779 Container.First.Prev := New_Node;
780 New_Node.Next := Container.First;
782 Container.First := New_Node;
785 pragma Assert (Container.First.Prev = null);
786 pragma Assert (Container.Last.Next = null);
788 New_Node.Next := Before;
789 New_Node.Prev := Before.Prev;
791 Before.Prev.Next := New_Node;
792 Before.Prev := New_Node;
795 Container.Length := Container.Length + 1;
802 function Is_Empty (Container : List) return Boolean is
804 return Container.Length = 0;
813 Process : not null access procedure (Position : Cursor))
815 C : List renames Container'Unrestricted_Access.all;
816 B : Natural renames C.Busy;
818 Node : Node_Access := Container.First;
824 while Node /= null loop
825 Process (Cursor'(Container'Unchecked_Access, Node));
841 function Last (Container : List) return Cursor is
843 if Container.Last = null then
847 return Cursor'(Container'Unchecked_Access, Container.Last);
854 function Last_Element (Container : List) return Element_Type is
856 return Container.Last.Element;
863 function Length (Container : List) return Count_Type is
865 return Container.Length;
873 (Target : in out List;
874 Source : in out List)
877 if Target'Address = Source'Address then
881 if Source.Busy > 0 then
887 Target.First := Source.First;
888 Source.First := null;
890 Target.Last := Source.Last;
893 Target.Length := Source.Length;
901 procedure Next (Position : in out Cursor) is
903 if Position.Node = null then
904 pragma Assert (Position.Container = null);
908 pragma Assert (Position.Container /= null);
909 pragma Assert (Position.Container.Length > 0);
910 pragma Assert (Position.Container.First.Prev = null);
911 pragma Assert (Position.Container.Last.Next = null);
913 pragma Assert (Position.Node.Prev = null
914 or else Position.Node.Prev.Next = Position.Node);
915 pragma Assert (Position.Node.Next = null
916 or else Position.Node.Next.Prev = Position.Node);
917 pragma Assert (Position.Node.Prev /= null
918 or else Position.Node = Position.Container.First);
919 pragma Assert (Position.Node.Next /= null
920 or else Position.Node = Position.Container.Last);
922 Position.Node := Position.Node.Next;
924 if Position.Node = null then
925 Position.Container := null;
929 function Next (Position : Cursor) return Cursor is
931 if Position.Node = null then
932 pragma Assert (Position.Container = null);
936 pragma Assert (Position.Container /= null);
937 pragma Assert (Position.Container.Length > 0);
938 pragma Assert (Position.Container.First.Prev = null);
939 pragma Assert (Position.Container.Last.Next = null);
941 pragma Assert (Position.Node.Prev = null
942 or else Position.Node.Prev.Next = Position.Node);
943 pragma Assert (Position.Node.Next = null
944 or else Position.Node.Next.Prev = Position.Node);
945 pragma Assert (Position.Node.Prev /= null
946 or else Position.Node = Position.Container.First);
947 pragma Assert (Position.Node.Next /= null
948 or else Position.Node = Position.Container.Last);
951 Next_Node : constant Node_Access := Position.Node.Next;
953 if Next_Node = null then
957 return Cursor'(Position.Container, Next_Node);
966 (Container : in out List;
967 New_Item : Element_Type;
968 Count : Count_Type := 1)
971 Insert (Container, First (Container), New_Item, Count);
978 procedure Previous (Position : in out Cursor) is
980 if Position.Node = null then
981 pragma Assert (Position.Container = null);
985 pragma Assert (Position.Container /= null);
986 pragma Assert (Position.Container.Length > 0);
987 pragma Assert (Position.Container.First.Prev = null);
988 pragma Assert (Position.Container.Last.Next = null);
990 pragma Assert (Position.Node.Prev = null
991 or else Position.Node.Prev.Next = Position.Node);
992 pragma Assert (Position.Node.Next = null
993 or else Position.Node.Next.Prev = Position.Node);
994 pragma Assert (Position.Node.Prev /= null
995 or else Position.Node = Position.Container.First);
996 pragma Assert (Position.Node.Next /= null
997 or else Position.Node = Position.Container.Last);
999 Position.Node := Position.Node.Prev;
1001 if Position.Node = null then
1002 Position.Container := null;
1006 function Previous (Position : Cursor) return Cursor is
1008 if Position.Node = null then
1009 pragma Assert (Position.Container = null);
1013 pragma Assert (Position.Container /= null);
1014 pragma Assert (Position.Container.Length > 0);
1015 pragma Assert (Position.Container.First.Prev = null);
1016 pragma Assert (Position.Container.Last.Next = null);
1018 pragma Assert (Position.Node.Prev = null
1019 or else Position.Node.Prev.Next = Position.Node);
1020 pragma Assert (Position.Node.Next = null
1021 or else Position.Node.Next.Prev = Position.Node);
1022 pragma Assert (Position.Node.Prev /= null
1023 or else Position.Node = Position.Container.First);
1024 pragma Assert (Position.Node.Next /= null
1025 or else Position.Node = Position.Container.Last);
1028 Prev_Node : constant Node_Access := Position.Node.Prev;
1030 if Prev_Node = null then
1034 return Cursor'(Position.Container, Prev_Node);
1042 procedure Query_Element
1044 Process : not null access procedure (Element : in Element_Type))
1046 pragma Assert (Position.Container /= null);
1047 pragma Assert (Position.Container.Length > 0);
1048 pragma Assert (Position.Container.First.Prev = null);
1049 pragma Assert (Position.Container.Last.Next = null);
1051 pragma Assert (Position.Node /= null);
1052 pragma Assert (Position.Node.Prev = null
1053 or else Position.Node.Prev.Next = Position.Node);
1054 pragma Assert (Position.Node.Next = null
1055 or else Position.Node.Next.Prev = Position.Node);
1056 pragma Assert (Position.Node.Prev /= null
1057 or else Position.Node = Position.Container.First);
1058 pragma Assert (Position.Node.Next /= null
1059 or else Position.Node = Position.Container.Last);
1061 E : Element_Type renames Position.Node.Element;
1063 C : List renames Position.Container.all'Unrestricted_Access.all;
1064 B : Natural renames C.Busy;
1065 L : Natural renames C.Lock;
1089 (Stream : access Root_Stream_Type'Class;
1092 N : Count_Type'Base;
1097 Count_Type'Base'Read (Stream, N);
1106 Element_Type'Read (Stream, X.Element);
1117 Item.Length := Item.Length + 1;
1118 exit when Item.Length = N;
1123 Element_Type'Read (Stream, X.Element);
1130 X.Prev := Item.Last;
1131 Item.Last.Next := X;
1136 ---------------------
1137 -- Replace_Element --
1138 ---------------------
1140 procedure Replace_Element
1144 pragma Assert (Position.Container /= null);
1145 pragma Assert (Position.Container.Length > 0);
1146 pragma Assert (Position.Container.First.Prev = null);
1147 pragma Assert (Position.Container.Last.Next = null);
1149 pragma Assert (Position.Node /= null);
1150 pragma Assert (Position.Node.Prev = null
1151 or else Position.Node.Prev.Next = Position.Node);
1152 pragma Assert (Position.Node.Next = null
1153 or else Position.Node.Next.Prev = Position.Node);
1154 pragma Assert (Position.Node.Prev /= null
1155 or else Position.Node = Position.Container.First);
1156 pragma Assert (Position.Node.Next /= null
1157 or else Position.Node = Position.Container.Last);
1159 E : Element_Type renames Position.Node.Element;
1162 if Position.Container.Lock > 0 then
1163 raise Program_Error;
1167 end Replace_Element;
1173 function Reverse_Find
1175 Item : Element_Type;
1176 Position : Cursor := No_Element) return Cursor
1178 Node : Node_Access := Position.Node;
1182 Node := Container.Last;
1184 if Position.Container /= List_Access'(Container'Unchecked_Access) then
1185 raise Program_Error;
1188 pragma Assert (Container.Length > 0);
1189 pragma Assert (Container.First.Prev = null);
1190 pragma Assert (Container.Last.Next = null);
1192 pragma Assert (Position.Node.Prev = null
1193 or else Position.Node.Prev.Next = Position.Node);
1194 pragma Assert (Position.Node.Next = null
1195 or else Position.Node.Next.Prev = Position.Node);
1196 pragma Assert (Position.Node.Prev /= null
1197 or else Position.Node = Container.First);
1198 pragma Assert (Position.Node.Next /= null
1199 or else Position.Node = Container.Last);
1202 while Node /= null loop
1203 if Node.Element = Item then
1204 return Cursor'(Container'Unchecked_Access, Node);
1213 ---------------------
1214 -- Reverse_Iterate --
1215 ---------------------
1217 procedure Reverse_Iterate
1219 Process : not null access procedure (Position : Cursor))
1221 C : List renames Container'Unrestricted_Access.all;
1222 B : Natural renames C.Busy;
1224 Node : Node_Access := Container.Last;
1230 while Node /= null loop
1231 Process (Cursor'(Container'Unchecked_Access, Node));
1241 end Reverse_Iterate;
1247 procedure Reverse_List (Container : in out List) is
1248 I : Node_Access := Container.First;
1249 J : Node_Access := Container.Last;
1251 procedure Swap (L, R : Node_Access);
1257 procedure Swap (L, R : Node_Access) is
1258 LN : constant Node_Access := L.Next;
1259 LP : constant Node_Access := L.Prev;
1261 RN : constant Node_Access := R.Next;
1262 RP : constant Node_Access := R.Prev;
1277 pragma Assert (RP = L);
1291 -- Start of processing for Reverse_List
1294 if Container.Length <= 1 then
1298 pragma Assert (Container.First.Prev = null);
1299 pragma Assert (Container.Last.Next = null);
1301 if Container.Busy > 0 then
1302 raise Program_Error;
1305 Container.First := J;
1306 Container.Last := I;
1308 Swap (L => I, R => J);
1316 Swap (L => J, R => I);
1325 pragma Assert (Container.First.Prev = null);
1326 pragma Assert (Container.Last.Next = null);
1334 (Target : in out List;
1336 Source : in out List)
1339 if Before.Node /= null then
1340 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1341 raise Program_Error;
1344 pragma Assert (Target.Length >= 1);
1345 pragma Assert (Target.First.Prev = null);
1346 pragma Assert (Target.Last.Next = null);
1348 pragma Assert (Before.Node.Prev = null
1349 or else Before.Node.Prev.Next = Before.Node);
1350 pragma Assert (Before.Node.Next = null
1351 or else Before.Node.Next.Prev = Before.Node);
1352 pragma Assert (Before.Node.Prev /= null
1353 or else Before.Node = Target.First);
1354 pragma Assert (Before.Node.Next /= null
1355 or else Before.Node = Target.Last);
1358 if Target'Address = Source'Address
1359 or else Source.Length = 0
1364 pragma Assert (Source.First.Prev = null);
1365 pragma Assert (Source.Last.Next = null);
1367 if Target.Length > Count_Type'Last - Source.Length then
1368 raise Constraint_Error;
1372 or else Source.Busy > 0
1374 raise Program_Error;
1377 if Target.Length = 0 then
1378 pragma Assert (Target.First = null);
1379 pragma Assert (Target.Last = null);
1380 pragma Assert (Before = No_Element);
1382 Target.First := Source.First;
1383 Target.Last := Source.Last;
1385 elsif Before.Node = null then
1386 pragma Assert (Target.Last.Next = null);
1388 Target.Last.Next := Source.First;
1389 Source.First.Prev := Target.Last;
1391 Target.Last := Source.Last;
1393 elsif Before.Node = Target.First then
1394 pragma Assert (Target.First.Prev = null);
1396 Source.Last.Next := Target.First;
1397 Target.First.Prev := Source.Last;
1399 Target.First := Source.First;
1402 pragma Assert (Target.Length >= 2);
1404 Before.Node.Prev.Next := Source.First;
1405 Source.First.Prev := Before.Node.Prev;
1407 Before.Node.Prev := Source.Last;
1408 Source.Last.Next := Before.Node;
1411 Source.First := null;
1412 Source.Last := null;
1414 Target.Length := Target.Length + Source.Length;
1419 (Target : in out List;
1424 if Before.Node /= null then
1425 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1426 raise Program_Error;
1429 pragma Assert (Target.Length >= 1);
1430 pragma Assert (Target.First.Prev = null);
1431 pragma Assert (Target.Last.Next = null);
1433 pragma Assert (Before.Node.Prev = null
1434 or else Before.Node.Prev.Next = Before.Node);
1435 pragma Assert (Before.Node.Next = null
1436 or else Before.Node.Next.Prev = Before.Node);
1437 pragma Assert (Before.Node.Prev /= null
1438 or else Before.Node = Target.First);
1439 pragma Assert (Before.Node.Next /= null
1440 or else Before.Node = Target.Last);
1443 if Position.Node = null then
1444 raise Constraint_Error;
1447 if Position.Container /= List_Access'(Target'Unchecked_Access) then
1448 raise Program_Error;
1451 pragma Assert (Target.Length >= 1);
1452 pragma Assert (Target.First.Prev = null);
1453 pragma Assert (Target.Last.Next = null);
1455 pragma Assert (Position.Node.Prev = null
1456 or else Position.Node.Prev.Next = Position.Node);
1457 pragma Assert (Position.Node.Next = null
1458 or else Position.Node.Next.Prev = Position.Node);
1459 pragma Assert (Position.Node.Prev /= null
1460 or else Position.Node = Target.First);
1461 pragma Assert (Position.Node.Next /= null
1462 or else Position.Node = Target.Last);
1464 if Position.Node = Before.Node
1465 or else Position.Node.Next = Before.Node
1470 pragma Assert (Target.Length >= 2);
1472 if Target.Busy > 0 then
1473 raise Program_Error;
1476 if Before.Node = null then
1477 pragma Assert (Position.Node /= Target.Last);
1479 if Position.Node = Target.First then
1480 Target.First := Position.Node.Next;
1481 Target.First.Prev := null;
1483 Position.Node.Prev.Next := Position.Node.Next;
1484 Position.Node.Next.Prev := Position.Node.Prev;
1487 Target.Last.Next := Position.Node;
1488 Position.Node.Prev := Target.Last;
1490 Target.Last := Position.Node;
1491 Target.Last.Next := null;
1496 if Before.Node = Target.First then
1497 pragma Assert (Position.Node /= Target.First);
1499 if Position.Node = Target.Last then
1500 Target.Last := Position.Node.Prev;
1501 Target.Last.Next := null;
1503 Position.Node.Prev.Next := Position.Node.Next;
1504 Position.Node.Next.Prev := Position.Node.Prev;
1507 Target.First.Prev := Position.Node;
1508 Position.Node.Next := Target.First;
1510 Target.First := Position.Node;
1511 Target.First.Prev := null;
1516 if Position.Node = Target.First then
1517 Target.First := Position.Node.Next;
1518 Target.First.Prev := null;
1520 elsif Position.Node = Target.Last then
1521 Target.Last := Position.Node.Prev;
1522 Target.Last.Next := null;
1525 Position.Node.Prev.Next := Position.Node.Next;
1526 Position.Node.Next.Prev := Position.Node.Prev;
1529 Before.Node.Prev.Next := Position.Node;
1530 Position.Node.Prev := Before.Node.Prev;
1532 Before.Node.Prev := Position.Node;
1533 Position.Node.Next := Before.Node;
1535 pragma Assert (Target.First.Prev = null);
1536 pragma Assert (Target.Last.Next = null);
1540 (Target : in out List;
1542 Source : in out List;
1543 Position : in out Cursor)
1546 if Target'Address = Source'Address then
1547 Splice (Target, Before, Position);
1551 if Before.Node /= null then
1552 if Before.Container /= List_Access'(Target'Unchecked_Access) then
1553 raise Program_Error;
1556 pragma Assert (Target.Length >= 1);
1557 pragma Assert (Target.First.Prev = null);
1558 pragma Assert (Target.Last.Next = null);
1560 pragma Assert (Before.Node.Prev = null
1561 or else Before.Node.Prev.Next = Before.Node);
1562 pragma Assert (Before.Node.Next = null
1563 or else Before.Node.Next.Prev = Before.Node);
1564 pragma Assert (Before.Node.Prev /= null
1565 or else Before.Node = Target.First);
1566 pragma Assert (Before.Node.Next /= null
1567 or else Before.Node = Target.Last);
1570 if Position.Node = null then
1571 raise Constraint_Error;
1574 if Position.Container /= List_Access'(Source'Unchecked_Access) then
1575 raise Program_Error;
1578 pragma Assert (Source.Length >= 1);
1579 pragma Assert (Source.First.Prev = null);
1580 pragma Assert (Source.Last.Next = null);
1582 pragma Assert (Position.Node.Prev = null
1583 or else Position.Node.Prev.Next = Position.Node);
1584 pragma Assert (Position.Node.Next = null
1585 or else Position.Node.Next.Prev = Position.Node);
1586 pragma Assert (Position.Node.Prev /= null
1587 or else Position.Node = Source.First);
1588 pragma Assert (Position.Node.Next /= null
1589 or else Position.Node = Source.Last);
1591 if Target.Length = Count_Type'Last then
1592 raise Constraint_Error;
1596 or else Source.Busy > 0
1598 raise Program_Error;
1601 if Position.Node = Source.First then
1602 Source.First := Position.Node.Next;
1603 Source.First.Prev := null;
1605 if Position.Node = Source.Last then
1606 pragma Assert (Source.First = null);
1607 pragma Assert (Source.Length = 1);
1608 Source.Last := null;
1611 elsif Position.Node = Source.Last then
1612 pragma Assert (Source.Length >= 2);
1613 Source.Last := Position.Node.Prev;
1614 Source.Last.Next := null;
1617 pragma Assert (Source.Length >= 3);
1618 Position.Node.Prev.Next := Position.Node.Next;
1619 Position.Node.Next.Prev := Position.Node.Prev;
1622 if Target.Length = 0 then
1623 pragma Assert (Target.First = null);
1624 pragma Assert (Target.Last = null);
1625 pragma Assert (Before = No_Element);
1627 Target.First := Position.Node;
1628 Target.Last := Position.Node;
1630 Target.First.Prev := null;
1631 Target.Last.Next := null;
1633 elsif Before.Node = null then
1634 pragma Assert (Target.Last.Next = null);
1635 Target.Last.Next := Position.Node;
1636 Position.Node.Prev := Target.Last;
1638 Target.Last := Position.Node;
1639 Target.Last.Next := null;
1641 elsif Before.Node = Target.First then
1642 pragma Assert (Target.First.Prev = null);
1643 Target.First.Prev := Position.Node;
1644 Position.Node.Next := Target.First;
1646 Target.First := Position.Node;
1647 Target.First.Prev := null;
1650 pragma Assert (Target.Length >= 2);
1651 Before.Node.Prev.Next := Position.Node;
1652 Position.Node.Prev := Before.Node.Prev;
1654 Before.Node.Prev := Position.Node;
1655 Position.Node.Next := Before.Node;
1658 Target.Length := Target.Length + 1;
1659 Source.Length := Source.Length - 1;
1661 Position.Container := Target'Unchecked_Access;
1668 procedure Swap (I, J : Cursor) is
1670 if I.Container = null
1671 or else J.Container = null
1673 raise Constraint_Error;
1676 if I.Container /= J.Container then
1677 raise Program_Error;
1681 C : List renames I.Container.all;
1683 pragma Assert (C.Length >= 1);
1684 pragma Assert (C.First.Prev = null);
1685 pragma Assert (C.Last.Next = null);
1687 pragma Assert (I.Node /= null);
1688 pragma Assert (I.Node.Prev = null
1689 or else I.Node.Prev.Next = I.Node);
1690 pragma Assert (I.Node.Next = null
1691 or else I.Node.Next.Prev = I.Node);
1692 pragma Assert (I.Node.Prev /= null
1693 or else I.Node = C.First);
1694 pragma Assert (I.Node.Next /= null
1695 or else I.Node = C.Last);
1697 if I.Node = J.Node then
1701 pragma Assert (C.Length >= 2);
1702 pragma Assert (J.Node /= null);
1703 pragma Assert (J.Node.Prev = null
1704 or else J.Node.Prev.Next = J.Node);
1705 pragma Assert (J.Node.Next = null
1706 or else J.Node.Next.Prev = J.Node);
1707 pragma Assert (J.Node.Prev /= null
1708 or else J.Node = C.First);
1709 pragma Assert (J.Node.Next /= null
1710 or else J.Node = C.Last);
1713 raise Program_Error;
1717 EI : Element_Type renames I.Node.Element;
1718 EJ : Element_Type renames J.Node.Element;
1720 EI_Copy : constant Element_Type := EI;
1732 procedure Swap_Links
1733 (Container : in out List;
1736 if I.Container = null
1737 or else J.Container = null
1739 raise Constraint_Error;
1742 if I.Container /= List_Access'(Container'Unchecked_Access) then
1743 raise Program_Error;
1746 if J.Container /= I.Container then
1747 raise Program_Error;
1750 pragma Assert (Container.Length >= 1);
1751 pragma Assert (Container.First.Prev = null);
1752 pragma Assert (Container.Last.Next = null);
1754 pragma Assert (I.Node /= null);
1755 pragma Assert (I.Node.Prev = null
1756 or else I.Node.Prev.Next = I.Node);
1757 pragma Assert (I.Node.Next = null
1758 or else I.Node.Next.Prev = I.Node);
1759 pragma Assert (I.Node.Prev /= null
1760 or else I.Node = Container.First);
1761 pragma Assert (I.Node.Next /= null
1762 or else I.Node = Container.Last);
1764 if I.Node = J.Node then
1768 pragma Assert (Container.Length >= 2);
1770 pragma Assert (J.Node /= null);
1771 pragma Assert (J.Node.Prev = null
1772 or else J.Node.Prev.Next = J.Node);
1773 pragma Assert (J.Node.Next = null
1774 or else J.Node.Next.Prev = J.Node);
1775 pragma Assert (J.Node.Prev /= null
1776 or else J.Node = Container.First);
1777 pragma Assert (J.Node.Next /= null
1778 or else J.Node = Container.Last);
1780 if Container.Busy > 0 then
1781 raise Program_Error;
1785 I_Next : constant Cursor := Next (I);
1789 Splice (Container, Before => I, Position => J);
1793 J_Next : constant Cursor := Next (J);
1797 Splice (Container, Before => J, Position => I);
1800 pragma Assert (Container.Length >= 3);
1802 Splice (Container, Before => I_Next, Position => J);
1803 Splice (Container, Before => J_Next, Position => I);
1810 --------------------
1811 -- Update_Element --
1812 --------------------
1814 procedure Update_Element
1816 Process : not null access procedure (Element : in out Element_Type)) is
1818 pragma Assert (Position.Container /= null);
1819 pragma Assert (Position.Container.Length >= 1);
1820 pragma Assert (Position.Container.First.Prev = null);
1821 pragma Assert (Position.Container.Last.Next = null);
1823 pragma Assert (Position.Node /= null);
1824 pragma Assert (Position.Node.Prev = null
1825 or else Position.Node.Prev.Next = Position.Node);
1826 pragma Assert (Position.Node.Next = null
1827 or else Position.Node.Next.Prev = Position.Node);
1828 pragma Assert (Position.Node.Prev /= null
1829 or else Position.Node = Position.Container.First);
1830 pragma Assert (Position.Node.Next /= null
1831 or else Position.Node = Position.Container.Last);
1833 E : Element_Type renames Position.Node.Element;
1835 C : List renames Position.Container.all'Unrestricted_Access.all;
1836 B : Natural renames C.Busy;
1837 L : Natural renames C.Lock;
1861 (Stream : access Root_Stream_Type'Class;
1864 Node : Node_Access := Item.First;
1867 Count_Type'Base'Write (Stream, Item.Length);
1869 while Node /= null loop
1870 Element_Type'Write (Stream, Node.Element);
1875 end Ada.Containers.Doubly_Linked_Lists;