Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / ada / libgnat / g-arrspl.ads
blob323a62a235cbcd9a6c91ec6a4b425667a625fa1e
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T . A R R A Y _ S P L I T --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2002-2023, Free Software Foundation, Inc. --
10 -- --
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. --
17 -- --
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. --
21 -- --
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 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
32 -- Useful array-manipulation routines: given a set of separators, split
33 -- an array wherever the separators appear, and provide direct access
34 -- to the resulting slices.
36 with Ada.Finalization;
38 generic
39 type Element is (<>);
40 -- Element of the array, this must be a discrete type
42 type Element_Sequence is array (Positive range <>) of Element;
43 -- The array which is a sequence of element
45 type Element_Set is private;
46 -- This type represent a set of elements. This set does not define a
47 -- specific order of the elements. The conversion of a sequence to a
48 -- set and membership tests in the set is performed using the routines
49 -- To_Set and Is_In defined below.
51 with function To_Set (Sequence : Element_Sequence) return Element_Set;
52 -- Returns an Element_Set given an Element_Sequence. Duplicate elements
53 -- can be ignored during this conversion.
55 with function Is_In (Item : Element; Set : Element_Set) return Boolean;
56 -- Returns True if Item is found in Set, False otherwise
58 package GNAT.Array_Split is
59 pragma Preelaborate;
61 Index_Error : exception;
62 -- Raised by all operations below if Index > Field_Count (S)
64 type Separator_Mode is
65 (Single,
66 -- In this mode the array is cut at each element in the separator
67 -- set. If two separators are contiguous the result at that position
68 -- is an empty slice.
70 Multiple
71 -- In this mode contiguous separators are handled as a single
72 -- separator and no empty slice is created.
75 type Slice_Set is private
76 with Iterable => (First => First_Cursor,
77 Next => Advance,
78 Has_Element => Has_Element,
79 Element => Slice);
81 -- This type uses by-reference semantics. This is a set of slices as
82 -- returned by Create or Set routines below. The abstraction represents
83 -- a set of items. Each item is a part of the original array named a
84 -- Slice. It is possible to access individual slices by using the Slice
85 -- routine below. The first slice in the Set is at the position/index
86 -- 1. The total number of slices in the set is returned by Slice_Count.
88 procedure Create
89 (S : out Slice_Set;
90 From : Element_Sequence;
91 Separators : Element_Sequence;
92 Mode : Separator_Mode := Single);
93 function Create
94 (From : Element_Sequence;
95 Separators : Element_Sequence;
96 Mode : Separator_Mode := Single) return Slice_Set;
97 -- Create a cut array object. From is the source array, and Separators
98 -- is a sequence of Element along which to split the array. The source
99 -- array is sliced at separator boundaries. The separators are not
100 -- included as part of the resulting slices.
102 -- Note that if From is terminated by a separator an extra empty element
103 -- is added to the slice set. If From only contains a separator the slice
104 -- set contains two empty elements.
106 procedure Create
107 (S : out Slice_Set;
108 From : Element_Sequence;
109 Separators : Element_Set;
110 Mode : Separator_Mode := Single);
111 function Create
112 (From : Element_Sequence;
113 Separators : Element_Set;
114 Mode : Separator_Mode := Single) return Slice_Set;
115 -- Same as above but using a Element_Set
117 procedure Set
118 (S : in out Slice_Set;
119 Separators : Element_Sequence;
120 Mode : Separator_Mode := Single);
121 -- Change the set of separators. The source array will be split according
122 -- to this new set of separators.
124 procedure Set
125 (S : in out Slice_Set;
126 Separators : Element_Set;
127 Mode : Separator_Mode := Single);
128 -- Same as above but using a Element_Set
130 type Slice_Number is new Natural;
131 -- Type used to count number of slices
133 function Slice_Count (S : Slice_Set) return Slice_Number with Inline;
134 -- Returns the number of slices (fields) in S
136 function First_Cursor (Unused : Slice_Set) return Slice_Number is (1);
137 function Advance
138 (Unused : Slice_Set; Position : Slice_Number) return Slice_Number
139 is (Position + 1);
140 function Has_Element
141 (Cont : Slice_Set; Position : Slice_Number) return Boolean
142 is (Position <= Slice_Count (Cont));
143 -- Functions used to iterate over a Slice_Set
145 function Slice
146 (S : Slice_Set;
147 Index : Slice_Number) return Element_Sequence with Inline;
148 -- Returns the slice at position Index. First slice is 1. If Index is 0
149 -- the whole array is returned including the separators (this is the
150 -- original source array).
152 type Position is (Before, After);
153 -- Used to designate position of separator
155 type Slice_Separators is array (Position) of Element;
156 -- Separators found before and after the slice
158 Array_End : constant Element;
159 -- This is the separator returned for the start or the end of the array
161 function Separators
162 (S : Slice_Set;
163 Index : Slice_Number) return Slice_Separators;
164 -- Returns the separators used to slice (front and back) the slice at
165 -- position Index. For slices at start and end of the original array, the
166 -- Array_End value is returned for the corresponding outer bound. In
167 -- Multiple mode only the element closest to the slice is returned.
168 -- if Index = 0, returns (Array_End, Array_End).
170 type Separators_Indexes is array (Positive range <>) of Positive;
172 function Separators (S : Slice_Set) return Separators_Indexes;
173 -- Returns indexes of all separators used to slice original source array S
175 private
177 Array_End : constant Element := Element'First;
179 type Element_Access is access Element_Sequence;
181 type Indexes_Access is access Separators_Indexes;
183 type Slice_Info is record
184 Start : Positive;
185 Stop : Natural;
186 end record;
187 -- Starting/Ending position of a slice. This does not include separators
189 type Slices_Indexes is array (Slice_Number range <>) of Slice_Info;
190 type Slices_Access is access Slices_Indexes;
191 -- All indexes for fast access to slices. In the Slice_Set we keep only
192 -- the original array and the indexes where each slice start and stop.
194 type Data is record
195 Ref_Counter : Natural; -- Reference counter, by-address sem
196 Source : Element_Access;
197 N_Slice : Slice_Number := 0; -- Number of slices found
198 Indexes : Indexes_Access;
199 Slices : Slices_Access;
200 end record;
201 type Data_Access is access all Data;
203 type Slice_Set is new Ada.Finalization.Controlled with record
204 D : Data_Access;
205 end record;
207 overriding procedure Initialize (S : in out Slice_Set);
208 overriding procedure Adjust (S : in out Slice_Set);
209 overriding procedure Finalize (S : in out Slice_Set);
211 end GNAT.Array_Split;