1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- A D A . C O N T A I N E R S . V E C T O R 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 Ada
.Containers
.Generic_Array_Sort
;
37 with Ada
.Unchecked_Deallocation
;
39 with System
; use type System
.Address
;
41 package body Ada
.Containers
.Vectors
is
43 type Int
is range System
.Min_Int
.. System
.Max_Int
;
46 new Ada
.Unchecked_Deallocation
(Elements_Type
, Elements_Access
);
52 function "&" (Left
, Right
: Vector
) return Vector
is
53 LN
: constant Count_Type
:= Length
(Left
);
54 RN
: constant Count_Type
:= Length
(Right
);
63 RE
: Elements_Type
renames
64 Right
.Elements
(Index_Type
'First .. Right
.Last
);
66 Elements
: constant Elements_Access
:=
67 new Elements_Type
'(RE);
70 return (Controlled with Elements, Right.Last, 0, 0);
76 LE : Elements_Type renames
77 Left.Elements (Index_Type'First .. Left.Last);
79 Elements : constant Elements_Access :=
80 new Elements_Type'(LE
);
83 return (Controlled
with Elements
, Left
.Last
, 0, 0);
89 Last_As_Int
: constant Int
'Base := -- TODO: handle overflow
90 Int
(Index_Type
'First) + Int
(LN
) + Int
(RN
) - 1;
93 if Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
94 raise Constraint_Error
;
98 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
100 LE
: Elements_Type
renames
101 Left
.Elements
(Index_Type
'First .. Left
.Last
);
103 RE
: Elements_Type
renames
104 Right
.Elements
(Index_Type
'First .. Right
.Last
);
106 Elements
: constant Elements_Access
:=
107 new Elements_Type
'(LE & RE);
110 return (Controlled with Elements, Last, 0, 0);
115 function "&" (Left : Vector; Right : Element_Type) return Vector is
116 LN : constant Count_Type := Length (Left);
121 subtype Elements_Subtype is
122 Elements_Type (Index_Type'First .. Index_Type'First);
124 Elements : constant Elements_Access :=
125 new Elements_Subtype'(others => Right
);
128 return (Controlled
with Elements
, Index_Type
'First, 0, 0);
133 Last_As_Int
: constant Int
'Base := -- TODO: handle overflow
134 Int
(Index_Type
'First) + Int
(LN
);
137 if Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
138 raise Constraint_Error
;
142 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
144 LE
: Elements_Type
renames
145 Left
.Elements
(Index_Type
'First .. Left
.Last
);
147 subtype ET
is Elements_Type
(Index_Type
'First .. Last
);
149 Elements
: constant Elements_Access
:= new ET
'(LE & Right);
152 return (Controlled with Elements, Last, 0, 0);
157 function "&" (Left : Element_Type; Right : Vector) return Vector is
158 RN : constant Count_Type := Length (Right);
163 subtype Elements_Subtype is
164 Elements_Type (Index_Type'First .. Index_Type'First);
166 Elements : constant Elements_Access :=
167 new Elements_Subtype'(others => Left
);
170 return (Controlled
with Elements
, Index_Type
'First, 0, 0);
175 Last_As_Int
: constant Int
'Base := -- TODO: handle overflow
176 Int
(Index_Type
'First) + Int
(RN
);
179 if Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
180 raise Constraint_Error
;
184 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
186 RE
: Elements_Type
renames
187 Right
.Elements
(Index_Type
'First .. Right
.Last
);
189 subtype ET
is Elements_Type
(Index_Type
'First .. Last
);
191 Elements
: constant Elements_Access
:= new ET
'(Left & RE);
194 return (Controlled with Elements, Last, 0, 0);
199 function "&" (Left, Right : Element_Type) return Vector is
201 if Index_Type'First >= Index_Type'Last then
202 raise Constraint_Error;
206 Last : constant Index_Type := Index_Type'First + 1;
208 subtype ET is Elements_Type (Index_Type'First .. Last);
210 Elements : constant Elements_Access := new ET'(Left
, Right
);
213 return (Controlled
with Elements
, Last
, 0, 0);
221 function "=" (Left
, Right
: Vector
) return Boolean is
223 if Left
'Address = Right
'Address then
227 if Left
.Last
/= Right
.Last
then
231 for J
in Index_Type
range Index_Type
'First .. Left
.Last
loop
232 if Left
.Elements
(J
) /= Right
.Elements
(J
) then
244 procedure Adjust
(Container
: in out Vector
) is
246 if Container
.Last
= No_Index
then
247 Container
.Elements
:= null;
252 E
: constant Elements_Access
:= Container
.Elements
;
253 L
: constant Index_Type
:= Container
.Last
;
256 Container
.Elements
:= null;
257 Container
.Last
:= No_Index
;
260 Container
.Elements
:= new Elements_Type
'(E (Index_Type'First .. L));
269 procedure Append (Container : in out Vector; New_Item : Vector) is
271 if Is_Empty (New_Item) then
275 if Container.Last = Index_Type'Last then
276 raise Constraint_Error;
286 (Container : in out Vector;
287 New_Item : Element_Type;
288 Count : Count_Type := 1)
295 if Container.Last = Index_Type'Last then
296 raise Constraint_Error;
310 function Capacity (Container : Vector) return Count_Type is
312 if Container.Elements = null then
316 return Container.Elements'Length;
323 procedure Clear (Container : in out Vector) is
325 if Container.Busy > 0 then
329 Container.Last := No_Index;
338 Item : Element_Type) return Boolean
341 return Find_Index (Container, Item) /= No_Index;
349 (Container : in out Vector;
350 Index : Extended_Index;
351 Count : Count_Type := 1)
354 if Index < Index_Type'First then
355 raise Constraint_Error;
358 if Index > Container.Last then
359 if Index > Container.Last + 1 then
360 raise Constraint_Error;
370 if Container.Busy > 0 then
375 I_As_Int : constant Int := Int (Index);
376 Old_Last_As_Int : constant Int := Index_Type'Pos (Container.Last);
378 Count1 : constant Int'Base := Count_Type'Pos (Count);
379 Count2 : constant Int'Base := Old_Last_As_Int - I_As_Int + 1;
380 N : constant Int'Base := Int'Min (Count1, Count2);
382 J_As_Int : constant Int'Base := I_As_Int + N;
385 if J_As_Int > Old_Last_As_Int then
386 Container.Last := Index - 1;
390 J : constant Index_Type := Index_Type (J_As_Int);
391 E : Elements_Type renames Container.Elements.all;
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);
398 E (Index .. New_Last) := E (J .. Container.Last);
399 Container.Last := New_Last;
406 (Container : in out Vector;
407 Position : in out Cursor;
408 Count : Count_Type := 1)
411 if Position.Container = null then
412 raise Constraint_Error;
415 if Position.Container /= Container'Unrestricted_Access
416 or else Position.Index > Container.Last
421 Delete (Container, Position.Index, Count);
423 -- This is the old behavior, prior to the York API (2005/06):
425 -- if Position.Index <= Container.Last then
426 -- Position := (Container'Unchecked_Access, Position.Index);
428 -- Position := No_Element;
431 -- This is the behavior specified by the York API:
433 Position := No_Element;
440 procedure Delete_First
441 (Container : in out Vector;
442 Count : Count_Type := 1)
449 if Count >= Length (Container) then
454 Delete (Container, Index_Type'First, Count);
461 procedure Delete_Last
462 (Container : in out Vector;
463 Count : Count_Type := 1)
472 if Container.Busy > 0 then
476 Index := Int'Base (Container.Last) - Int'Base (Count);
478 if Index < Index_Type'Pos (Index_Type'First) then
479 Container.Last := No_Index;
481 Container.Last := Index_Type (Index);
491 Index : Index_Type) return Element_Type
494 if Index > Container.Last then
495 raise Constraint_Error;
498 return Container.Elements (Index);
501 function Element (Position : Cursor) return Element_Type is
503 if Position.Container = null then
504 raise Constraint_Error;
507 return Element (Position.Container.all, Position.Index);
514 procedure Finalize (Container : in out Vector) is
515 X : Elements_Access := Container.Elements;
518 if Container.Busy > 0 then
522 Container.Elements := null;
523 Container.Last := No_Index;
534 Position : Cursor := No_Element) return Cursor
537 if Position.Container /= null
538 and then (Position.Container /= Container'Unrestricted_Access
539 or else Position.Index > Container.Last)
544 for J in Position.Index .. Container.Last loop
545 if Container.Elements (J) = Item then
546 return (Container'Unchecked_Access, J);
560 Index : Index_Type := Index_Type'First) return Extended_Index
563 for Indx in Index .. Container.Last loop
564 if Container.Elements (Indx) = Item then
576 function First (Container : Vector) return Cursor is
578 if Is_Empty (Container) then
582 return (Container'Unchecked_Access, Index_Type'First);
589 function First_Element (Container : Vector) return Element_Type is
591 return Element (Container, Index_Type'First);
598 function First_Index (Container : Vector) return Index_Type is
599 pragma Unreferenced (Container);
601 return Index_Type'First;
604 ---------------------
605 -- Generic_Sorting --
606 ---------------------
608 package body Generic_Sorting is
614 function Is_Sorted (Container : Vector) return Boolean is
616 if Container.Last <= Index_Type'First then
621 E : Elements_Type renames Container.Elements.all;
623 for I in Index_Type'First .. Container.Last - 1 loop
624 if E (I + 1) < E (I) then
637 procedure Merge (Target, Source : in out Vector) is
638 I : Index_Type'Base := Target.Last;
642 if Target.Last < Index_Type'First then
643 Move (Target => Target, Source => Source);
647 if Target'Address = Source'Address then
651 if Source.Last < Index_Type'First then
655 if Source.Busy > 0 then
659 Target.Set_Length (Length (Target) + Length (Source));
662 while Source.Last >= Index_Type'First loop
663 pragma Assert (Source.Last <= Index_Type'First
664 or else not (Source.Elements (Source.Last) <
665 Source.Elements (Source.Last - 1)));
667 if I < Index_Type'First then
668 Target.Elements (Index_Type'First .. J) :=
669 Source.Elements (Index_Type'First .. Source.Last);
671 Source.Last := No_Index;
675 pragma Assert (I <= Index_Type'First
676 or else not (Target.Elements (I) <
677 Target.Elements (I - 1)));
679 if Source.Elements (Source.Last) < Target.Elements (I) then
680 Target.Elements (J) := Target.Elements (I);
684 Target.Elements (J) := Source.Elements (Source.Last);
685 Source.Last := Source.Last - 1;
696 procedure Sort (Container : in out Vector)
699 new Generic_Array_Sort
700 (Index_Type => Index_Type,
701 Element_Type => Element_Type,
702 Array_Type => Elements_Type,
706 if Container.Last <= Index_Type'First then
710 if Container.Lock > 0 then
714 Sort (Container.Elements (Index_Type'First .. Container.Last));
723 function Has_Element (Position : Cursor) return Boolean is
725 if Position.Container = null then
729 return Position.Index <= Position.Container.Last;
737 (Container : in out Vector;
738 Before : Extended_Index;
739 New_Item : Element_Type;
740 Count : Count_Type := 1)
742 N : constant Int := Count_Type'Pos (Count);
744 New_Last_As_Int : Int'Base;
745 New_Last : Index_Type;
747 Dst : Elements_Access;
750 if Before < Index_Type'First then
751 raise Constraint_Error;
754 if Before > Container.Last
755 and then Before > Container.Last + 1
757 raise Constraint_Error;
765 Old_Last : constant Extended_Index := Container.Last;
767 Old_Last_As_Int : constant Int := Index_Type'Pos (Old_Last);
770 New_Last_As_Int := Old_Last_As_Int + N;
772 if New_Last_As_Int > Index_Type'Pos (Index_Type'Last) then
773 raise Constraint_Error;
776 New_Last := Index_Type (New_Last_As_Int);
779 if Container.Busy > 0 then
783 if Container.Elements = null then
785 subtype Elements_Subtype is
786 Elements_Type (Index_Type'First .. New_Last);
788 Container.Elements := new Elements_Subtype'(others => New_Item
);
791 Container
.Last
:= New_Last
;
795 if New_Last
<= Container
.Elements
'Last then
797 E
: Elements_Type
renames Container
.Elements
.all;
799 if Before
<= Container
.Last
then
801 Index_As_Int
: constant Int
'Base :=
802 Index_Type
'Pos (Before
) + N
;
804 Index
: constant Index_Type
:= Index_Type
(Index_As_Int
);
807 E
(Index
.. New_Last
) := E
(Before
.. Container
.Last
);
809 E
(Before
.. Index_Type
'Pred (Index
)) :=
810 (others => New_Item
);
814 E
(Before
.. New_Last
) := (others => New_Item
);
818 Container
.Last
:= New_Last
;
823 First
: constant Int
:= Int
(Index_Type
'First);
824 New_Size
: constant Int
'Base := New_Last_As_Int
- First
+ 1;
825 Size
: Int
'Base := Int
'Max (1, Container
.Elements
'Length);
828 while Size
< New_Size
loop
829 if Size
> Int
'Last / 2 then
837 -- TODO: The following calculations aren't quite right, since
838 -- there will be overflow if Index_Type'Range is very large
839 -- (e.g. this package is instantiated with a 64-bit integer).
843 Max_Size
: constant Int
'Base := Int
(Index_Type
'Last) - First
+ 1;
845 if Size
> Max_Size
then
851 Dst_Last
: constant Index_Type
:= Index_Type
(First
+ Size
- 1);
853 Dst
:= new Elements_Type
(Index_Type
'First .. Dst_Last
);
858 Src
: Elements_Type
renames Container
.Elements
.all;
861 Dst
(Index_Type
'First .. Index_Type
'Pred (Before
)) :=
862 Src
(Index_Type
'First .. Index_Type
'Pred (Before
));
864 if Before
<= Container
.Last
then
866 Index_As_Int
: constant Int
'Base :=
867 Index_Type
'Pos (Before
) + N
;
869 Index
: constant Index_Type
:= Index_Type
(Index_As_Int
);
872 Dst
(Before
.. Index_Type
'Pred (Index
)) := (others => New_Item
);
873 Dst
(Index
.. New_Last
) := Src
(Before
.. Container
.Last
);
877 Dst
(Before
.. New_Last
) := (others => New_Item
);
886 X
: Elements_Access
:= Container
.Elements
;
888 Container
.Elements
:= Dst
;
889 Container
.Last
:= New_Last
;
895 (Container
: in out Vector
;
896 Before
: Extended_Index
;
899 N
: constant Count_Type
:= Length
(New_Item
);
902 if Before
< Index_Type
'First then
903 raise Constraint_Error
;
906 if Before
> Container
.Last
907 and then Before
> Container
.Last
+ 1
909 raise Constraint_Error
;
916 Insert_Space
(Container
, Before
, Count
=> N
);
919 Dst_Last_As_Int
: constant Int
'Base :=
920 Int
'Base (Before
) + Int
'Base (N
) - 1;
922 Dst_Last
: constant Index_Type
:= Index_Type
(Dst_Last_As_Int
);
925 if Container
'Address /= New_Item
'Address then
926 Container
.Elements
(Before
.. Dst_Last
) :=
927 New_Item
.Elements
(Index_Type
'First .. New_Item
.Last
);
933 subtype Src_Index_Subtype
is Index_Type
'Base range
934 Index_Type
'First .. Before
- 1;
936 Src
: Elements_Type
renames
937 Container
.Elements
(Src_Index_Subtype
);
939 Index_As_Int
: constant Int
'Base :=
940 Int
(Before
) + Src
'Length - 1;
942 Index
: constant Index_Type
'Base :=
943 Index_Type
'Base (Index_As_Int
);
945 Dst
: Elements_Type
renames
946 Container
.Elements
(Before
.. Index
);
952 if Dst_Last
= Container
.Last
then
957 subtype Src_Index_Subtype
is Index_Type
'Base range
958 Dst_Last
+ 1 .. Container
.Last
;
960 Src
: Elements_Type
renames
961 Container
.Elements
(Src_Index_Subtype
);
963 Index_As_Int
: constant Int
'Base :=
964 Dst_Last_As_Int
- Src
'Length + 1;
966 Index
: constant Index_Type
:=
967 Index_Type
(Index_As_Int
);
969 Dst
: Elements_Type
renames
970 Container
.Elements
(Index
.. Dst_Last
);
979 (Container
: in out Vector
;
983 Index
: Index_Type
'Base;
986 if Before
.Container
/= null
987 and then Before
.Container
/= Vector_Access
'(Container'Unchecked_Access)
992 if Is_Empty (New_Item) then
996 if Before.Container = null
997 or else Before.Index > Container.Last
999 if Container.Last = Index_Type'Last then
1000 raise Constraint_Error;
1003 Index := Container.Last + 1;
1006 Index := Before.Index;
1009 Insert (Container, Index, New_Item);
1013 (Container : in out Vector;
1016 Position : out Cursor)
1018 Index : Index_Type'Base;
1021 if Before.Container /= null
1022 and then Before.Container /= Vector_Access'(Container
'Unchecked_Access)
1024 raise Program_Error
;
1027 if Is_Empty
(New_Item
) then
1028 if Before
.Container
= null
1029 or else Before
.Index
> Container
.Last
1031 Position
:= No_Element
;
1033 Position
:= (Container
'Unchecked_Access, Before
.Index
);
1039 if Before
.Container
= null
1040 or else Before
.Index
> Container
.Last
1042 if Container
.Last
= Index_Type
'Last then
1043 raise Constraint_Error
;
1046 Index
:= Container
.Last
+ 1;
1049 Index
:= Before
.Index
;
1052 Insert
(Container
, Index
, New_Item
);
1054 Position
:= Cursor
'(Container'Unchecked_Access, Index);
1058 (Container : in out Vector;
1060 New_Item : Element_Type;
1061 Count : Count_Type := 1)
1063 Index : Index_Type'Base;
1066 if Before.Container /= null
1067 and then Before.Container /= Vector_Access'(Container
'Unchecked_Access)
1069 raise Program_Error
;
1076 if Before
.Container
= null
1077 or else Before
.Index
> Container
.Last
1079 if Container
.Last
= Index_Type
'Last then
1080 raise Constraint_Error
;
1083 Index
:= Container
.Last
+ 1;
1086 Index
:= Before
.Index
;
1089 Insert
(Container
, Index
, New_Item
, Count
);
1093 (Container
: in out Vector
;
1095 New_Item
: Element_Type
;
1096 Position
: out Cursor
;
1097 Count
: Count_Type
:= 1)
1099 Index
: Index_Type
'Base;
1102 if Before
.Container
/= null
1103 and then Before
.Container
/= Vector_Access
'(Container'Unchecked_Access)
1105 raise Program_Error;
1109 if Before.Container = null
1110 or else Before.Index > Container.Last
1112 Position := No_Element;
1114 Position := (Container'Unchecked_Access, Before.Index);
1120 if Before.Container = null
1121 or else Before.Index > Container.Last
1123 if Container.Last = Index_Type'Last then
1124 raise Constraint_Error;
1127 Index := Container.Last + 1;
1130 Index := Before.Index;
1133 Insert (Container, Index, New_Item, Count);
1135 Position := Cursor'(Container
'Unchecked_Access, Index
);
1139 (Container
: in out Vector
;
1140 Before
: Extended_Index
;
1141 Count
: Count_Type
:= 1)
1143 New_Item
: Element_Type
; -- Default-initialized value
1144 pragma Warnings
(Off
, New_Item
);
1147 Insert
(Container
, Before
, New_Item
, Count
);
1151 (Container
: in out Vector
;
1153 Position
: out Cursor
;
1154 Count
: Count_Type
:= 1)
1156 New_Item
: Element_Type
; -- Default-initialized value
1157 pragma Warnings
(Off
, New_Item
);
1160 Insert
(Container
, Before
, New_Item
, Position
, Count
);
1167 procedure Insert_Space
1168 (Container
: in out Vector
;
1169 Before
: Extended_Index
;
1170 Count
: Count_Type
:= 1)
1172 N
: constant Int
:= Count_Type
'Pos (Count
);
1174 New_Last_As_Int
: Int
'Base;
1175 New_Last
: Index_Type
;
1177 Dst
: Elements_Access
;
1180 if Before
< Index_Type
'First then
1181 raise Constraint_Error
;
1184 if Before
> Container
.Last
1185 and then Before
> Container
.Last
+ 1
1187 raise Constraint_Error
;
1195 Old_Last
: constant Extended_Index
:= Container
.Last
;
1197 Old_Last_As_Int
: constant Int
:= Index_Type
'Pos (Old_Last
);
1200 New_Last_As_Int
:= Old_Last_As_Int
+ N
;
1202 if New_Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
1203 raise Constraint_Error
;
1206 New_Last
:= Index_Type
(New_Last_As_Int
);
1209 if Container
.Busy
> 0 then
1210 raise Program_Error
;
1213 if Container
.Elements
= null then
1214 Container
.Elements
:=
1215 new Elements_Type
(Index_Type
'First .. New_Last
);
1217 Container
.Last
:= New_Last
;
1221 if New_Last
<= Container
.Elements
'Last then
1223 E
: Elements_Type
renames Container
.Elements
.all;
1225 if Before
<= Container
.Last
then
1227 Index_As_Int
: constant Int
'Base :=
1228 Index_Type
'Pos (Before
) + N
;
1230 Index
: constant Index_Type
:= Index_Type
(Index_As_Int
);
1233 E
(Index
.. New_Last
) := E
(Before
.. Container
.Last
);
1238 Container
.Last
:= New_Last
;
1243 First
: constant Int
:= Int
(Index_Type
'First);
1244 New_Size
: constant Int
'Base := New_Last_As_Int
- First
+ 1;
1245 Size
: Int
'Base := Int
'Max (1, Container
.Elements
'Length);
1248 while Size
< New_Size
loop
1249 if Size
> Int
'Last / 2 then
1257 -- TODO: The following calculations aren't quite right, since
1258 -- there will be overflow if Index_Type'Range is very large
1259 -- (e.g. this package is instantiated with a 64-bit integer).
1263 Max_Size
: constant Int
'Base := Int
(Index_Type
'Last) - First
+ 1;
1265 if Size
> Max_Size
then
1271 Dst_Last
: constant Index_Type
:= Index_Type
(First
+ Size
- 1);
1273 Dst
:= new Elements_Type
(Index_Type
'First .. Dst_Last
);
1278 Src
: Elements_Type
renames Container
.Elements
.all;
1281 Dst
(Index_Type
'First .. Index_Type
'Pred (Before
)) :=
1282 Src
(Index_Type
'First .. Index_Type
'Pred (Before
));
1284 if Before
<= Container
.Last
then
1286 Index_As_Int
: constant Int
'Base :=
1287 Index_Type
'Pos (Before
) + N
;
1289 Index
: constant Index_Type
:= Index_Type
(Index_As_Int
);
1292 Dst
(Index
.. New_Last
) := Src
(Before
.. Container
.Last
);
1302 X
: Elements_Access
:= Container
.Elements
;
1304 Container
.Elements
:= Dst
;
1305 Container
.Last
:= New_Last
;
1310 procedure Insert_Space
1311 (Container
: in out Vector
;
1313 Position
: out Cursor
;
1314 Count
: Count_Type
:= 1)
1316 Index
: Index_Type
'Base;
1319 if Before
.Container
/= null
1320 and then Before
.Container
/= Vector_Access
'(Container'Unchecked_Access)
1322 raise Program_Error;
1326 if Before.Container = null
1327 or else Before.Index > Container.Last
1329 Position := No_Element;
1331 Position := (Container'Unchecked_Access, Before.Index);
1337 if Before.Container = null
1338 or else Before.Index > Container.Last
1340 if Container.Last = Index_Type'Last then
1341 raise Constraint_Error;
1344 Index := Container.Last + 1;
1347 Index := Before.Index;
1350 Insert_Space (Container, Index, Count => Count);
1352 Position := Cursor'(Container
'Unchecked_Access, Index
);
1359 function Is_Empty
(Container
: Vector
) return Boolean is
1361 return Container
.Last
< Index_Type
'First;
1369 (Container
: Vector
;
1370 Process
: not null access procedure (Position
: Cursor
))
1372 V
: Vector
renames Container
'Unrestricted_Access.all;
1373 B
: Natural renames V
.Busy
;
1379 for Indx
in Index_Type
'First .. Container
.Last
loop
1380 Process
(Cursor
'(Container'Unchecked_Access, Indx));
1395 function Last (Container : Vector) return Cursor is
1397 if Is_Empty (Container) then
1401 return (Container'Unchecked_Access, Container.Last);
1408 function Last_Element (Container : Vector) return Element_Type is
1410 return Element (Container, Container.Last);
1417 function Last_Index (Container : Vector) return Extended_Index is
1419 return Container.Last;
1426 function Length (Container : Vector) return Count_Type is
1427 L : constant Int := Int (Container.Last);
1428 F : constant Int := Int (Index_Type'First);
1429 N : constant Int'Base := L - F + 1;
1432 if N > Count_Type'Pos (Count_Type'Last) then
1433 raise Constraint_Error;
1436 return Count_Type (N);
1444 (Target : in out Vector;
1445 Source : in out Vector)
1448 if Target'Address = Source'Address then
1452 if Target.Busy > 0 then
1453 raise Program_Error;
1456 if Source.Busy > 0 then
1457 raise Program_Error;
1461 Target_Elements : constant Elements_Access := Target.Elements;
1463 Target.Elements := Source.Elements;
1464 Source.Elements := Target_Elements;
1467 Target.Last := Source.Last;
1468 Source.Last := No_Index;
1475 function Next (Position : Cursor) return Cursor is
1477 if Position.Container = null then
1481 if Position.Index < Position.Container.Last then
1482 return (Position.Container, Position.Index + 1);
1492 procedure Next (Position : in out Cursor) is
1494 if Position.Container = null then
1498 if Position.Index < Position.Container.Last then
1499 Position.Index := Position.Index + 1;
1501 Position := No_Element;
1509 procedure Prepend (Container : in out Vector; New_Item : Vector) is
1511 Insert (Container, Index_Type'First, New_Item);
1515 (Container : in out Vector;
1516 New_Item : Element_Type;
1517 Count : Count_Type := 1)
1530 procedure Previous (Position : in out Cursor) is
1532 if Position.Container = null then
1536 if Position.Index > Index_Type'First then
1537 Position.Index := Position.Index - 1;
1539 Position := No_Element;
1543 function Previous (Position : Cursor) return Cursor is
1545 if Position.Container = null then
1549 if Position.Index > Index_Type'First then
1550 return (Position.Container, Position.Index - 1);
1560 procedure Query_Element
1561 (Container : Vector;
1563 Process : not null access procedure (Element : Element_Type))
1565 V : Vector renames Container'Unrestricted_Access.all;
1566 B : Natural renames V.Busy;
1567 L : Natural renames V.Lock;
1570 if Index > Container.Last then
1571 raise Constraint_Error;
1578 Process (V.Elements (Index));
1590 procedure Query_Element
1592 Process : not null access procedure (Element : Element_Type))
1595 if Position.Container = null then
1596 raise Constraint_Error;
1599 Query_Element (Position.Container.all, Position.Index, Process);
1607 (Stream : access Root_Stream_Type'Class;
1608 Container : out Vector)
1610 Length : Count_Type'Base;
1611 Last : Index_Type'Base := No_Index;
1616 Count_Type'Base'Read
(Stream
, Length
);
1618 if Length
> Capacity
(Container
) then
1619 Reserve_Capacity
(Container
, Capacity
=> Length
);
1622 for J
in Count_Type
range 1 .. Length
loop
1624 Element_Type
'Read (Stream
, Container
.Elements
(Last
));
1625 Container
.Last
:= Last
;
1630 (Stream
: access Root_Stream_Type
'Class;
1631 Position
: out Cursor
)
1634 raise Program_Error
;
1637 ---------------------
1638 -- Replace_Element --
1639 ---------------------
1641 procedure Replace_Element
1642 (Container
: in out Vector
;
1644 New_Item
: Element_Type
)
1647 if Index
> Container
.Last
then
1648 raise Constraint_Error
;
1651 if Container
.Lock
> 0 then
1652 raise Program_Error
;
1655 Container
.Elements
(Index
) := New_Item
;
1656 end Replace_Element
;
1658 procedure Replace_Element
1659 (Container
: in out Vector
;
1661 New_Item
: Element_Type
)
1664 if Position
.Container
= null then
1665 raise Constraint_Error
;
1668 if Position
.Container
/= Container
'Unrestricted_Access then
1669 raise Program_Error
;
1672 Replace_Element
(Container
, Position
.Index
, New_Item
);
1673 end Replace_Element
;
1675 ----------------------
1676 -- Reserve_Capacity --
1677 ----------------------
1679 procedure Reserve_Capacity
1680 (Container
: in out Vector
;
1681 Capacity
: Count_Type
)
1683 N
: constant Count_Type
:= Length
(Container
);
1686 if Capacity
= 0 then
1689 X
: Elements_Access
:= Container
.Elements
;
1691 Container
.Elements
:= null;
1695 elsif N
< Container
.Elements
'Length then
1696 if Container
.Busy
> 0 then
1697 raise Program_Error
;
1701 subtype Array_Index_Subtype
is Index_Type
'Base range
1702 Index_Type
'First .. Container
.Last
;
1704 Src
: Elements_Type
renames
1705 Container
.Elements
(Array_Index_Subtype
);
1707 subtype Array_Subtype
is
1708 Elements_Type
(Array_Index_Subtype
);
1710 X
: Elements_Access
:= Container
.Elements
;
1713 Container
.Elements
:= new Array_Subtype
'(Src);
1721 if Container.Elements = null then
1723 Last_As_Int : constant Int'Base :=
1724 Int (Index_Type'First) + Int (Capacity) - 1;
1727 if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
1728 raise Constraint_Error;
1732 Last : constant Index_Type := Index_Type (Last_As_Int);
1734 subtype Array_Subtype is
1735 Elements_Type (Index_Type'First .. Last);
1737 Container.Elements := new Array_Subtype;
1744 if Capacity <= N then
1745 if N < Container.Elements'Length then
1746 if Container.Busy > 0 then
1747 raise Program_Error;
1751 subtype Array_Index_Subtype is Index_Type'Base range
1752 Index_Type'First .. Container.Last;
1754 Src : Elements_Type renames
1755 Container.Elements (Array_Index_Subtype);
1757 subtype Array_Subtype is
1758 Elements_Type (Array_Index_Subtype);
1760 X : Elements_Access := Container.Elements;
1763 Container.Elements := new Array_Subtype'(Src
);
1772 if Capacity
= Container
.Elements
'Length then
1776 if Container
.Busy
> 0 then
1777 raise Program_Error
;
1781 Last_As_Int
: constant Int
'Base :=
1782 Int
(Index_Type
'First) + Int
(Capacity
) - 1;
1785 if Last_As_Int
> Index_Type
'Pos (Index_Type
'Last) then
1786 raise Constraint_Error
;
1790 Last
: constant Index_Type
:= Index_Type
(Last_As_Int
);
1792 subtype Array_Subtype
is
1793 Elements_Type
(Index_Type
'First .. Last
);
1795 E
: Elements_Access
:= new Array_Subtype
;
1799 Src
: Elements_Type
renames
1800 Container
.Elements
(Index_Type
'First .. Container
.Last
);
1802 Tgt
: Elements_Type
renames
1803 E
(Index_Type
'First .. Container
.Last
);
1815 X
: Elements_Access
:= Container
.Elements
;
1817 Container
.Elements
:= E
;
1822 end Reserve_Capacity
;
1824 ----------------------
1825 -- Reverse_Elements --
1826 ----------------------
1828 procedure Reverse_Elements
(Container
: in out Vector
) is
1830 if Container
.Length
<= 1 then
1834 if Container
.Lock
> 0 then
1835 raise Program_Error
;
1839 I
: Index_Type
:= Index_Type
'First;
1840 J
: Index_Type
:= Container
.Last
;
1841 E
: Elements_Type
renames Container
.Elements
.all;
1846 EI
: constant Element_Type
:= E
(I
);
1857 end Reverse_Elements
;
1863 function Reverse_Find
1864 (Container
: Vector
;
1865 Item
: Element_Type
;
1866 Position
: Cursor
:= No_Element
) return Cursor
1868 Last
: Index_Type
'Base;
1871 if Position
.Container
/= null
1872 and then Position
.Container
/=
1873 Vector_Access
'(Container'Unchecked_Access)
1875 raise Program_Error;
1878 if Position.Container = null
1879 or else Position.Index > Container.Last
1881 Last := Container.Last;
1883 Last := Position.Index;
1886 for Indx in reverse Index_Type'First .. Last loop
1887 if Container.Elements (Indx) = Item then
1888 return (Container'Unchecked_Access, Indx);
1895 ------------------------
1896 -- Reverse_Find_Index --
1897 ------------------------
1899 function Reverse_Find_Index
1900 (Container : Vector;
1901 Item : Element_Type;
1902 Index : Index_Type := Index_Type'Last) return Extended_Index
1904 Last : Index_Type'Base;
1907 if Index > Container.Last then
1908 Last := Container.Last;
1913 for Indx in reverse Index_Type'First .. Last loop
1914 if Container.Elements (Indx) = Item then
1920 end Reverse_Find_Index;
1922 ---------------------
1923 -- Reverse_Iterate --
1924 ---------------------
1926 procedure Reverse_Iterate
1927 (Container : Vector;
1928 Process : not null access procedure (Position : Cursor))
1930 V : Vector renames Container'Unrestricted_Access.all;
1931 B : Natural renames V.Busy;
1937 for Indx in reverse Index_Type'First .. Container.Last loop
1938 Process (Cursor'(Container
'Unchecked_Access, Indx
));
1947 end Reverse_Iterate
;
1953 procedure Set_Length
(Container
: in out Vector
; Length
: Count_Type
) is
1955 if Length
= Vectors
.Length
(Container
) then
1959 if Container
.Busy
> 0 then
1960 raise Program_Error
;
1963 if Length
> Capacity
(Container
) then
1964 Reserve_Capacity
(Container
, Capacity
=> Length
);
1968 Last_As_Int
: constant Int
'Base :=
1969 Int
(Index_Type
'First) + Int
(Length
) - 1;
1971 Container
.Last
:= Index_Type
'Base (Last_As_Int
);
1979 procedure Swap
(Container
: in out Vector
; I
, J
: Index_Type
) is
1981 if I
> Container
.Last
1982 or else J
> Container
.Last
1984 raise Constraint_Error
;
1991 if Container
.Lock
> 0 then
1992 raise Program_Error
;
1996 EI
: Element_Type
renames Container
.Elements
(I
);
1997 EJ
: Element_Type
renames Container
.Elements
(J
);
1999 EI_Copy
: constant Element_Type
:= EI
;
2007 procedure Swap
(Container
: in out Vector
; I
, J
: Cursor
) is
2009 if I
.Container
= null
2010 or else J
.Container
= null
2012 raise Constraint_Error
;
2015 if I
.Container
/= Container
'Unrestricted_Access
2016 or else J
.Container
/= Container
'Unrestricted_Access
2018 raise Program_Error
;
2021 Swap
(Container
, I
.Index
, J
.Index
);
2029 (Container
: Vector
;
2030 Index
: Extended_Index
) return Cursor
2033 if Index
not in Index_Type
'First .. Container
.Last
then
2037 return Cursor
'(Container'Unchecked_Access, Index);
2044 function To_Index (Position : Cursor) return Extended_Index is
2046 if Position.Container = null then
2050 if Position.Index <= Position.Container.Last then
2051 return Position.Index;
2061 function To_Vector (Length : Count_Type) return Vector is
2064 return Empty_Vector;
2068 First : constant Int := Int (Index_Type'First);
2069 Last_As_Int : constant Int'Base := First + Int (Length) - 1;
2071 Elements : Elements_Access;
2074 if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
2075 raise Constraint_Error;
2078 Last := Index_Type (Last_As_Int);
2079 Elements := new Elements_Type (Index_Type'First .. Last);
2081 return (Controlled with Elements, Last, 0, 0);
2086 (New_Item : Element_Type;
2087 Length : Count_Type) return Vector
2091 return Empty_Vector;
2095 First : constant Int := Int (Index_Type'First);
2096 Last_As_Int : constant Int'Base := First + Int (Length) - 1;
2098 Elements : Elements_Access;
2101 if Last_As_Int > Index_Type'Pos (Index_Type'Last) then
2102 raise Constraint_Error;
2105 Last := Index_Type (Last_As_Int);
2106 Elements := new Elements_Type'(Index_Type
'First .. Last
=> New_Item
);
2108 return (Controlled
with Elements
, Last
, 0, 0);
2112 --------------------
2113 -- Update_Element --
2114 --------------------
2116 procedure Update_Element
2117 (Container
: in out Vector
;
2119 Process
: not null access procedure (Element
: in out Element_Type
))
2121 B
: Natural renames Container
.Busy
;
2122 L
: Natural renames Container
.Lock
;
2125 if Index
> Container
.Last
then
2126 raise Constraint_Error
;
2133 Process
(Container
.Elements
(Index
));
2145 procedure Update_Element
2146 (Container
: in out Vector
;
2148 Process
: not null access procedure (Element
: in out Element_Type
))
2151 if Position
.Container
= null then
2152 raise Constraint_Error
;
2155 if Position
.Container
/= Container
'Unrestricted_Access then
2156 raise Program_Error
;
2159 Update_Element
(Container
, Position
.Index
, Process
);
2167 (Stream
: access Root_Stream_Type
'Class;
2171 Count_Type
'Base'Write (Stream, Length (Container));
2173 for J in Index_Type'First .. Container.Last loop
2174 Element_Type'Write (Stream, Container.Elements (J));
2179 (Stream : access Root_Stream_Type'Class;
2183 raise Program_Error;
2186 end Ada.Containers.Vectors;