3 with Ada
.Text_IO
; use Ada
.Text_IO
;
5 with GNAT
.Lists
; use GNAT
.Lists
;
7 procedure Linkedlist
is
8 package Integer_Lists
is new Doubly_Linked_List
9 (Element_Type
=> Integer,
18 -- Ensure that none of the elements in the range Low_Elem .. High_Elem are
19 -- present in list L, and that the list's length is 0.
21 procedure Check_Locked_Mutations
(Caller
: String; L
: in out Instance
);
22 -- Ensure that all mutation operations of list L are locked
24 procedure Check_Present
29 -- Ensure that all elements in the range Low_Elem .. High_Elem are present
32 procedure Check_Unlocked_Mutations
(Caller
: String; L
: in out Instance
);
33 -- Ensure that all mutation operations of list L are unlocked
35 procedure Populate_With_Append
39 -- Add elements in the range Low_Elem .. High_Elem in that order in list L
41 procedure Test_Append
;
42 -- Verify that Append properly inserts at the tail of a list
44 procedure Test_Contains
47 -- Verify that Contains properly identifies that elements in the range
48 -- Low_Elem .. High_Elem are within a list.
50 procedure Test_Create
;
51 -- Verify that all list operations fail on a non-created list
56 -- Verify that Delete properly removes elements in the range Low_Elem ..
57 -- High_Elem from a list.
59 procedure Test_Delete_First
62 -- Verify that Delete properly removes elements in the range Low_Elem ..
63 -- High_Elem from the head of a list.
65 procedure Test_Delete_Last
68 -- Verify that Delete properly removes elements in the range Low_Elem ..
69 -- High_Elem from the tail of a list.
72 -- Verify that First properly returns the head of a list
74 procedure Test_Insert_After
;
75 -- Verify that Insert_After properly adds an element after some other
78 procedure Test_Insert_Before
;
79 -- Vefity that Insert_Before properly adds an element before some other
82 procedure Test_Is_Empty
;
83 -- Verify that Is_Empty properly returns this status of a list
85 procedure Test_Iterate
;
86 -- Verify that iterators properly manipulate mutation operations
88 procedure Test_Iterate_Empty
;
89 -- Verify that iterators properly manipulate mutation operations of an
92 procedure Test_Iterate_Forced
95 -- Verify that an iterator that is forcefully advanced by Next properly
96 -- unlocks the mutation operations of a list.
99 -- Verify that Last properly returns the tail of a list
101 procedure Test_Prepend
;
102 -- Verify that Prepend properly inserts at the head of a list
104 procedure Test_Replace
;
105 -- Verify that Replace properly substitutes old elements with new ones
108 -- Verify that Size returns the correct size of a list
114 procedure Check_Empty
120 Len
: constant Natural := Size
(L
);
123 for Elem
in Low_Elem
.. High_Elem
loop
124 if Contains
(L
, Elem
) then
125 Put_Line
("ERROR: " & Caller
& ": extra element" & Elem
'Img);
130 Put_Line
("ERROR: " & Caller
& ": wrong length");
131 Put_Line
("expected: 0");
132 Put_Line
("got :" & Len
'Img);
136 ----------------------------
137 -- Check_Locked_Mutations --
138 ----------------------------
140 procedure Check_Locked_Mutations
(Caller
: String; L
: in out Instance
) is
144 Put_Line
("ERROR: " & Caller
& ": Append: no exception raised");
149 Put_Line
("ERROR: " & Caller
& ": Append: unexpected exception");
154 Put_Line
("ERROR: " & Caller
& ": Delete: no exception raised");
161 Put_Line
("ERROR: " & Caller
& ": Delete: unexpected exception");
166 Put_Line
("ERROR: " & Caller
& ": Delete_First: no exception raised");
174 ("ERROR: " & Caller
& ": Delete_First: unexpected exception");
179 Put_Line
("ERROR: " & Caller
& ": Delete_List: no exception raised");
187 ("ERROR: " & Caller
& ": Delete_Last: unexpected exception");
192 Put_Line
("ERROR: " & Caller
& ": Destroy: no exception raised");
197 Put_Line
("ERROR: " & Caller
& ": Destroy: unexpected exception");
201 Insert_After
(L
, 1, 2);
202 Put_Line
("ERROR: " & Caller
& ": Insert_After: no exception raised");
208 ("ERROR: " & Caller
& ": Insert_After: unexpected exception");
212 Insert_Before
(L
, 1, 2);
214 ("ERROR: " & Caller
& ": Insert_Before: no exception raised");
220 ("ERROR: " & Caller
& ": Insert_Before: unexpected exception");
225 Put_Line
("ERROR: " & Caller
& ": Prepend: no exception raised");
230 Put_Line
("ERROR: " & Caller
& ": Prepend: unexpected exception");
235 Put_Line
("ERROR: " & Caller
& ": Replace: no exception raised");
240 Put_Line
("ERROR: " & Caller
& ": Replace: unexpected exception");
242 end Check_Locked_Mutations
;
248 procedure Check_Present
259 for Exp_Elem
in Low_Elem
.. High_Elem
loop
262 if Elem
/= Exp_Elem
then
263 Put_Line
("ERROR: " & Caller
& ": Check_Present: wrong element");
264 Put_Line
("expected:" & Exp_Elem
'Img);
265 Put_Line
("got :" & Elem
'Img);
269 -- At this point all elements should have been accounted for. Check for
272 while Has_Next
(Iter
) loop
275 ("ERROR: " & Caller
& ": Check_Present: extra element" & Elem
'Img);
279 when Iterator_Exhausted
=>
283 & "Check_Present: incorrect number of elements");
286 ------------------------------
287 -- Check_Unlocked_Mutations --
288 ------------------------------
290 procedure Check_Unlocked_Mutations
(Caller
: String; L
: in out Instance
) is
298 Insert_After
(L
, 2, 3);
299 Insert_Before
(L
, 2, 1);
302 end Check_Unlocked_Mutations
;
304 --------------------------
305 -- Populate_With_Append --
306 --------------------------
308 procedure Populate_With_Append
314 for Elem
in Low_Elem
.. High_Elem
loop
317 end Populate_With_Append
;
323 procedure Test_Append
is
324 L
: Instance
:= Create
;
334 (Caller
=> "Test_Append",
346 procedure Test_Contains
350 Low_Bogus
: constant Integer := Low_Elem
- 1;
351 High_Bogus
: constant Integer := High_Elem
+ 1;
353 L
: Instance
:= Create
;
356 Populate_With_Append
(L
, Low_Elem
, High_Elem
);
358 -- Ensure that the elements are contained in the list
360 for Elem
in Low_Elem
.. High_Elem
loop
361 if not Contains
(L
, Elem
) then
363 ("ERROR: Test_Contains: element" & Elem
'Img & " not in list");
367 -- Ensure that arbitrary elements which were not inserted in the list
368 -- are not contained in the list.
370 if Contains
(L
, Low_Bogus
) then
372 ("ERROR: Test_Contains: element" & Low_Bogus
'Img & " in list");
375 if Contains
(L
, High_Bogus
) then
377 ("ERROR: Test_Contains: element" & High_Bogus
'Img & " in list");
387 procedure Test_Create
is
395 -- Ensure that every routine defined in the API fails on a list which
396 -- has not been created yet.
400 Put_Line
("ERROR: Test_Create: Append: no exception raised");
405 Put_Line
("ERROR: Test_Create: Append: unexpected exception");
409 Flag
:= Contains
(L
, 1);
410 Put_Line
("ERROR: Test_Create: Contains: no exception raised");
415 Put_Line
("ERROR: Test_Create: Contains: unexpected exception");
420 Put_Line
("ERROR: Test_Create: Delete: no exception raised");
425 Put_Line
("ERROR: Test_Create: Delete: unexpected exception");
430 Put_Line
("ERROR: Test_Create: Delete_First: no exception raised");
436 ("ERROR: Test_Create: Delete_First: unexpected exception");
441 Put_Line
("ERROR: Test_Create: Delete_Last: no exception raised");
446 Put_Line
("ERROR: Test_Create: Delete_Last: unexpected exception");
451 Put_Line
("ERROR: Test_Create: First: no exception raised");
456 Put_Line
("ERROR: Test_Create: First: unexpected exception");
460 Insert_After
(L
, 1, 2);
461 Put_Line
("ERROR: Test_Create: Insert_After: no exception raised");
467 ("ERROR: Test_Create: Insert_After: unexpected exception");
471 Insert_Before
(L
, 1, 2);
472 Put_Line
("ERROR: Test_Create: Insert_Before: no exception raised");
478 ("ERROR: Test_Create: Insert_Before: unexpected exception");
482 Flag
:= Is_Empty
(L
);
483 Put_Line
("ERROR: Test_Create: Is_Empty: no exception raised");
488 Put_Line
("ERROR: Test_Create: Is_Empty: unexpected exception");
493 Put_Line
("ERROR: Test_Create: Iterate: no exception raised");
498 Put_Line
("ERROR: Test_Create: Iterate: unexpected exception");
503 Put_Line
("ERROR: Test_Create: Last: no exception raised");
508 Put_Line
("ERROR: Test_Create: Last: unexpected exception");
513 Put_Line
("ERROR: Test_Create: Prepend: no exception raised");
518 Put_Line
("ERROR: Test_Create: Prepend: unexpected exception");
523 Put_Line
("ERROR: Test_Create: Replace: no exception raised");
528 Put_Line
("ERROR: Test_Create: Replace: unexpected exception");
533 Put_Line
("ERROR: Test_Create: Size: no exception raised");
538 Put_Line
("ERROR: Test_Create: Size: unexpected exception");
546 procedure Test_Delete
551 L
: Instance
:= Create
;
554 Populate_With_Append
(L
, Low_Elem
, High_Elem
);
556 -- Delete the first element, which is technically the head
558 Delete
(L
, Low_Elem
);
560 -- Ensure that all remaining elements except for the head are present in
564 (Caller
=> "Test_Delete",
566 Low_Elem
=> Low_Elem
+ 1,
567 High_Elem
=> High_Elem
);
569 -- Delete the last element, which is technically the tail
571 Delete
(L
, High_Elem
);
573 -- Ensure that all remaining elements except for the head and tail are
574 -- present in the list.
577 (Caller
=> "Test_Delete",
579 Low_Elem
=> Low_Elem
+ 1,
580 High_Elem
=> High_Elem
- 1);
582 -- Delete all even elements
584 for Elem
in Low_Elem
+ 1 .. High_Elem
- 1 loop
585 if Elem
mod 2 = 0 then
590 -- Ensure that all remaining elements except the head, tail, and even
591 -- elements are present in the list.
593 for Elem
in Low_Elem
+ 1 .. High_Elem
- 1 loop
594 if Elem
mod 2 /= 0 and then not Contains
(L
, Elem
) then
595 Put_Line
("ERROR: Test_Delete: missing element" & Elem
'Img);
599 -- Delete all odd elements
601 for Elem
in Low_Elem
+ 1 .. High_Elem
- 1 loop
602 if Elem
mod 2 /= 0 then
607 -- At this point the list should be completely empty
610 (Caller
=> "Test_Delete",
612 Low_Elem
=> Low_Elem
,
613 High_Elem
=> High_Elem
);
615 -- Try to delete an element. This operation should raise List_Empty.
618 Delete
(L
, Low_Elem
);
619 Put_Line
("ERROR: Test_Delete: List_Empty not raised");
624 Put_Line
("ERROR: Test_Delete: unexpected exception");
630 -----------------------
631 -- Test_Delete_First --
632 -----------------------
634 procedure Test_Delete_First
638 L
: Instance
:= Create
;
641 Populate_With_Append
(L
, Low_Elem
, High_Elem
);
643 -- Delete the head of the list, and verify that the remaining elements
644 -- are still present in the list.
646 for Elem
in Low_Elem
.. High_Elem
loop
650 (Caller
=> "Test_Delete_First",
652 Low_Elem
=> Elem
+ 1,
653 High_Elem
=> High_Elem
);
656 -- At this point the list should be completely empty
659 (Caller
=> "Test_Delete_First",
661 Low_Elem
=> Low_Elem
,
662 High_Elem
=> High_Elem
);
664 -- Try to delete an element. This operation should raise List_Empty.
668 Put_Line
("ERROR: Test_Delete_First: List_Empty not raised");
673 Put_Line
("ERROR: Test_Delete_First: unexpected exception");
677 end Test_Delete_First
;
679 ----------------------
680 -- Test_Delete_Last --
681 ----------------------
683 procedure Test_Delete_Last
687 L
: Instance
:= Create
;
690 Populate_With_Append
(L
, Low_Elem
, High_Elem
);
692 -- Delete the tail of the list, and verify that the remaining elements
693 -- are still present in the list.
695 for Elem
in reverse Low_Elem
.. High_Elem
loop
699 (Caller
=> "Test_Delete_Last",
701 Low_Elem
=> Low_Elem
,
702 High_Elem
=> Elem
- 1);
705 -- At this point the list should be completely empty
708 (Caller
=> "Test_Delete_Last",
710 Low_Elem
=> Low_Elem
,
711 High_Elem
=> High_Elem
);
713 -- Try to delete an element. This operation should raise List_Empty.
717 Put_Line
("ERROR: Test_Delete_Last: List_Empty not raised");
722 Put_Line
("ERROR: Test_Delete_First: unexpected exception");
726 end Test_Delete_Last
;
732 procedure Test_First
is
734 L
: Instance
:= Create
;
737 -- Try to obtain the head. This operation should raise List_Empty.
741 Put_Line
("ERROR: Test_First: List_Empty not raised");
746 Put_Line
("ERROR: Test_First: unexpected exception");
749 Populate_With_Append
(L
, 1, 2);
756 Put_Line
("ERROR: Test_First: wrong element");
757 Put_Line
("expected: 1");
758 Put_Line
("got :" & Elem
'Img);
764 -----------------------
765 -- Test_Insert_After --
766 -----------------------
768 procedure Test_Insert_After
is
769 L
: Instance
:= Create
;
772 -- Try to insert after a non-inserted element, in an empty list
774 Insert_After
(L
, 1, 2);
776 -- At this point the list should be completely empty
779 (Caller
=> "Test_Insert_After",
786 Insert_After
(L
, 1, 3); -- 1, 3
787 Insert_After
(L
, 1, 2); -- 1, 2, 3
788 Insert_After
(L
, 3, 4); -- 1, 2, 3, 4
790 -- Try to insert after a non-inserted element, in a full list
792 Insert_After
(L
, 10, 11);
795 (Caller
=> "Test_Insert_After",
801 end Test_Insert_After
;
803 ------------------------
804 -- Test_Insert_Before --
805 ------------------------
807 procedure Test_Insert_Before
is
808 L
: Instance
:= Create
;
811 -- Try to insert before a non-inserted element, in an empty list
813 Insert_Before
(L
, 1, 2);
815 -- At this point the list should be completely empty
818 (Caller
=> "Test_Insert_Before",
825 Insert_Before
(L
, 4, 2); -- 2, 4
826 Insert_Before
(L
, 2, 1); -- 1, 2, 4
827 Insert_Before
(L
, 4, 3); -- 1, 2, 3, 4
829 -- Try to insert before a non-inserted element, in a full list
831 Insert_Before
(L
, 10, 11);
834 (Caller
=> "Test_Insert_Before",
840 end Test_Insert_Before
;
846 procedure Test_Is_Empty
is
847 L
: Instance
:= Create
;
850 if not Is_Empty
(L
) then
851 Put_Line
("ERROR: Test_Is_Empty: list is not empty");
857 Put_Line
("ERROR: Test_Is_Empty: list is empty");
862 if not Is_Empty
(L
) then
863 Put_Line
("ERROR: Test_Is_Empty: list is not empty");
873 procedure Test_Iterate
is
877 L
: Instance
:= Create
;
880 Populate_With_Append
(L
, 1, 5);
882 -- Obtain an iterator. This action must lock all mutation operations of
885 Iter_1
:= Iterate
(L
);
887 -- Ensure that every mutation routine defined in the API fails on a list
888 -- with at least one outstanding iterator.
890 Check_Locked_Mutations
891 (Caller
=> "Test_Iterate",
894 -- Obtain another iterator
896 Iter_2
:= Iterate
(L
);
898 -- Ensure that every mutation is still locked
900 Check_Locked_Mutations
901 (Caller
=> "Test_Iterate",
904 -- Exhaust the first itertor
906 while Has_Next
(Iter_1
) loop
910 -- Ensure that every mutation is still locked
912 Check_Locked_Mutations
913 (Caller
=> "Test_Iterate",
916 -- Exhaust the second itertor
918 while Has_Next
(Iter_2
) loop
922 -- Ensure that all mutation operations are once again callable
924 Check_Unlocked_Mutations
925 (Caller
=> "Test_Iterate",
931 ------------------------
932 -- Test_Iterate_Empty --
933 ------------------------
935 procedure Test_Iterate_Empty
is
938 L
: Instance
:= Create
;
941 -- Obtain an iterator. This action must lock all mutation operations of
946 -- Ensure that every mutation routine defined in the API fails on a list
947 -- with at least one outstanding iterator.
949 Check_Locked_Mutations
950 (Caller
=> "Test_Iterate_Empty",
953 -- Attempt to iterate over the elements
955 while Has_Next
(Iter
) loop
959 ("ERROR: Test_Iterate_Empty: element" & Elem
'Img & " exists");
962 -- Ensure that all mutation operations are once again callable
964 Check_Unlocked_Mutations
965 (Caller
=> "Test_Iterate_Empty",
969 end Test_Iterate_Empty
;
971 -------------------------
972 -- Test_Iterate_Forced --
973 -------------------------
975 procedure Test_Iterate_Forced
981 L
: Instance
:= Create
;
984 Populate_With_Append
(L
, Low_Elem
, High_Elem
);
986 -- Obtain an iterator. This action must lock all mutation operations of
991 -- Ensure that every mutation routine defined in the API fails on a list
992 -- with at least one outstanding iterator.
994 Check_Locked_Mutations
995 (Caller
=> "Test_Iterate_Forced",
998 -- Forcibly advance the iterator until it raises an exception
1001 for Guard
in Low_Elem
.. High_Elem
+ 1 loop
1006 ("ERROR: Test_Iterate_Forced: Iterator_Exhausted not raised");
1008 when Iterator_Exhausted
=>
1011 Put_Line
("ERROR: Test_Iterate_Forced: unexpected exception");
1014 -- Ensure that all mutation operations are once again callable
1016 Check_Unlocked_Mutations
1017 (Caller
=> "Test_Iterate_Forced",
1021 end Test_Iterate_Forced
;
1027 procedure Test_Last
is
1029 L
: Instance
:= Create
;
1032 -- Try to obtain the tail. This operation should raise List_Empty.
1036 Put_Line
("ERROR: Test_Last: List_Empty not raised");
1041 Put_Line
("ERROR: Test_Last: unexpected exception");
1044 Populate_With_Append
(L
, 1, 2);
1051 Put_Line
("ERROR: Test_Last: wrong element");
1052 Put_Line
("expected: 2");
1053 Put_Line
("got :" & Elem
'Img);
1063 procedure Test_Prepend
is
1064 L
: Instance
:= Create
;
1074 (Caller
=> "Test_Prepend",
1086 procedure Test_Replace
is
1087 L
: Instance
:= Create
;
1090 Populate_With_Append
(L
, 1, 5);
1098 Replace
(L
, 11, 12);
1101 (Caller
=> "Test_Replace",
1113 procedure Test_Size
is
1114 L
: Instance
:= Create
;
1121 Put_Line
("ERROR: Test_Size: wrong size");
1122 Put_Line
("expected: 0");
1123 Put_Line
("got :" & S
'Img);
1126 Populate_With_Append
(L
, 1, 2);
1130 Put_Line
("ERROR: Test_Size: wrong size");
1131 Put_Line
("expected: 2");
1132 Put_Line
("got :" & S
'Img);
1135 Populate_With_Append
(L
, 3, 6);
1139 Put_Line
("ERROR: Test_Size: wrong size");
1140 Put_Line
("expected: 6");
1141 Put_Line
("got :" & S
'Img);
1147 -- Start of processing for Operations