Merge branch 'master' r216746-r217593 into gimple-classes-v2-option-3
[official-gcc.git] / gcc / ada / a-cfdlli.ads
blob0c028ef844bbcde54cb33a314820e31b4f65acf2
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- ADA.CONTAINERS.FORMAL_DOUBLY_LINKED_LISTS --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2004-2014, Free Software Foundation, Inc. --
10 -- --
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. --
14 -- --
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. --
21 -- --
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. --
25 -- --
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 -- This spec is derived from Ada.Containers.Bounded_Doubly_Linked_Lists in the
33 -- Ada 2012 RM. The modifications are meant to facilitate formal proofs by
34 -- making it easier to express properties, and by making the specification of
35 -- this unit compatible with SPARK 2014. Note that the API of this unit may be
36 -- subject to incompatible changes as SPARK 2014 evolves.
38 -- The modifications are:
40 -- A parameter for the container is added to every function reading the
41 -- contents of a container: Next, Previous, Query_Element, Has_Element,
42 -- Iterate, Reverse_Iterate, Element. This change is motivated by the need
43 -- to have cursors which are valid on different containers (typically a
44 -- container C and its previous version C'Old) for expressing properties,
45 -- which is not possible if cursors encapsulate an access to the underlying
46 -- container.
48 -- There are three new functions:
50 -- function Strict_Equal (Left, Right : List) return Boolean;
51 -- function First_To_Previous (Container : List; Current : Cursor)
52 -- return List;
53 -- function Current_To_Last (Container : List; Current : Cursor)
54 -- return List;
56 -- See subprogram specifications that follow for details
58 generic
59 type Element_Type is private;
61 with function "=" (Left, Right : Element_Type)
62 return Boolean is <>;
64 package Ada.Containers.Formal_Doubly_Linked_Lists is
65 pragma Annotate (GNATprove, External_Axiomatization);
66 pragma Pure;
68 type List (Capacity : Count_Type) is private with
69 Iterable => (First => First,
70 Next => Next,
71 Has_Element => Has_Element,
72 Element => Element),
73 Default_Initial_Condition;
74 pragma Preelaborable_Initialization (List);
76 type Cursor is private;
77 pragma Preelaborable_Initialization (Cursor);
79 Empty_List : constant List;
81 No_Element : constant Cursor;
83 function "=" (Left, Right : List) return Boolean with
84 Global => null;
86 function Length (Container : List) return Count_Type with
87 Global => null;
89 function Is_Empty (Container : List) return Boolean with
90 Global => null;
92 procedure Clear (Container : in out List) with
93 Global => null;
95 procedure Assign (Target : in out List; Source : List) with
96 Global => null,
97 Pre => Target.Capacity >= Length (Source);
99 function Copy (Source : List; Capacity : Count_Type := 0) return List with
100 Global => null,
101 Pre => Capacity = 0 or else Capacity >= Source.Capacity;
103 function Element
104 (Container : List;
105 Position : Cursor) return Element_Type
106 with
107 Global => null,
108 Pre => Has_Element (Container, Position);
110 procedure Replace_Element
111 (Container : in out List;
112 Position : Cursor;
113 New_Item : Element_Type)
114 with
115 Global => null,
116 Pre => Has_Element (Container, Position);
118 procedure Move (Target : in out List; Source : in out List) with
119 Global => null,
120 Pre => Target.Capacity >= Length (Source);
122 procedure Insert
123 (Container : in out List;
124 Before : Cursor;
125 New_Item : Element_Type;
126 Count : Count_Type := 1)
127 with
128 Global => null,
129 Pre => Length (Container) + Count <= Container.Capacity
130 and then (Has_Element (Container, Before)
131 or else Before = No_Element);
133 procedure Insert
134 (Container : in out List;
135 Before : Cursor;
136 New_Item : Element_Type;
137 Position : out Cursor;
138 Count : Count_Type := 1)
139 with
140 Global => null,
141 Pre => Length (Container) + Count <= Container.Capacity
142 and then (Has_Element (Container, Before)
143 or else Before = No_Element);
145 procedure Insert
146 (Container : in out List;
147 Before : Cursor;
148 Position : out Cursor;
149 Count : Count_Type := 1)
150 with
151 Global => null,
152 Pre => Length (Container) + Count <= Container.Capacity
153 and then (Has_Element (Container, Before)
154 or else Before = No_Element);
156 procedure Prepend
157 (Container : in out List;
158 New_Item : Element_Type;
159 Count : Count_Type := 1)
160 with
161 Global => null,
162 Pre => Length (Container) + Count <= Container.Capacity;
164 procedure Append
165 (Container : in out List;
166 New_Item : Element_Type;
167 Count : Count_Type := 1)
168 with
169 Global => null,
170 Pre => Length (Container) + Count <= Container.Capacity;
172 procedure Delete
173 (Container : in out List;
174 Position : in out Cursor;
175 Count : Count_Type := 1)
176 with
177 Global => null,
178 Pre => Has_Element (Container, Position);
180 procedure Delete_First
181 (Container : in out List;
182 Count : Count_Type := 1)
183 with
184 Global => null;
186 procedure Delete_Last
187 (Container : in out List;
188 Count : Count_Type := 1)
189 with
190 Global => null;
192 procedure Reverse_Elements (Container : in out List) with
193 Global => null;
195 procedure Swap
196 (Container : in out List;
197 I, J : Cursor)
198 with
199 Global => null,
200 Pre => Has_Element (Container, I) and then Has_Element (Container, J);
202 procedure Swap_Links
203 (Container : in out List;
204 I, J : Cursor)
205 with
206 Global => null,
207 Pre => Has_Element (Container, I) and then Has_Element (Container, J);
209 procedure Splice
210 (Target : in out List;
211 Before : Cursor;
212 Source : in out List)
213 with
214 Global => null,
215 Pre => Length (Source) + Length (Target) <= Target.Capacity
216 and then (Has_Element (Target, Before)
217 or else Before = No_Element);
219 procedure Splice
220 (Target : in out List;
221 Before : Cursor;
222 Source : in out List;
223 Position : in out Cursor)
224 with
225 Global => null,
226 Pre => Length (Source) + Length (Target) <= Target.Capacity
227 and then (Has_Element (Target, Before)
228 or else Before = No_Element)
229 and then Has_Element (Source, Position);
231 procedure Splice
232 (Container : in out List;
233 Before : Cursor;
234 Position : Cursor)
235 with
236 Global => null,
237 Pre => 2 * Length (Container) <= Container.Capacity
238 and then (Has_Element (Container, Before)
239 or else Before = No_Element)
240 and then Has_Element (Container, Position);
242 function First (Container : List) return Cursor with
243 Global => null;
245 function First_Element (Container : List) return Element_Type with
246 Global => null,
247 Pre => not Is_Empty (Container);
249 function Last (Container : List) return Cursor with
250 Global => null;
252 function Last_Element (Container : List) return Element_Type with
253 Global => null,
254 Pre => not Is_Empty (Container);
256 function Next (Container : List; Position : Cursor) return Cursor with
257 Global => null,
258 Pre => Has_Element (Container, Position) or else Position = No_Element;
260 procedure Next (Container : List; Position : in out Cursor) with
261 Global => null,
262 Pre => Has_Element (Container, Position) or else Position = No_Element;
264 function Previous (Container : List; Position : Cursor) return Cursor with
265 Global => null,
266 Pre => Has_Element (Container, Position) or else Position = No_Element;
268 procedure Previous (Container : List; Position : in out Cursor) with
269 Global => null,
270 Pre => Has_Element (Container, Position) or else Position = No_Element;
272 function Find
273 (Container : List;
274 Item : Element_Type;
275 Position : Cursor := No_Element) return Cursor
276 with
277 Global => null,
278 Pre => Has_Element (Container, Position) or else Position = No_Element;
280 function Reverse_Find
281 (Container : List;
282 Item : Element_Type;
283 Position : Cursor := No_Element) return Cursor
284 with
285 Global => null,
286 Pre => Has_Element (Container, Position) or else Position = No_Element;
288 function Contains
289 (Container : List;
290 Item : Element_Type) return Boolean
291 with
292 Global => null;
294 function Has_Element (Container : List; Position : Cursor) return Boolean
295 with
296 Global => null;
298 generic
299 with function "<" (Left, Right : Element_Type) return Boolean is <>;
300 package Generic_Sorting is
302 function Is_Sorted (Container : List) return Boolean with
303 Global => null;
305 procedure Sort (Container : in out List) with
306 Global => null;
308 procedure Merge (Target, Source : in out List) with
309 Global => null;
311 end Generic_Sorting;
313 function Strict_Equal (Left, Right : List) return Boolean with
314 Ghost,
315 Global => null;
316 -- Strict_Equal returns True if the containers are physically equal, i.e.
317 -- they are structurally equal (function "=" returns True) and that they
318 -- have the same set of cursors.
320 function First_To_Previous (Container : List; Current : Cursor) return List
321 with
322 Ghost,
323 Global => null,
324 Pre => Has_Element (Container, Current) or else Current = No_Element;
326 function Current_To_Last (Container : List; Current : Cursor) return List
327 with
328 Ghost,
329 Global => null,
330 Pre => Has_Element (Container, Current) or else Current = No_Element;
331 -- First_To_Previous returns a container containing all elements preceding
332 -- Current (excluded) in Container. Current_To_Last returns a container
333 -- containing all elements following Current (included) in Container.
334 -- These two new functions can be used to express invariant properties in
335 -- loops which iterate over containers. First_To_Previous returns the part
336 -- of the container already scanned and Current_To_Last the part not
337 -- scanned yet.
339 private
341 type Node_Type is record
342 Prev : Count_Type'Base := -1;
343 Next : Count_Type;
344 Element : Element_Type;
345 end record;
347 function "=" (L, R : Node_Type) return Boolean is abstract;
349 type Node_Array is array (Count_Type range <>) of Node_Type;
350 function "=" (L, R : Node_Array) return Boolean is abstract;
352 type List (Capacity : Count_Type) is tagged record
353 Nodes : Node_Array (1 .. Capacity) := (others => <>);
354 Free : Count_Type'Base := -1;
355 Length : Count_Type := 0;
356 First : Count_Type := 0;
357 Last : Count_Type := 0;
358 end record;
360 type Cursor is record
361 Node : Count_Type := 0;
362 end record;
364 Empty_List : constant List := (0, others => <>);
366 No_Element : constant Cursor := (Node => 0);
368 end Ada.Containers.Formal_Doubly_Linked_Lists;