1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT LIBRARY COMPONENTS                          --
4--                                                                          --
5--           A D A . C O N T A I N E R S . O R D E R E D _ M A P S          --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 2004-2013, 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-- This unit was originally developed by Matthew J Heaney.                  --
32------------------------------------------------------------------------------
33
34with Ada.Iterator_Interfaces;
35
36private with Ada.Containers.Red_Black_Trees;
37private with Ada.Finalization;
38private with Ada.Streams;
39
40generic
41   type Key_Type is private;
42   type Element_Type is private;
43
44   with function "<" (Left, Right : Key_Type) return Boolean is <>;
45   with function "=" (Left, Right : Element_Type) return Boolean is <>;
46
47package Ada.Containers.Ordered_Maps is
48   pragma Preelaborate;
49   pragma Remote_Types;
50
51   function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
52
53   type Map is tagged private with
54      Constant_Indexing => Constant_Reference,
55      Variable_Indexing => Reference,
56      Default_Iterator  => Iterate,
57      Iterator_Element  => Element_Type;
58
59   type Cursor is private;
60   pragma Preelaborable_Initialization (Cursor);
61
62   Empty_Map : constant Map;
63
64   No_Element : constant Cursor;
65
66   function Has_Element (Position : Cursor) return Boolean;
67
68   package Map_Iterator_Interfaces is new
69     Ada.Iterator_Interfaces (Cursor, Has_Element);
70
71   function "=" (Left, Right : Map) return Boolean;
72
73   function Length (Container : Map) return Count_Type;
74
75   function Is_Empty (Container : Map) return Boolean;
76
77   procedure Clear (Container : in out Map);
78
79   function Key (Position : Cursor) return Key_Type;
80
81   function Element (Position : Cursor) return Element_Type;
82
83   procedure Replace_Element
84     (Container : in out Map;
85      Position  : Cursor;
86      New_Item  : Element_Type);
87
88   procedure Query_Element
89     (Position : Cursor;
90      Process  : not null access
91                   procedure (Key : Key_Type; Element : Element_Type));
92
93   procedure Update_Element
94     (Container : in out Map;
95      Position  : Cursor;
96      Process   : not null access
97                   procedure (Key : Key_Type; Element : in out Element_Type));
98
99   type Constant_Reference_Type
100      (Element : not null access constant Element_Type) is private
101   with
102      Implicit_Dereference => Element;
103
104   type Reference_Type (Element : not null access Element_Type) is private
105   with
106      Implicit_Dereference => Element;
107
108   function Constant_Reference
109     (Container : aliased Map;
110      Position  : Cursor) return Constant_Reference_Type;
111   pragma Inline (Constant_Reference);
112
113   function Reference
114     (Container : aliased in out Map;
115      Position  : Cursor) return Reference_Type;
116   pragma Inline (Reference);
117
118   function Constant_Reference
119     (Container : aliased Map;
120      Key       : Key_Type) return Constant_Reference_Type;
121   pragma Inline (Constant_Reference);
122
123   function Reference
124     (Container : aliased in out Map;
125      Key       : Key_Type) return Reference_Type;
126   pragma Inline (Reference);
127
128   procedure Assign (Target : in out Map; Source : Map);
129
130   function Copy (Source : Map) return Map;
131
132   procedure Move (Target : in out Map; Source : in out Map);
133
134   procedure Insert
135     (Container : in out Map;
136      Key       : Key_Type;
137      New_Item  : Element_Type;
138      Position  : out Cursor;
139      Inserted  : out Boolean);
140
141   procedure Insert
142     (Container : in out Map;
143      Key       : Key_Type;
144      Position  : out Cursor;
145      Inserted  : out Boolean);
146
147   procedure Insert
148     (Container : in out Map;
149      Key       : Key_Type;
150      New_Item  : Element_Type);
151
152   procedure Include
153     (Container : in out Map;
154      Key       : Key_Type;
155      New_Item  : Element_Type);
156
157   procedure Replace
158     (Container : in out Map;
159      Key       : Key_Type;
160      New_Item  : Element_Type);
161
162   procedure Exclude (Container : in out Map; Key : Key_Type);
163
164   procedure Delete (Container : in out Map; Key : Key_Type);
165
166   procedure Delete (Container : in out Map; Position : in out Cursor);
167
168   procedure Delete_First (Container : in out Map);
169
170   procedure Delete_Last (Container : in out Map);
171
172   function First (Container : Map) return Cursor;
173
174   function First_Element (Container : Map) return Element_Type;
175
176   function First_Key (Container : Map) return Key_Type;
177
178   function Last (Container : Map) return Cursor;
179
180   function Last_Element (Container : Map) return Element_Type;
181
182   function Last_Key (Container : Map) return Key_Type;
183
184   function Next (Position : Cursor) return Cursor;
185
186   procedure Next (Position : in out Cursor);
187
188   function Previous (Position : Cursor) return Cursor;
189
190   procedure Previous (Position : in out Cursor);
191
192   function Find (Container : Map; Key : Key_Type) return Cursor;
193
194   function Element (Container : Map; Key : Key_Type) return Element_Type;
195
196   function Floor (Container : Map; Key : Key_Type) return Cursor;
197
198   function Ceiling (Container : Map; Key : Key_Type) return Cursor;
199
200   function Contains (Container : Map; Key : Key_Type) return Boolean;
201
202   function "<" (Left, Right : Cursor) return Boolean;
203
204   function ">" (Left, Right : Cursor) return Boolean;
205
206   function "<" (Left : Cursor; Right : Key_Type) return Boolean;
207
208   function ">" (Left : Cursor; Right : Key_Type) return Boolean;
209
210   function "<" (Left : Key_Type; Right : Cursor) return Boolean;
211
212   function ">" (Left : Key_Type; Right : Cursor) return Boolean;
213
214   procedure Iterate
215     (Container : Map;
216      Process   : not null access procedure (Position : Cursor));
217
218   procedure Reverse_Iterate
219     (Container : Map;
220      Process   : not null access procedure (Position : Cursor));
221
222   --  The map container supports iteration in both the forward and reverse
223   --  directions, hence these constructor functions return an object that
224   --  supports the Reversible_Iterator interface.
225
226   function Iterate
227     (Container : Map)
228      return Map_Iterator_Interfaces.Reversible_Iterator'class;
229
230   function Iterate
231     (Container : Map;
232      Start     : Cursor)
233      return Map_Iterator_Interfaces.Reversible_Iterator'class;
234
235private
236
237   pragma Inline (Next);
238   pragma Inline (Previous);
239
240   type Node_Type;
241   type Node_Access is access Node_Type;
242
243   type Node_Type is limited record
244      Parent  : Node_Access;
245      Left    : Node_Access;
246      Right   : Node_Access;
247      Color   : Red_Black_Trees.Color_Type := Red_Black_Trees.Red;
248      Key     : Key_Type;
249      Element : aliased Element_Type;
250   end record;
251
252   package Tree_Types is
253     new Red_Black_Trees.Generic_Tree_Types (Node_Type, Node_Access);
254
255   type Map is new Ada.Finalization.Controlled with record
256      Tree : Tree_Types.Tree_Type;
257   end record;
258
259   overriding procedure Adjust (Container : in out Map);
260
261   overriding procedure Finalize (Container : in out Map) renames Clear;
262
263   use Red_Black_Trees;
264   use Tree_Types;
265   use Ada.Finalization;
266   use Ada.Streams;
267
268   procedure Write
269     (Stream    : not null access Root_Stream_Type'Class;
270      Container : Map);
271
272   for Map'Write use Write;
273
274   procedure Read
275     (Stream    : not null access Root_Stream_Type'Class;
276      Container : out Map);
277
278   for Map'Read use Read;
279
280   type Map_Access is access all Map;
281   for Map_Access'Storage_Size use 0;
282
283   type Cursor is record
284      Container : Map_Access;
285      Node      : Node_Access;
286   end record;
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   procedure Read
295     (Stream : not null access Root_Stream_Type'Class;
296      Item   : out Cursor);
297
298   for Cursor'Read use Read;
299
300   type Reference_Control_Type is
301      new Controlled with record
302         Container : Map_Access;
303      end record;
304
305   overriding procedure Adjust (Control : in out Reference_Control_Type);
306   pragma Inline (Adjust);
307
308   overriding procedure Finalize (Control : in out Reference_Control_Type);
309   pragma Inline (Finalize);
310
311   type Constant_Reference_Type
312      (Element : not null access constant Element_Type) is
313      record
314         Control : Reference_Control_Type;
315      end record;
316
317   procedure Read
318     (Stream : not null access Root_Stream_Type'Class;
319      Item   : out Constant_Reference_Type);
320
321   for Constant_Reference_Type'Read use Read;
322
323   procedure Write
324     (Stream : not null access Root_Stream_Type'Class;
325      Item   : Constant_Reference_Type);
326
327   for Constant_Reference_Type'Write use Write;
328
329   type Reference_Type
330      (Element : not null access Element_Type) is
331      record
332         Control : Reference_Control_Type;
333      end record;
334
335   procedure Read
336     (Stream : not null access Root_Stream_Type'Class;
337      Item   : out Reference_Type);
338
339   for Reference_Type'Read use Read;
340
341   procedure Write
342     (Stream : not null access Root_Stream_Type'Class;
343      Item   : Reference_Type);
344
345   for Reference_Type'Write use Write;
346
347   Empty_Map : constant Map :=
348                 (Controlled with Tree => (First  => null,
349                                           Last   => null,
350                                           Root   => null,
351                                           Length => 0,
352                                           Busy   => 0,
353                                           Lock   => 0));
354
355   No_Element : constant Cursor := Cursor'(null, null);
356
357   type Iterator is new Limited_Controlled and
358     Map_Iterator_Interfaces.Reversible_Iterator with
359   record
360      Container : Map_Access;
361      Node      : Node_Access;
362   end record;
363
364   overriding procedure Finalize (Object : in out Iterator);
365
366   overriding function First (Object : Iterator) return Cursor;
367   overriding function Last  (Object : Iterator) return Cursor;
368
369   overriding function Next
370     (Object   : Iterator;
371      Position : Cursor) return Cursor;
372
373   overriding function Previous
374     (Object   : Iterator;
375      Position : Cursor) return Cursor;
376
377end Ada.Containers.Ordered_Maps;
378