stephes_ada_library_3.7.3_08b48307/source/sal-gen_indefinite_doubly_linked_lists_sorted_aux.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
--  Abstract :
--
--  A generic sorted doubly linked list with indefinite elements;
--  Element_Compare takes an auxiliary object.
--
--  Copyright (C) 2018 - 2021 Free Software Foundation, Inc.
--
--  This library is free software;  you can redistribute it and/or modify it
--  under terms of the  GNU General Public License  as published by the Free
--  Software  Foundation;  either version 3,  or (at your  option) any later
--  version. This library is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
--  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.

--  As a special exception under Section 7 of GPL version 3, you are granted
--  additional permissions described in the GCC Runtime Library Exception,
--  version 3.1, as published by the Free Software Foundation.

pragma License (Modified_GPL);

with Ada.Finalization;
with Ada.Iterator_Interfaces;
with Ada.Unchecked_Deallocation;
generic
   type Element_Type (<>) is private;
   type Compare_Aux is limited private;
   with function Element_Compare (Left, Right : in Element_Type; Aux : in Compare_Aux) return Compare_Result;
package SAL.Gen_Indefinite_Doubly_Linked_Lists_Sorted_Aux is
   use all type Ada.Containers.Count_Type;

   type List is new Ada.Finalization.Controlled with private
   with
     Constant_Indexing => Constant_Reference,
     Variable_Indexing => Variable_Reference,
     Default_Iterator  => Iterate,
     Iterator_Element  => Element_Type;

   --  If user uses Variable_Indexing, they must not change the sort
   --  order of the elements.

   Empty_List : constant List;

   function Is_Empty (Container : in List) return Boolean;

   overriding procedure Adjust (Container : in out List);
   --  Deep copy.

   overriding procedure Finalize (Container : in out List);
   --  Free all items in List.

   procedure Clear (Container : in out List) renames Finalize;

   overriding function "=" (Left, Right : in List) return Boolean;
   --  True if contents are the same.

   function Length (Container : in List) return Ada.Containers.Count_Type;

   function To_List (Element : in Element_Type) return List;

   procedure Insert
     (Container : in out List;
      Element   : in     Element_Type;
      Aux       : in     Compare_Aux);
   --  Insert Element before first item for which Element_Order (item,
   --  element) returns True.

   function Contains
     (Container : in List;
      Element   : in Element_Type;
      Aux       : in     Compare_Aux)
     return Boolean;

   procedure Merge
     (Target : in out List;
      Source : in     List;
      Aux    : in     Compare_Aux;
      Added  :    out Boolean);
   --  Add all elements of Source to Target, if they are not already
   --  present.
   --
   --  Added is True if any element was not already present.

   procedure Merge
     (Target  : in out List;
      Source  : in     List;
      Aux     : in     Compare_Aux;
      Added   :    out Boolean;
      Exclude : in     Element_Type);
   --  Add all elements of Source to Target, if they are not already
   --  present, and are not equal to Exclude.
   --
   --  Added is True if any element was not already present.

   type Cursor is private;

   function No_Element (Container : aliased in List) return Cursor;

   function Has_Element (Position : in Cursor) return Boolean;

   function First (Container : aliased in List) return Cursor;
   function Last (Container : aliased in List) return Cursor;

   function Find
     (Container : aliased in List;
      Element   :         in Element_Type;
      Aux       :         in Compare_Aux)
     return Cursor;
   --  No_Element if Element not found.

   procedure Next (Position : in out Cursor)
   with Pre => Has_Element (Position);

   function Next (Position : in Cursor) return Cursor
   with Pre => Has_Element (Position);
   function Previous (Position : in Cursor) return Cursor
   with Pre => Has_Element (Position);

   function Element (Position : in Cursor) return Element_Type
   with Pre => Has_Element (Position);

   procedure Delete (Container : in out List; Position : in out Cursor)
   with Pre => Has_Element (Position);

   function Pop (Container : in out List) return Element_Type
   with Pre => Container.Length > 0;
   --  Return Container.First, delete it from Container.

   type Constant_Reference_Type (Element : not null access constant Element_Type) is private with
     Implicit_Dereference => Element;

   function Constant_Reference (Container : in List; Position : in Cursor) return Constant_Reference_Type with
     Inline, Pre => Has_Element (Position);

   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type with
     Inline, Pre => Has_Element (Position);

   type Variable_Reference_Type (Element : not null access Element_Type) is private with
     Implicit_Dereference => Element;

   function Variable_Reference (Container : in List; Position : in Cursor) return Variable_Reference_Type
   with Inline, Pre => Has_Element (Position);

   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
   with Inline, Pre => Has_Element (Position);
   --  User must not change the element in a way that affects the sort order.

   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, Has_Element);

   function Iterate (Container : aliased in List) return Iterator_Interfaces.Reversible_Iterator'Class;

private
   type Node_Type;
   type Node_Access is access Node_Type;
   type Element_Access is access Element_Type;

   type Node_Type is record
      Element : Element_Access;
      Prev    : Node_Access;
      Next    : Node_Access;
   end record;

   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
   procedure Free is new Ada.Unchecked_Deallocation (Element_Type, Element_Access);

   type List is new Ada.Finalization.Controlled with record
      Head  : Node_Access               := null;
      Tail  : Node_Access               := null;
      Count : Ada.Containers.Count_Type := 0;
   end record;

   function Is_Empty (Container : in List) return Boolean
   is (Container.Head = null);

   type Cursor is record
      Ptr : Node_Access;
   end record;

   type Constant_Reference_Type (Element : not null access constant Element_Type) is
   record
      Dummy : Integer := raise Program_Error with "uninitialized reference";
   end record;

   type Variable_Reference_Type (Element : not null access Element_Type) is
   record
      Dummy : Integer := raise Program_Error with "uninitialized reference";
   end record;

   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 0);

   function No_Element (Container : aliased in List) return Cursor
   is (Ptr => null);

   type Iterator (Container : not null access constant List) is new Iterator_Interfaces.Reversible_Iterator with
     null record;

   overriding function First (Object : Iterator) return Cursor;
   overriding function Last  (Object : Iterator) return Cursor;

   overriding function Next
     (Object   : Iterator;
      Position : Cursor) return Cursor;

   overriding function Previous
     (Object   : Iterator;
      Position : Cursor) return Cursor;

end SAL.Gen_Indefinite_Doubly_Linked_Lists_Sorted_Aux;