OSDN Git Service

2011-10-16 Tristan Gingold <gingold@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-cfdlli.ads
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-2011, 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 ------------------------------------------------------------------------------
31
32 --  This spec is derived from Ada.Containers.Bounded_Doubly_Linked_Lists in the
33 --  Ada 2012 RM. The modifications are to facilitate formal proofs by making it
34 --  easier to express properties.
35
36 --  The modifications are:
37
38 --    A parameter for the container is added to every function reading the
39 --    contents of a container: Next, Previous, Query_Element, Has_Element,
40 --    Iterate, Reverse_Iterate, Element. This change is motivated by the need
41 --    to have cursors which are valid on different containers (typically a
42 --    container C and its previous version C'Old) for expressing properties,
43 --    which is not possible if cursors encapsulate an access to the underlying
44 --    container.
45
46 --    There are three new functions:
47
48 --      function Strict_Equal (Left, Right : List) return Boolean;
49 --      function Left  (Container : List; Position : Cursor) return List;
50 --      function Right (Container : List; Position : Cursor) return List;
51
52 --    See detailed specifications for these subprograms
53
54 private with Ada.Streams;
55 with Ada.Containers;
56
57 generic
58    type Element_Type is private;
59
60    with function "=" (Left, Right : Element_Type)
61                       return Boolean is <>;
62
63 package Ada.Containers.Formal_Doubly_Linked_Lists is
64    pragma Pure;
65
66    type List (Capacity : Count_Type) is tagged private;
67    --  pragma Preelaborable_Initialization (List);
68
69    type Cursor is private;
70    pragma Preelaborable_Initialization (Cursor);
71
72    Empty_List : constant List;
73
74    No_Element : constant Cursor;
75
76    function "=" (Left, Right : List) return Boolean;
77
78    function Length (Container : List) return Count_Type;
79
80    function Is_Empty (Container : List) return Boolean;
81
82    procedure Clear (Container : in out List);
83
84    procedure Assign (Target : in out List; Source : List);
85
86    function Copy (Source : List; Capacity : Count_Type := 0) return List;
87
88    function Element (Container : List; Position : Cursor) return Element_Type;
89
90    procedure Replace_Element
91      (Container : in out List;
92       Position  : Cursor;
93       New_Item  : Element_Type);
94
95    procedure Query_Element
96      (Container : List; Position : Cursor;
97       Process   : not null access procedure (Element : Element_Type));
98
99    procedure Update_Element
100      (Container : in out List;
101       Position  : Cursor;
102       Process   : not null access procedure (Element : in out Element_Type));
103
104    procedure Move (Target : in out List; Source : in out List);
105
106    procedure Insert
107      (Container : in out List;
108       Before    : Cursor;
109       New_Item  : Element_Type;
110       Count     : Count_Type := 1);
111
112    procedure Insert
113      (Container : in out List;
114       Before    : Cursor;
115       New_Item  : Element_Type;
116       Position  : out Cursor;
117       Count     : Count_Type := 1);
118
119    procedure Insert
120      (Container : in out List;
121       Before    : Cursor;
122       Position  : out Cursor;
123       Count     : Count_Type := 1);
124
125    procedure Prepend
126      (Container : in out List;
127       New_Item  : Element_Type;
128       Count     : Count_Type := 1);
129
130    procedure Append
131      (Container : in out List;
132       New_Item  : Element_Type;
133       Count     : Count_Type := 1);
134
135    procedure Delete
136      (Container : in out List;
137       Position  : in out Cursor;
138       Count     : Count_Type := 1);
139
140    procedure Delete_First
141      (Container : in out List;
142       Count     : Count_Type := 1);
143
144    procedure Delete_Last
145      (Container : in out List;
146       Count     : Count_Type := 1);
147
148    procedure Reverse_Elements (Container : in out List);
149
150    procedure Swap
151      (Container : in out List;
152       I, J      : Cursor);
153
154    procedure Swap_Links
155      (Container : in out List;
156       I, J      : Cursor);
157
158    procedure Splice
159      (Target : in out List;
160       Before : Cursor;
161       Source : in out List);
162
163    procedure Splice
164      (Target   : in out List;
165       Before   : Cursor;
166       Source   : in out List;
167       Position : in out Cursor);
168
169    procedure Splice
170      (Container : in out List;
171       Before    : Cursor;
172       Position  : Cursor);
173
174    function First (Container : List) return Cursor;
175
176    function First_Element (Container : List) return Element_Type;
177
178    function Last (Container : List) return Cursor;
179
180    function Last_Element (Container : List) return Element_Type;
181
182    function Next (Container : List; Position : Cursor) return Cursor;
183
184    procedure Next (Container : List; Position : in out Cursor);
185
186    function Previous (Container : List; Position : Cursor) return Cursor;
187
188    procedure Previous (Container : List; Position : in out Cursor);
189
190    function Find
191      (Container : List;
192       Item      : Element_Type;
193       Position  : Cursor := No_Element) return Cursor;
194
195    function Reverse_Find
196      (Container : List;
197       Item      : Element_Type;
198       Position  : Cursor := No_Element) return Cursor;
199
200    function Contains
201      (Container : List;
202       Item      : Element_Type) return Boolean;
203
204    function Has_Element (Container : List; Position : Cursor) return Boolean;
205
206    procedure Iterate
207      (Container : List;
208       Process   :
209       not null access procedure (Container : List; Position : Cursor));
210
211    procedure Reverse_Iterate
212      (Container : List;
213       Process   :
214       not null access procedure (Container : List; Position : Cursor));
215
216    generic
217       with function "<" (Left, Right : Element_Type) return Boolean is <>;
218    package Generic_Sorting is
219
220       function Is_Sorted (Container : List) return Boolean;
221
222       procedure Sort (Container : in out List);
223
224       procedure Merge (Target, Source : in out List);
225
226    end Generic_Sorting;
227
228    function Strict_Equal (Left, Right : List) return Boolean;
229    --  Strict_Equal returns True if the containers are physically equal, i.e.
230    --  they are structurally equal (function "=" returns True) and that they
231    --  have the same set of cursors.
232
233    function Left  (Container : List; Position : Cursor) return List;
234    function Right (Container : List; Position : Cursor) return List;
235    --  Left returns a container containing all elements preceding Position
236    --  (excluded) in Container. Right returns a container containing all
237    --  elements following Position (included) in Container. These two new
238    --  functions can be used to express invariant properties in loops which
239    --  iterate over containers. Left returns the part of the container already
240    --  scanned and Right the part not scanned yet.
241
242 private
243
244    type Node_Type is record
245       Prev    : Count_Type'Base := -1;
246       Next    : Count_Type;
247       Element : Element_Type;
248    end record;
249    function "=" (L, R : Node_Type) return Boolean is abstract;
250
251    type Node_Array is array (Count_Type range <>) of Node_Type;
252    function "=" (L, R : Node_Array) return Boolean is abstract;
253
254    type List (Capacity : Count_Type) is tagged record
255       Nodes  : Node_Array (1 .. Capacity) := (others => <>);
256       Free   : Count_Type'Base := -1;
257       Busy   : Natural := 0;
258       Lock   : Natural := 0;
259       Length : Count_Type := 0;
260       First  : Count_Type := 0;
261       Last   : Count_Type := 0;
262    end record;
263
264    use Ada.Streams;
265
266    procedure Read
267      (Stream : not null access Root_Stream_Type'Class;
268       Item   : out List);
269
270    for List'Read use Read;
271
272    procedure Write
273      (Stream : not null access Root_Stream_Type'Class;
274       Item   : List);
275
276    for List'Write use Write;
277
278    type Cursor is record
279       Node : Count_Type := 0;
280    end record;
281
282    procedure Read
283      (Stream : not null access Root_Stream_Type'Class;
284       Item   : out Cursor);
285
286    for Cursor'Read use Read;
287
288    procedure Write
289      (Stream : not null access Root_Stream_Type'Class;
290       Item   : Cursor);
291
292    for Cursor'Write use Write;
293
294    Empty_List : constant List := (0, others => <>);
295
296    No_Element : constant Cursor := (Node => 0);
297
298 end Ada.Containers.Formal_Doubly_Linked_Lists;