1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . F O R M A L _ V E C T O R S --
9 -- Copyright (C) 2010-2013, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 ------------------------------------------------------------------------------
28 with Ada
.Containers
.Generic_Array_Sort
;
29 with System
; use type System
.Address
;
31 package body Ada
.Containers
.Formal_Vectors
is
33 type Int
is range System
.Min_Int
.. System
.Max_Int
;
34 type UInt
is mod System
.Max_Binary_Modulus
;
38 Position
: Count_Type
) return Element_Type
;
40 procedure Insert_Space
41 (Container
: in out Vector
;
42 Before
: Extended_Index
;
43 Count
: Count_Type
:= 1);
49 function "&" (Left
, Right
: Vector
) return Vector
is
50 LN
: constant Count_Type
:= Length
(Left
);
51 RN
: constant Count_Type
:= Length
(Right
);
60 E
: constant Elements_Array
(1 .. Length
(Right
)) :=
61 Right
.Elements
(1 .. RN
);
63 return (Length
(Right
), E
, Last
=> Right
.Last
, others => <>);
69 E
: constant Elements_Array
(1 .. Length
(Left
)) :=
70 Left
.Elements
(1 .. LN
);
72 return (Length
(Left
), E
, Last
=> Left
.Last
, others => <>);
77 N
: constant Int
'Base := Int
(LN
) + Int
(RN
);
78 Last_As_Int
: Int
'Base;
81 if Int
(No_Index
) > Int
'Last - N
then
82 raise Constraint_Error
with "new length is out of range";
85 Last_As_Int
:= Int
(No_Index
) + N
;
87 if Last_As_Int
> Int
(Index_Type
'Last) then
88 raise Constraint_Error
with "new length is out of range";
91 -- TODO: should check whether length > max capacity (cnt_t'last) ???
94 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
96 LE
: constant Elements_Array
(1 .. LN
) := Left
.Elements
(1 .. LN
);
97 RE
: Elements_Array
renames Right
.Elements
(1 .. RN
);
99 Capacity
: constant Count_Type
:= Length
(Left
) + Length
(Right
);
102 return (Capacity
, LE
& RE
, Last
=> Last
, others => <>);
107 function "&" (Left
: Vector
; Right
: Element_Type
) return Vector
is
108 LN
: constant Count_Type
:= Length
(Left
);
109 Last_As_Int
: Int
'Base;
113 return (1, (1 .. 1 => Right
), Index_Type
'First, others => <>);
116 if Int
(Index_Type
'First) > Int
'Last - Int
(LN
) then
117 raise Constraint_Error
with "new length is out of range";
120 Last_As_Int
:= Int
(Index_Type
'First) + Int
(LN
);
122 if Last_As_Int
> Int
(Index_Type
'Last) then
123 raise Constraint_Error
with "new length is out of range";
127 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
128 LE
: constant Elements_Array
(1 .. LN
) := Left
.Elements
(1 .. LN
);
130 Capacity
: constant Count_Type
:= Length
(Left
) + 1;
133 return (Capacity
, LE
& Right
, Last
=> Last
, others => <>);
137 function "&" (Left
: Element_Type
; Right
: Vector
) return Vector
is
138 RN
: constant Count_Type
:= Length
(Right
);
139 Last_As_Int
: Int
'Base;
143 return (1, (1 .. 1 => Left
),
144 Index_Type
'First, others => <>);
147 if Int
(Index_Type
'First) > Int
'Last - Int
(RN
) then
148 raise Constraint_Error
with "new length is out of range";
151 Last_As_Int
:= Int
(Index_Type
'First) + Int
(RN
);
153 if Last_As_Int
> Int
(Index_Type
'Last) then
154 raise Constraint_Error
with "new length is out of range";
158 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
159 RE
: Elements_Array
renames Right
.Elements
(1 .. RN
);
160 Capacity
: constant Count_Type
:= 1 + Length
(Right
);
162 return (Capacity
, Left
& RE
, Last
=> Last
, others => <>);
166 function "&" (Left
, Right
: Element_Type
) return Vector
is
168 if Index_Type
'First >= Index_Type
'Last then
169 raise Constraint_Error
with "new length is out of range";
173 Last
: constant Index_Type
:= Index_Type
'First + 1;
175 return (2, (Left
, Right
), Last
=> Last
, others => <>);
183 function "=" (Left
, Right
: Vector
) return Boolean is
185 if Left
'Address = Right
'Address then
189 if Length
(Left
) /= Length
(Right
) then
193 for J
in Count_Type
range 1 .. Length
(Left
) loop
194 if Get_Element
(Left
, J
) /= Get_Element
(Right
, J
) then
206 procedure Append
(Container
: in out Vector
; New_Item
: Vector
) is
208 if Is_Empty
(New_Item
) then
212 if Container
.Last
= Index_Type
'Last then
213 raise Constraint_Error
with "vector is already at its maximum length";
216 Insert
(Container
, Container
.Last
+ 1, New_Item
);
220 (Container
: in out Vector
;
221 New_Item
: Element_Type
;
222 Count
: Count_Type
:= 1)
229 if Container
.Last
= Index_Type
'Last then
230 raise Constraint_Error
with "vector is already at its maximum length";
233 -- TODO: should check whether length > max capacity (cnt_t'last) ???
235 Insert
(Container
, Container
.Last
+ 1, New_Item
, Count
);
242 procedure Assign
(Target
: in out Vector
; Source
: Vector
) is
243 LS
: constant Count_Type
:= Length
(Source
);
246 if Target
'Address = Source
'Address then
250 if Target
.Capacity
< LS
then
251 raise Constraint_Error
;
256 Target
.Elements
(1 .. LS
) := Source
.Elements
(1 .. LS
);
257 Target
.Last
:= Source
.Last
;
264 function Capacity
(Container
: Vector
) return Count_Type
is
266 return Container
.Elements
'Length;
273 procedure Clear
(Container
: in out Vector
) is
275 Container
.Last
:= No_Index
;
284 Item
: Element_Type
) return Boolean
287 return Find_Index
(Container
, Item
) /= No_Index
;
296 Capacity
: Count_Type
:= 0) return Vector
298 LS
: constant Count_Type
:= Length
(Source
);
304 elsif Capacity
>= LS
and then Capacity
in Capacity_Range
then
307 raise Capacity_Error
;
310 return Target
: Vector
(C
) do
311 Target
.Elements
(1 .. LS
) := Source
.Elements
(1 .. LS
);
312 Target
.Last
:= Source
.Last
;
316 ---------------------
317 -- Current_To_Last --
318 ---------------------
320 function Current_To_Last
322 Current
: Cursor
) return Vector
324 C
: Vector
(Container
.Capacity
) := Copy
(Container
, Container
.Capacity
);
327 if Current
= No_Element
then
331 elsif not Has_Element
(Container
, Current
) then
332 raise Constraint_Error
;
335 while C
.Last
/= Container
.Last
- Current
.Index
+ 1 loop
348 (Container
: in out Vector
;
349 Index
: Extended_Index
;
350 Count
: Count_Type
:= 1)
353 if Index
< Index_Type
'First then
354 raise Constraint_Error
with "Index is out of range (too small)";
357 if Index
> Container
.Last
then
358 if Index
> Container
.Last
+ 1 then
359 raise Constraint_Error
with "Index is out of range (too large)";
370 I_As_Int
: constant Int
:= Int
(Index
);
371 Old_Last_As_Int
: constant Int
:= Index_Type
'Pos (Container
.Last
);
373 Count1
: constant Int
'Base := Count_Type
'Pos (Count
);
374 Count2
: constant Int
'Base := Old_Last_As_Int
- I_As_Int
+ 1;
375 N
: constant Int
'Base := Int
'Min (Count1
, Count2
);
377 J_As_Int
: constant Int
'Base := I_As_Int
+ N
;
380 if J_As_Int
> Old_Last_As_Int
then
381 Container
.Last
:= Index
- 1;
385 EA
: Elements_Array
renames Container
.Elements
;
387 II
: constant Int
'Base := I_As_Int
- Int
(No_Index
);
388 I
: constant Count_Type
:= Count_Type
(II
);
390 JJ
: constant Int
'Base := J_As_Int
- Int
(No_Index
);
391 J
: constant Count_Type
:= Count_Type
(JJ
);
393 New_Last_As_Int
: constant Int
'Base := Old_Last_As_Int
- N
;
394 New_Last
: constant Index_Type
:=
395 Index_Type
(New_Last_As_Int
);
397 KK
: constant Int
:= New_Last_As_Int
- Int
(No_Index
);
398 K
: constant Count_Type
:= Count_Type
(KK
);
401 EA
(I
.. K
) := EA
(J
.. Length
(Container
));
402 Container
.Last
:= New_Last
;
409 (Container
: in out Vector
;
410 Position
: in out Cursor
;
411 Count
: Count_Type
:= 1)
414 if not Position
.Valid
then
415 raise Constraint_Error
with "Position cursor has no element";
418 if Position
.Index
> Container
.Last
then
419 raise Program_Error
with "Position index is out of range";
422 Delete
(Container
, Position
.Index
, Count
);
423 Position
:= No_Element
;
430 procedure Delete_First
431 (Container
: in out Vector
;
432 Count
: Count_Type
:= 1)
439 if Count
>= Length
(Container
) then
444 Delete
(Container
, Index_Type
'First, Count
);
451 procedure Delete_Last
452 (Container
: in out Vector
;
453 Count
: Count_Type
:= 1)
462 Index
:= Int
'Base (Container
.Last
) - Int
'Base (Count
);
464 if Index
< Index_Type
'Pos (Index_Type
'First) then
465 Container
.Last
:= No_Index
;
467 Container
.Last
:= Index_Type
(Index
);
477 Index
: Index_Type
) return Element_Type
480 if Index
> Container
.Last
then
481 raise Constraint_Error
with "Index is out of range";
485 II
: constant Int
'Base := Int
(Index
) - Int
(No_Index
);
486 I
: constant Count_Type
:= Count_Type
(II
);
488 return Get_Element
(Container
, I
);
494 Position
: Cursor
) return Element_Type
496 Lst
: constant Index_Type
:= Last_Index
(Container
);
499 if not Position
.Valid
then
500 raise Constraint_Error
with "Position cursor has no element";
503 if Position
.Index
> Lst
then
504 raise Constraint_Error
with "Position cursor is out of range";
508 II
: constant Int
'Base := Int
(Position
.Index
) - Int
(No_Index
);
509 I
: constant Count_Type
:= Count_Type
(II
);
511 return Get_Element
(Container
, I
);
522 Position
: Cursor
:= No_Element
) return Cursor
525 Last
: constant Index_Type
:= Last_Index
(Container
);
528 if Position
.Valid
then
529 if Position
.Index
> Last_Index
(Container
) then
530 raise Program_Error
with "Position index is out of range";
534 K
:= Count_Type
(Int
(Position
.Index
) - Int
(No_Index
));
536 for J
in Position
.Index
.. Last
loop
537 if Get_Element
(Container
, K
) = Item
then
538 return Cursor
'(Index => J, others => <>);
554 Index : Index_Type := Index_Type'First) return Extended_Index
557 Last : constant Index_Type := Last_Index (Container);
560 K := Count_Type (Int (Index) - Int (No_Index));
561 for Indx in Index .. Last loop
562 if Get_Element (Container, K) = Item then
576 function First (Container : Vector) return Cursor is
578 if Is_Empty (Container) then
582 return (True, Index_Type'First);
589 function First_Element (Container : Vector) return Element_Type is
591 if Is_Empty (Container) then
592 raise Constraint_Error with "Container is empty";
595 return Get_Element (Container, 1);
602 function First_Index (Container : Vector) return Index_Type is
603 pragma Unreferenced (Container);
605 return Index_Type'First;
608 -----------------------
609 -- First_To_Previous --
610 -----------------------
612 function First_To_Previous
614 Current : Cursor) return Vector
616 C : Vector (Container.Capacity) := Copy (Container, Container.Capacity);
619 if Current = No_Element then
622 elsif not Has_Element (Container, Current) then
623 raise Constraint_Error;
626 while C.Last /= Current.Index - 1 loop
632 end First_To_Previous;
634 ---------------------
635 -- Generic_Sorting --
636 ---------------------
638 package body Generic_Sorting is
644 function Is_Sorted (Container : Vector) return Boolean is
645 Last : constant Index_Type := Last_Index (Container);
648 if Container.Last <= Last then
653 L : constant Count_Type := Length (Container);
655 for J in Count_Type range 1 .. L - 1 loop
656 if Get_Element (Container, J + 1) <
657 Get_Element (Container, J)
671 procedure Merge (Target, Source : in out Vector) is
674 TA : Elements_Array renames Target.Elements;
675 SA : Elements_Array renames Source.Elements;
681 -- if Target.Last < Index_Type'First then
682 -- Move (Target => Target, Source => Source);
686 if Target'Address = Source'Address then
690 if Source.Last < Index_Type'First then
694 -- I think we're missing this check in a-convec.adb... ???
696 I := Length (Target);
697 Set_Length (Target, I + Length (Source));
699 J := Length (Target);
700 while not Is_Empty (Source) loop
701 pragma Assert (Length (Source) <= 1
702 or else not (SA (Length (Source)) <
703 SA (Length (Source) - 1)));
706 TA (1 .. J) := SA (1 .. Length (Source));
707 Source.Last := No_Index;
711 pragma Assert (I <= 1 or else not (TA (I) < TA (I - 1)));
713 if SA (Length (Source)) < TA (I) then
718 TA (J) := SA (Length (Source));
719 Source.Last := Source.Last - 1;
731 procedure Sort (Container : in out Vector)
734 new Generic_Array_Sort
735 (Index_Type => Count_Type,
736 Element_Type => Element_Type,
737 Array_Type => Elements_Array,
741 if Container.Last <= Index_Type'First then
745 Sort (Container.Elements (1 .. Length (Container)));
756 Position : Count_Type) return Element_Type
759 return Container.Elements (Position);
768 Position : Cursor) return Boolean
771 if not Position.Valid then
774 return Position.Index <= Last_Index (Container);
783 (Container : in out Vector;
784 Before : Extended_Index;
785 New_Item : Element_Type;
786 Count : Count_Type := 1)
788 N : constant Int := Count_Type'Pos (Count);
790 First : constant Int := Int (Index_Type'First);
791 New_Last_As_Int : Int'Base;
792 New_Last : Index_Type;
794 Max_Length : constant UInt := UInt (Container.Capacity);
797 if Before < Index_Type'First then
798 raise Constraint_Error with
799 "Before index is out of range (too small)";
802 if Before > Container.Last
803 and then Before > Container.Last + 1
805 raise Constraint_Error with
806 "Before index is out of range (too large)";
814 Old_Last_As_Int : constant Int := Int (Container.Last);
817 if Old_Last_As_Int > Int'Last - N then
818 raise Constraint_Error with "new length is out of range";
821 New_Last_As_Int := Old_Last_As_Int + N;
823 if New_Last_As_Int > Int (Index_Type'Last) then
824 raise Constraint_Error with "new length is out of range";
827 New_Length := UInt (New_Last_As_Int - First + Int'(1));
829 if New_Length
> Max_Length
then
830 raise Constraint_Error
with "new length is out of range";
833 New_Last
:= Index_Type
(New_Last_As_Int
);
835 -- Resolve issue of capacity vs. max index ???
839 EA
: Elements_Array
renames Container
.Elements
;
841 BB
: constant Int
'Base := Int
(Before
) - Int
(No_Index
);
842 B
: constant Count_Type
:= Count_Type
(BB
);
844 LL
: constant Int
'Base := New_Last_As_Int
- Int
(No_Index
);
845 L
: constant Count_Type
:= Count_Type
(LL
);
848 if Before
<= Container
.Last
then
850 II
: constant Int
'Base := BB
+ N
;
851 I
: constant Count_Type
:= Count_Type
(II
);
853 EA
(I
.. L
) := EA
(B
.. Length
(Container
));
854 EA
(B
.. I
- 1) := (others => New_Item
);
858 EA
(B
.. L
) := (others => New_Item
);
862 Container
.Last
:= New_Last
;
866 (Container
: in out Vector
;
867 Before
: Extended_Index
;
870 N
: constant Count_Type
:= Length
(New_Item
);
873 if Before
< Index_Type
'First then
874 raise Constraint_Error
with
875 "Before index is out of range (too small)";
878 if Before
> Container
.Last
879 and then Before
> Container
.Last
+ 1
881 raise Constraint_Error
with
882 "Before index is out of range (too large)";
889 Insert_Space
(Container
, Before
, Count
=> N
);
892 Dst_Last_As_Int
: constant Int
'Base :=
893 Int
(Before
) + Int
(N
) - 1 - Int
(No_Index
);
895 Dst_Last
: constant Count_Type
:= Count_Type
(Dst_Last_As_Int
);
897 BB
: constant Int
'Base := Int
(Before
) - Int
(No_Index
);
898 B
: constant Count_Type
:= Count_Type
(BB
);
901 if Container
'Address /= New_Item
'Address then
902 Container
.Elements
(B
.. Dst_Last
) := New_Item
.Elements
(1 .. N
);
907 Src
: Elements_Array
renames Container
.Elements
(1 .. B
- 1);
909 Index_As_Int
: constant Int
'Base := BB
+ Src
'Length - 1;
911 Index
: constant Count_Type
:= Count_Type
(Index_As_Int
);
913 Dst
: Elements_Array
renames Container
.Elements
(B
.. Index
);
919 if Dst_Last
= Length
(Container
) then
924 Src
: Elements_Array
renames
925 Container
.Elements
(Dst_Last
+ 1 .. Length
(Container
));
927 Index_As_Int
: constant Int
'Base :=
928 Dst_Last_As_Int
- Src
'Length + 1;
930 Index
: constant Count_Type
:= Count_Type
(Index_As_Int
);
932 Dst
: Elements_Array
renames
933 Container
.Elements
(Index
.. Dst_Last
);
942 (Container
: in out Vector
;
946 Index
: Index_Type
'Base;
949 if Is_Empty
(New_Item
) then
954 or else Before
.Index
> Container
.Last
956 if Container
.Last
= Index_Type
'Last then
957 raise Constraint_Error
with
958 "vector is already at its maximum length";
961 Index
:= Container
.Last
+ 1;
964 Index
:= Before
.Index
;
967 Insert
(Container
, Index
, New_Item
);
971 (Container
: in out Vector
;
974 Position
: out Cursor
)
976 Index
: Index_Type
'Base;
979 if Is_Empty
(New_Item
) then
981 or else Before
.Index
> Container
.Last
983 Position
:= No_Element
;
985 Position
:= (True, Before
.Index
);
992 or else Before
.Index
> Container
.Last
994 if Container
.Last
= Index_Type
'Last then
995 raise Constraint_Error
with
996 "vector is already at its maximum length";
999 Index
:= Container
.Last
+ 1;
1002 Index
:= Before
.Index
;
1005 Insert
(Container
, Index
, New_Item
);
1007 Position
:= Cursor
'(True, Index);
1011 (Container : in out Vector;
1013 New_Item : Element_Type;
1014 Count : Count_Type := 1)
1016 Index : Index_Type'Base;
1024 or else Before.Index > Container.Last
1026 if Container.Last = Index_Type'Last then
1027 raise Constraint_Error with
1028 "vector is already at its maximum length";
1031 Index := Container.Last + 1;
1034 Index := Before.Index;
1037 Insert (Container, Index, New_Item, Count);
1041 (Container : in out Vector;
1043 New_Item : Element_Type;
1044 Position : out Cursor;
1045 Count : Count_Type := 1)
1047 Index : Index_Type'Base;
1052 or else Before.Index > Container.Last
1054 Position := No_Element;
1056 Position := (True, Before.Index);
1063 or else Before.Index > Container.Last
1065 if Container.Last = Index_Type'Last then
1066 raise Constraint_Error with
1067 "vector is already at its maximum length";
1070 Index := Container.Last + 1;
1073 Index := Before.Index;
1076 Insert (Container, Index, New_Item, Count);
1078 Position := Cursor'(True, Index
);
1085 procedure Insert_Space
1086 (Container
: in out Vector
;
1087 Before
: Extended_Index
;
1088 Count
: Count_Type
:= 1)
1090 N
: constant Int
:= Count_Type
'Pos (Count
);
1092 First
: constant Int
:= Int
(Index_Type
'First);
1093 New_Last_As_Int
: Int
'Base;
1094 New_Last
: Index_Type
;
1096 Max_Length
: constant UInt
:= UInt
(Count_Type
'Last);
1099 if Before
< Index_Type
'First then
1100 raise Constraint_Error
with
1101 "Before index is out of range (too small)";
1104 if Before
> Container
.Last
1105 and then Before
> Container
.Last
+ 1
1107 raise Constraint_Error
with
1108 "Before index is out of range (too large)";
1116 Old_Last_As_Int
: constant Int
:= Int
(Container
.Last
);
1119 if Old_Last_As_Int
> Int
'Last - N
then
1120 raise Constraint_Error
with "new length is out of range";
1123 New_Last_As_Int
:= Old_Last_As_Int
+ N
;
1125 if New_Last_As_Int
> Int
(Index_Type
'Last) then
1126 raise Constraint_Error
with "new length is out of range";
1129 New_Length
:= UInt
(New_Last_As_Int
- First
+ Int
'(1));
1131 if New_Length > Max_Length then
1132 raise Constraint_Error with "new length is out of range";
1135 New_Last := Index_Type (New_Last_As_Int);
1137 -- Resolve issue of capacity vs. max index ???
1141 EA : Elements_Array renames Container.Elements;
1143 BB : constant Int'Base := Int (Before) - Int (No_Index);
1144 B : constant Count_Type := Count_Type (BB);
1146 LL : constant Int'Base := New_Last_As_Int - Int (No_Index);
1147 L : constant Count_Type := Count_Type (LL);
1150 if Before <= Container.Last then
1152 II : constant Int'Base := BB + N;
1153 I : constant Count_Type := Count_Type (II);
1155 EA (I .. L) := EA (B .. Length (Container));
1160 Container.Last := New_Last;
1167 function Is_Empty (Container : Vector) return Boolean is
1169 return Last_Index (Container) < Index_Type'First;
1176 function Last (Container : Vector) return Cursor is
1178 if Is_Empty (Container) then
1182 return (True, Last_Index (Container));
1189 function Last_Element (Container : Vector) return Element_Type is
1191 if Is_Empty (Container) then
1192 raise Constraint_Error with "Container is empty";
1195 return Get_Element (Container, Length (Container));
1202 function Last_Index (Container : Vector) return Extended_Index is
1204 return Container.Last;
1211 function Length (Container : Vector) return Count_Type is
1212 L : constant Int := Int (Last_Index (Container));
1213 F : constant Int := Int (Index_Type'First);
1214 N : constant Int'Base := L - F + 1;
1217 return Count_Type (N);
1225 (Target : in out Vector;
1226 Source : in out Vector)
1228 N : constant Count_Type := Length (Source);
1231 if Target'Address = Source'Address then
1235 if N > Target.Capacity then
1236 raise Constraint_Error with -- correct exception here???
1237 "length of Source is greater than capacity of Target";
1240 -- We could also write this as a loop, and incrementally
1241 -- copy elements from source to target.
1243 Target.Last := No_Index; -- in case array assignment files
1244 Target.Elements (1 .. N) := Source.Elements (1 .. N);
1246 Target.Last := Source.Last;
1247 Source.Last := No_Index;
1254 function Next (Container : Vector; Position : Cursor) return Cursor is
1256 if not Position.Valid then
1260 if Position.Index < Last_Index (Container) then
1261 return (True, Position.Index + 1);
1271 procedure Next (Container : Vector; Position : in out Cursor) is
1273 if not Position.Valid then
1277 if Position.Index < Last_Index (Container) then
1278 Position.Index := Position.Index + 1;
1280 Position := No_Element;
1288 procedure Prepend (Container : in out Vector; New_Item : Vector) is
1290 Insert (Container, Index_Type'First, New_Item);
1294 (Container : in out Vector;
1295 New_Item : Element_Type;
1296 Count : Count_Type := 1)
1309 procedure Previous (Container : Vector; Position : in out Cursor) is
1311 if not Position.Valid then
1315 if Position.Index > Index_Type'First
1316 and then Position.Index <= Last_Index (Container)
1318 Position.Index := Position.Index - 1;
1320 Position := No_Element;
1324 function Previous (Container : Vector; Position : Cursor) return Cursor is
1326 if not Position.Valid then
1330 if Position.Index > Index_Type'First
1331 and then Position.Index <= Last_Index (Container)
1333 return (True, Position.Index - 1);
1339 ---------------------
1340 -- Replace_Element --
1341 ---------------------
1343 procedure Replace_Element
1344 (Container : in out Vector;
1346 New_Item : Element_Type)
1349 if Index > Container.Last then
1350 raise Constraint_Error with "Index is out of range";
1354 II : constant Int'Base := Int (Index) - Int (No_Index);
1355 I : constant Count_Type := Count_Type (II);
1358 Container.Elements (I) := New_Item;
1360 end Replace_Element;
1362 procedure Replace_Element
1363 (Container : in out Vector;
1365 New_Item : Element_Type)
1368 if not Position.Valid then
1369 raise Constraint_Error with "Position cursor has no element";
1372 if Position.Index > Container.Last then
1373 raise Constraint_Error with "Position cursor is out of range";
1377 II : constant Int'Base := Int (Position.Index) - Int (No_Index);
1378 I : constant Count_Type := Count_Type (II);
1380 Container.Elements (I) := New_Item;
1382 end Replace_Element;
1384 ----------------------
1385 -- Reserve_Capacity --
1386 ----------------------
1388 procedure Reserve_Capacity
1389 (Container : in out Vector;
1390 Capacity : Count_Type)
1393 if Capacity > Container.Capacity then
1394 raise Constraint_Error with "Capacity is out of range";
1396 end Reserve_Capacity;
1398 ----------------------
1399 -- Reverse_Elements --
1400 ----------------------
1402 procedure Reverse_Elements (Container : in out Vector) is
1404 if Length (Container) <= 1 then
1410 E : Elements_Array renames Container.Elements;
1414 J := Length (Container);
1417 EI : constant Element_Type := E (I);
1427 end Reverse_Elements;
1433 function Reverse_Find
1434 (Container : Vector;
1435 Item : Element_Type;
1436 Position : Cursor := No_Element) return Cursor
1438 Last : Index_Type'Base;
1442 if not Position.Valid
1443 or else Position.Index > Last_Index (Container)
1445 Last := Last_Index (Container);
1447 Last := Position.Index;
1450 K := Count_Type (Int (Last) - Int (No_Index));
1451 for Indx in reverse Index_Type'First .. Last loop
1452 if Get_Element (Container, K) = Item then
1453 return (True, Indx);
1462 ------------------------
1463 -- Reverse_Find_Index --
1464 ------------------------
1466 function Reverse_Find_Index
1467 (Container : Vector;
1468 Item : Element_Type;
1469 Index : Index_Type := Index_Type'Last) return Extended_Index
1471 Last : Index_Type'Base;
1475 if Index > Last_Index (Container) then
1476 Last := Last_Index (Container);
1481 K := Count_Type (Int (Last) - Int (No_Index));
1482 for Indx in reverse Index_Type'First .. Last loop
1483 if Get_Element (Container, K) = Item then
1491 end Reverse_Find_Index;
1497 procedure Set_Length
1498 (Container : in out Vector;
1499 New_Length : Count_Type)
1502 if New_Length = Formal_Vectors.Length (Container) then
1506 if New_Length > Container.Capacity then
1507 raise Constraint_Error; -- ???
1511 Last_As_Int : constant Int'Base :=
1512 Int (Index_Type'First) + Int (New_Length) - 1;
1514 Container.Last := Index_Type'Base (Last_As_Int);
1522 function Strict_Equal (Left, Right : Vector) return Boolean is
1524 -- On bounded vectors, cursors are indexes. As a consequence, two
1525 -- vectors always have the same cursor at the same position and
1526 -- Strict_Equal is simply =
1528 return Left = Right;
1535 procedure Swap (Container : in out Vector; I, J : Index_Type) is
1537 if I > Container.Last then
1538 raise Constraint_Error with "I index is out of range";
1541 if J > Container.Last then
1542 raise Constraint_Error with "J index is out of range";
1550 II : constant Int'Base := Int (I) - Int (No_Index);
1551 JJ : constant Int'Base := Int (J) - Int (No_Index);
1553 EI : Element_Type renames Container.Elements (Count_Type (II));
1554 EJ : Element_Type renames Container.Elements (Count_Type (JJ));
1556 EI_Copy : constant Element_Type := EI;
1564 procedure Swap (Container : in out Vector; I, J : Cursor) is
1567 raise Constraint_Error with "I cursor has no element";
1571 raise Constraint_Error with "J cursor has no element";
1574 Swap (Container, I.Index, J.Index);
1582 (Container : Vector;
1583 Index : Extended_Index) return Cursor
1586 if Index not in Index_Type'First .. Last_Index (Container) then
1590 return Cursor'(True, Index
);
1597 function To_Index
(Position
: Cursor
) return Extended_Index
is
1599 if not Position
.Valid
then
1603 return Position
.Index
;
1611 (New_Item
: Element_Type
;
1612 Length
: Count_Type
) return Vector
1616 return Empty_Vector
;
1620 First
: constant Int
:= Int
(Index_Type
'First);
1621 Last_As_Int
: constant Int
'Base := First
+ Int
(Length
) - 1;
1625 if Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
1626 raise Constraint_Error
with "Length is out of range"; -- ???
1629 Last
:= Index_Type
(Last_As_Int
);
1631 return (Length
, (others => New_Item
), Last
=> Last
,
1636 end Ada
.Containers
.Formal_Vectors
;