1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.FORMAL_INDEFINITE_VECTORS --
9 -- Copyright (C) 2014-2017, 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 3, 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. --
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
23 -- additional permissions described in the GCC Runtime Library Exception, --
24 -- version 3.1, as published by the Free Software Foundation. --
26 -- You should have received a copy of the GNU General Public License and --
27 -- a copy of the GCC Runtime Library Exception along with this program; --
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
29 -- <http://www.gnu.org/licenses/>. --
30 ------------------------------------------------------------------------------
32 -- Similar to Ada.Containers.Formal_Vectors. The main difference is that
33 -- Element_Type may be indefinite (but not an unconstrained array).
35 with Ada.Containers.Bounded_Holders;
36 with Ada.Containers.Functional_Vectors;
39 type Index_Type is range <>;
40 type Element_Type (<>) is private;
41 Max_Size_In_Storage_Elements : Natural :=
42 Element_Type'Max_Size_In_Storage_Elements;
43 -- Maximum size of Vector elements in bytes. This has the same meaning as
44 -- in Ada.Containers.Bounded_Holders, with the same restrictions. Note that
45 -- setting this too small can lead to erroneous execution; see comments in
46 -- Ada.Containers.Bounded_Holders. If Element_Type is class-wide, it is the
47 -- responsibility of clients to calculate the maximum size of all types in
50 Bounded : Boolean := True;
51 -- If True, the containers are bounded; the initial capacity is the maximum
52 -- size, and heap allocation will be avoided. If False, the containers can
53 -- grow via heap allocation.
55 package Ada.Containers.Formal_Indefinite_Vectors with
58 pragma Annotate (CodePeer, Skip_Analysis);
60 subtype Extended_Index is Index_Type'Base
61 range Index_Type'First - 1 ..
62 Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
64 No_Index : constant Extended_Index := Extended_Index'First;
66 subtype Capacity_Range is
67 Count_Type range 0 .. Count_Type (Index_Type'Last - Index_Type'First + 1);
69 type Vector (Capacity : Capacity_Range) is limited private with
70 Default_Initial_Condition => Is_Empty (Vector);
71 -- In the bounded case, Capacity is the capacity of the container, which
72 -- never changes. In the unbounded case, Capacity is the initial capacity
73 -- of the container, and operations such as Reserve_Capacity and Append can
74 -- increase the capacity. The capacity never shrinks, except in the case of
77 -- Note that all objects of type Vector are constrained, including in the
78 -- unbounded case; you can't assign from one object to another if the
79 -- Capacity is different.
81 function Length (Container : Vector) return Capacity_Range with
83 Post => Length'Result <= Capacity (Container);
85 pragma Unevaluated_Use_Of_Old (Allow);
87 package Formal_Model with Ghost is
89 package M is new Ada.Containers.Functional_Vectors
90 (Index_Type => Index_Type,
91 Element_Type => Element_Type);
95 Right : M.Sequence) return Boolean renames M."=";
99 Right : M.Sequence) return Boolean renames M."<";
103 Right : M.Sequence) return Boolean renames M."<=";
105 function M_Elements_In_Union
106 (Container : M.Sequence;
108 Right : M.Sequence) return Boolean
109 -- The elements of Container are contained in either Left or Right
113 M_Elements_In_Union'Result =
114 (for all I in Index_Type'First .. M.Last (Container) =>
115 (for some J in Index_Type'First .. M.Last (Left) =>
116 Element (Container, I) = Element (Left, J))
117 or (for some J in Index_Type'First .. M.Last (Right) =>
118 Element (Container, I) = Element (Right, J)));
119 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_In_Union);
121 function M_Elements_Included
123 L_Fst : Index_Type := Index_Type'First;
124 L_Lst : Extended_Index;
126 R_Fst : Index_Type := Index_Type'First;
127 R_Lst : Extended_Index) return Boolean
128 -- The elements of the slice from L_Fst to L_Lst in Left are contained
129 -- in the slide from R_Fst to R_Lst in Right.
132 Pre => L_Lst <= M.Last (Left) and R_Lst <= M.Last (Right),
134 M_Elements_Included'Result =
135 (for all I in L_Fst .. L_Lst =>
136 (for some J in R_Fst .. R_Lst =>
137 Element (Left, I) = Element (Right, J)));
138 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Included);
140 function M_Elements_Reversed
142 Right : M.Sequence) return Boolean
143 -- Right is Left in reverse order
147 M_Elements_Reversed'Result =
148 (M.Length (Left) = M.Length (Right)
149 and (for all I in Index_Type'First .. M.Last (Left) =>
151 Element (Right, M.Last (Left) - I + 1))
152 and (for all I in Index_Type'First .. M.Last (Right) =>
154 Element (Left, M.Last (Left) - I + 1)));
155 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Reversed);
157 function M_Elements_Swapped
161 Y : Index_Type) return Boolean
162 -- Elements stored at X and Y are reversed in Left and Right
165 Pre => X <= M.Last (Left) and Y <= M.Last (Left),
167 M_Elements_Swapped'Result =
168 (M.Length (Left) = M.Length (Right)
169 and Element (Left, X) = Element (Right, Y)
170 and Element (Left, Y) = Element (Right, X)
171 and M.Equal_Except (Left, Right, X, Y));
172 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Swapped);
174 function Model (Container : Vector) return M.Sequence with
175 -- The high-level model of a vector is a sequence of elements. The
176 -- sequence really is similar to the vector itself. However, it is not
177 -- limited which allows usage of 'Old and 'Loop_Entry attributes.
181 Post => M.Length (Model'Result) = Length (Container);
185 I : Index_Type) return Element_Type renames M.Get;
186 -- To improve readability of contracts, we rename the function used to
187 -- access an element in the model to Element.
191 function Empty_Vector return Vector with
193 Post => Length (Empty_Vector'Result) = 0;
195 function "=" (Left, Right : Vector) return Boolean with
197 Post => "="'Result = (Model (Left) = Model (Right));
200 (New_Item : Element_Type;
201 Length : Capacity_Range) return Vector
205 Formal_Indefinite_Vectors.Length (To_Vector'Result) = Length
206 and M.Constant_Range (Container => Model (To_Vector'Result),
207 Fst => Index_Type'First,
208 Lst => Last_Index (To_Vector'Result),
211 function Capacity (Container : Vector) return Capacity_Range with
214 Capacity'Result = (if Bounded then Container.Capacity
215 else Capacity_Range'Last);
216 pragma Annotate (GNATprove, Inline_For_Proof, Capacity);
218 procedure Reserve_Capacity
219 (Container : in out Vector;
220 Capacity : Capacity_Range)
223 Pre => (if Bounded then Capacity <= Container.Capacity),
224 Post => Model (Container) = Model (Container)'Old;
226 function Is_Empty (Container : Vector) return Boolean with
228 Post => Is_Empty'Result = (Length (Container) = 0);
230 procedure Clear (Container : in out Vector) with
232 Post => Length (Container) = 0;
233 -- Note that this reclaims storage in the unbounded case. You need to call
234 -- this before a container goes out of scope in order to avoid storage
235 -- leaks. In addition, "X := ..." can leak unless you Clear(X) first.
237 procedure Assign (Target : in out Vector; Source : Vector) with
239 Pre => (if Bounded then Length (Source) <= Target.Capacity),
240 Post => Model (Target) = Model (Source);
244 Capacity : Capacity_Range := 0) return Vector
247 Pre => (if Bounded then (Capacity = 0 or Length (Source) <= Capacity)),
249 Model (Copy'Result) = Model (Source)
250 and (if Capacity = 0 then Copy'Result.Capacity = Length (Source)
251 else Copy'Result.Capacity = Capacity);
253 procedure Move (Target : in out Vector; Source : in out Vector)
256 Pre => (if Bounded then Length (Source) <= Capacity (Target)),
257 Post => Model (Target) = Model (Source)'Old and Length (Source) = 0;
261 Index : Index_Type) return Element_Type
264 Pre => Index in First_Index (Container) .. Last_Index (Container),
265 Post => Element'Result = Element (Model (Container), Index);
266 pragma Annotate (GNATprove, Inline_For_Proof, Element);
268 procedure Replace_Element
269 (Container : in out Vector;
271 New_Item : Element_Type)
274 Pre => Index in First_Index (Container) .. Last_Index (Container),
276 Length (Container) = Length (Container)'Old
278 -- Container now has New_Item at index Index
280 and Element (Model (Container), Index) = New_Item
282 -- All other elements are preserved
285 (Left => Model (Container)'Old,
286 Right => Model (Container),
290 (Container : in out Vector;
291 Before : Extended_Index;
296 Length (Container) <= Capacity (Container) - Length (New_Item)
297 and (Before in Index_Type'First .. Last_Index (Container)
298 or Before - 1 = Last_Index (Container)),
300 Length (Container) = Length (Container)'Old + Length (New_Item)
302 -- Elements located before Before in Container are preserved
305 (Left => Model (Container)'Old,
306 Right => Model (Container),
307 Fst => Index_Type'First,
310 -- Elements of New_Item are inserted at position Before
312 and (if Length (New_Item) > 0 then
314 (Left => Model (New_Item),
315 Right => Model (Container),
316 Fst => Index_Type'First,
317 Lst => Last_Index (New_Item),
318 Offset => Count_Type (Before - Index_Type'First)))
320 -- Elements located after Before in Container are shifted
323 (Left => Model (Container)'Old,
324 Right => Model (Container),
326 Lst => Last_Index (Container)'Old,
327 Offset => Length (New_Item));
330 (Container : in out Vector;
331 Before : Extended_Index;
332 New_Item : Element_Type)
336 Length (Container) < Capacity (Container)
337 and then (Before in Index_Type'First .. Last_Index (Container) + 1),
339 Length (Container) = Length (Container)'Old + 1
341 -- Elements located before Before in Container are preserved
344 (Left => Model (Container)'Old,
345 Right => Model (Container),
346 Fst => Index_Type'First,
349 -- Container now has New_Item at index Before
351 and Element (Model (Container), Before) = New_Item
353 -- Elements located after Before in Container are shifted by 1
356 (Left => Model (Container)'Old,
357 Right => Model (Container),
359 Lst => Last_Index (Container)'Old,
363 (Container : in out Vector;
364 Before : Extended_Index;
365 New_Item : Element_Type;
370 Length (Container) <= Capacity (Container) - Count
371 and (Before in Index_Type'First .. Last_Index (Container)
372 or Before - 1 = Last_Index (Container)),
374 Length (Container) = Length (Container)'Old + Count
376 -- Elements located before Before in Container are preserved
379 (Left => Model (Container)'Old,
380 Right => Model (Container),
381 Fst => Index_Type'First,
384 -- New_Item is inserted Count times at position Before
386 and (if Count > 0 then
388 (Container => Model (Container),
390 Lst => Before + Index_Type'Base (Count - 1),
393 -- Elements located after Before in Container are shifted
396 (Left => Model (Container)'Old,
397 Right => Model (Container),
399 Lst => Last_Index (Container)'Old,
403 (Container : in out Vector;
407 Pre => Length (Container) <= Capacity (Container) - Length (New_Item),
409 Length (Container) = Length (Container)'Old + Length (New_Item)
411 -- Elements of New_Item are inserted at the beginning of Container
414 (Left => Model (New_Item),
415 Right => Model (Container),
416 Fst => Index_Type'First,
417 Lst => Last_Index (New_Item))
419 -- Elements of Container are shifted
422 (Left => Model (Container)'Old,
423 Right => Model (Container),
424 Fst => Index_Type'First,
425 Lst => Last_Index (Container)'Old,
426 Offset => Length (New_Item));
429 (Container : in out Vector;
430 New_Item : Element_Type)
433 Pre => Length (Container) < Capacity (Container),
435 Length (Container) = Length (Container)'Old + 1
437 -- Container now has New_Item at Index_Type'First
439 and Element (Model (Container), Index_Type'First) = New_Item
441 -- Elements of Container are shifted by 1
444 (Left => Model (Container)'Old,
445 Right => Model (Container),
446 Fst => Index_Type'First,
447 Lst => Last_Index (Container)'Old,
451 (Container : in out Vector;
452 New_Item : Element_Type;
456 Pre => Length (Container) <= Capacity (Container) - Count,
458 Length (Container) = Length (Container)'Old + Count
460 -- New_Item is inserted Count times at the beginning of Container
463 (Container => Model (Container),
464 Fst => Index_Type'First,
465 Lst => Index_Type'First + Index_Type'Base (Count - 1),
468 -- Elements of Container are shifted
471 (Left => Model (Container)'Old,
472 Right => Model (Container),
473 Fst => Index_Type'First,
474 Lst => Last_Index (Container)'Old,
478 (Container : in out Vector;
483 Length (Container) <= Capacity (Container) - Length (New_Item),
485 Length (Container) = Length (Container)'Old + Length (New_Item)
487 -- The elements of Container are preserved
489 and Model (Container)'Old <= Model (Container)
491 -- Elements of New_Item are inserted at the end of Container
493 and (if Length (New_Item) > 0 then
495 (Left => Model (New_Item),
496 Right => Model (Container),
497 Fst => Index_Type'First,
498 Lst => Last_Index (New_Item),
501 (Last_Index (Container)'Old - Index_Type'First + 1)));
504 (Container : in out Vector;
505 New_Item : Element_Type)
508 Pre => Length (Container) < Capacity (Container),
510 Length (Container) = Length (Container)'Old + 1
512 -- Elements of Container are preserved
514 and Model (Container)'Old < Model (Container)
516 -- Container now has New_Item at the end of Container
519 (Model (Container), Last_Index (Container)'Old + 1) = New_Item;
522 (Container : in out Vector;
523 New_Item : Element_Type;
527 Pre => Length (Container) <= Capacity (Container) - Count,
529 Length (Container) = Length (Container)'Old + Count
531 -- Elements of Container are preserved
533 and Model (Container)'Old <= Model (Container)
535 -- New_Item is inserted Count times at the end of Container
537 and (if Count > 0 then
539 (Container => Model (Container),
540 Fst => Last_Index (Container)'Old + 1,
542 Last_Index (Container)'Old + Index_Type'Base (Count),
546 (Container : in out Vector;
547 Index : Extended_Index)
550 Pre => Index in First_Index (Container) .. Last_Index (Container),
552 Length (Container) = Length (Container)'Old - 1
554 -- Elements located before Index in Container are preserved
557 (Left => Model (Container)'Old,
558 Right => Model (Container),
559 Fst => Index_Type'First,
562 -- Elements located after Index in Container are shifted by 1
565 (Left => Model (Container),
566 Right => Model (Container)'Old,
568 Lst => Last_Index (Container),
572 (Container : in out Vector;
573 Index : Extended_Index;
578 Index in First_Index (Container) .. Last_Index (Container),
580 Length (Container) in
581 Length (Container)'Old - Count .. Length (Container)'Old
583 -- The elements of Container located before Index are preserved.
586 (Left => Model (Container)'Old,
587 Right => Model (Container),
588 Fst => Index_Type'First,
593 -- All the elements after Position have been erased
595 (Length (Container) - Count <= Count_Type (Index - Index_Type'First) =>
596 Length (Container) = Count_Type (Index - Index_Type'First),
599 Length (Container) = Length (Container)'Old - Count
601 -- Other elements are shifted by Count
604 (Left => Model (Container),
605 Right => Model (Container)'Old,
607 Lst => Last_Index (Container),
610 procedure Delete_First
611 (Container : in out Vector)
614 Pre => Length (Container) > 0,
616 Length (Container) = Length (Container)'Old - 1
618 -- Elements of Container are shifted by 1
621 (Left => Model (Container),
622 Right => Model (Container)'Old,
623 Fst => Index_Type'First,
624 Lst => Last_Index (Container),
627 procedure Delete_First
628 (Container : in out Vector;
634 -- All the elements of Container have been erased
636 (Length (Container) <= Count => Length (Container) = 0,
639 Length (Container) = Length (Container)'Old - Count
641 -- Elements of Container are shifted by Count
644 (Left => Model (Container),
645 Right => Model (Container)'Old,
646 Fst => Index_Type'First,
647 Lst => Last_Index (Container),
650 procedure Delete_Last
651 (Container : in out Vector)
654 Pre => Length (Container) > 0,
656 Length (Container) = Length (Container)'Old - 1
658 -- Elements of Container are preserved
660 and Model (Container) < Model (Container)'Old;
662 procedure Delete_Last
663 (Container : in out Vector;
669 -- All the elements after Position have been erased
671 (Length (Container) <= Count => Length (Container) = 0,
674 Length (Container) = Length (Container)'Old - Count
676 -- The elements of Container are preserved
678 and Model (Container) <= Model (Container)'Old);
680 procedure Reverse_Elements (Container : in out Vector) with
682 Post => M_Elements_Reversed (Model (Container)'Old, Model (Container));
684 procedure Swap (Container : in out Vector; I, J : Index_Type) with
686 Pre => I in First_Index (Container) .. Last_Index (Container)
687 and then J in First_Index (Container) .. Last_Index (Container),
689 M_Elements_Swapped (Model (Container)'Old, Model (Container), I, J);
691 function First_Index (Container : Vector) return Index_Type with
693 Post => First_Index'Result = Index_Type'First;
694 pragma Annotate (GNATprove, Inline_For_Proof, First_Index);
696 function First_Element (Container : Vector) return Element_Type with
698 Pre => not Is_Empty (Container),
700 First_Element'Result = Element (Model (Container), Index_Type'First);
701 pragma Annotate (GNATprove, Inline_For_Proof, First_Element);
703 function Last_Index (Container : Vector) return Extended_Index with
705 Post => Last_Index'Result = M.Last (Model (Container));
706 pragma Annotate (GNATprove, Inline_For_Proof, Last_Index);
708 function Last_Element (Container : Vector) return Element_Type with
710 Pre => not Is_Empty (Container),
712 Last_Element'Result =
713 Element (Model (Container), Last_Index (Container));
714 pragma Annotate (GNATprove, Inline_For_Proof, Last_Element);
719 Index : Index_Type := Index_Type'First) return Extended_Index
724 -- If Item is not is not contained in Container after Index, Find_Index
727 (Index > Last_Index (Container)
728 or else not M.Contains
729 (Container => Model (Container),
731 Lst => Last_Index (Container),
734 Find_Index'Result = No_Index,
736 -- Otherwise, Find_Index returns a valid index greater than Index
739 Find_Index'Result in Index .. Last_Index (Container)
741 -- The element at this index in Container is Item
743 and Element (Model (Container), Find_Index'Result) = Item
745 -- It is the first occurrence of Item after Index in Container
748 (Container => Model (Container),
750 Lst => Find_Index'Result - 1,
753 function Reverse_Find_Index
756 Index : Index_Type := Index_Type'Last) return Extended_Index
761 -- If Item is not is not contained in Container before Index,
762 -- Reverse_Find_Index returns No_Index.
765 (Container => Model (Container),
766 Fst => Index_Type'First,
767 Lst => (if Index <= Last_Index (Container) then Index
768 else Last_Index (Container)),
771 Reverse_Find_Index'Result = No_Index,
773 -- Otherwise, Reverse_Find_Index returns a valid index smaller than
777 Reverse_Find_Index'Result in Index_Type'First .. Index
778 and Reverse_Find_Index'Result <= Last_Index (Container)
780 -- The element at this index in Container is Item
782 and Element (Model (Container), Reverse_Find_Index'Result) = Item
784 -- It is the last occurrence of Item before Index in Container
787 (Container => Model (Container),
788 Fst => Reverse_Find_Index'Result + 1,
790 (if Index <= Last_Index (Container) then Index
791 else Last_Index (Container)),
796 Item : Element_Type) return Boolean
800 Contains'Result = M.Contains (Container => Model (Container),
801 Fst => Index_Type'First,
802 Lst => Last_Index (Container),
807 Position : Extended_Index) return Boolean
812 (Position in Index_Type'First .. Last_Index (Container));
813 pragma Annotate (GNATprove, Inline_For_Proof, Has_Element);
816 with function "<" (Left, Right : Element_Type) return Boolean is <>;
817 package Generic_Sorting with SPARK_Mode is
818 function M_Elements_Sorted (Container : M.Sequence) return Boolean with
822 M_Elements_Sorted'Result =
823 (for all I in Index_Type'First .. M.Last (Container) =>
824 (for all J in I .. M.Last (Container) =>
825 Element (Container, I) = Element (Container, J)
826 or Element (Container, I) < Element (Container, J)));
827 pragma Annotate (GNATprove, Inline_For_Proof, M_Elements_Sorted);
829 function Is_Sorted (Container : Vector) return Boolean with
831 Post => Is_Sorted'Result = M_Elements_Sorted (Model (Container));
833 procedure Sort (Container : in out Vector) with
836 Length (Container) = Length (Container)'Old
837 and M_Elements_Sorted (Model (Container))
838 and M_Elements_Included (Left => Model (Container)'Old,
839 L_Lst => Last_Index (Container),
840 Right => Model (Container),
841 R_Lst => Last_Index (Container))
842 and M_Elements_Included (Left => Model (Container),
843 L_Lst => Last_Index (Container),
844 Right => Model (Container)'Old,
845 R_Lst => Last_Index (Container));
847 procedure Merge (Target : in out Vector; Source : in out Vector) with
848 -- Target and Source should not be aliased
850 Pre => Length (Source) <= Capacity (Target) - Length (Target),
852 Length (Target) = Length (Target)'Old + Length (Source)'Old
853 and Length (Source) = 0
854 and (if M_Elements_Sorted (Model (Target)'Old)
855 and M_Elements_Sorted (Model (Source)'Old)
856 then M_Elements_Sorted (Model (Target)))
857 and M_Elements_Included (Left => Model (Target)'Old,
858 L_Lst => Last_Index (Target)'Old,
859 Right => Model (Target),
860 R_Lst => Last_Index (Target))
861 and M_Elements_Included (Left => Model (Source)'Old,
862 L_Lst => Last_Index (Source)'Old,
863 Right => Model (Target),
864 R_Lst => Last_Index (Target))
865 and M_Elements_In_Union (Model (Target),
871 pragma SPARK_Mode (Off);
873 pragma Inline (First_Index);
874 pragma Inline (Last_Index);
875 pragma Inline (Element);
876 pragma Inline (First_Element);
877 pragma Inline (Last_Element);
878 pragma Inline (Replace_Element);
879 pragma Inline (Contains);
881 -- The implementation method is to instantiate Bounded_Holders to get a
882 -- definite type for Element_Type.
884 package Holders is new Bounded_Holders
885 (Element_Type, Max_Size_In_Storage_Elements, "=");
888 subtype Array_Index is Capacity_Range range 1 .. Capacity_Range'Last;
889 type Elements_Array is array (Array_Index range <>) of Holder;
890 function "=" (L, R : Elements_Array) return Boolean is abstract;
892 type Elements_Array_Ptr is access all Elements_Array;
894 type Vector (Capacity : Capacity_Range) is limited record
895 -- In the bounded case, the elements are stored in Elements. In the
896 -- unbounded case, the elements are initially stored in Elements, until
897 -- we run out of room, then we switch to Elements_Ptr.
898 Last : Extended_Index := No_Index;
899 Elements_Ptr : Elements_Array_Ptr := null;
900 Elements : aliased Elements_Array (1 .. Capacity);
903 -- The primary reason Vector is limited is that in the unbounded case, once
904 -- Elements_Ptr is in use, assignment statements won't work. "X := Y;" will
905 -- cause X and Y to share state; that is, X.Elements_Ptr = Y.Elements_Ptr,
906 -- so for example "Append (X, ...);" will modify BOTH X and Y. That would
907 -- allow SPARK to "prove" things that are false. We could fix that by
908 -- making Vector a controlled type, and override Adjust to make a deep
909 -- copy, but finalization is not allowed in SPARK.
911 -- Note that (unfortunately) this means that 'Old and 'Loop_Entry are not
912 -- allowed on Vectors.
914 function Empty_Vector return Vector is
915 ((Capacity => 0, others => <>));
917 end Ada.Containers.Formal_Indefinite_Vectors;