stephes_ada_library_3.7.3_08b48307/source/sal-gen_bounded_definite_doubly_linked_lists.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
--  Abstract :
--
--  A generic bounded doubly linked list with definite elements; no dynamic memory.
--
--  Copyright (C) 2017 - 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR
--  PURPOSE. See the GNU General Public License for more details. You
--  should have received a copy of the GNU General Public License
--  distributed with this program; see file COPYING. If not, write to
--  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
--  MA 02111-1307, USA.
--
--  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.Containers;
with Ada.Iterator_Interfaces;
generic
   type Element_Type is private;
package SAL.Gen_Bounded_Definite_Doubly_Linked_Lists is

   type List (Size : Peek_Type) is tagged private
   --  We'd like to force initialization; one choice is to use
   --  Ada.Finalization, but that's pretty heavy. Another is to use <>
   --  instead of Size, but then we can't declare a List in a record type
   --  (ie WisiToken Configuration). So we do this, and let the user
   --  cope.
   with
      Constant_Indexing => Constant_Ref,
      Variable_Indexing => Variable_Ref,
      Default_Iterator  => Iterate,
      Iterator_Element  => Element_Type;

   type List_Access_Constant is access constant List;
   for List_Access_Constant'Storage_Size use 0;

   type List_Access is access all List;
   for List_Access'Storage_Size use 0;

   procedure Initialize (Container : in out List);

   function Empty_List (Size : in Peek_Type) return List;

   procedure Clear (Container : in out List);
   --  Set Container to empty.

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

   procedure Append (Container : in out List; Element : in Element_Type);
   --  Raises SAL.Container_Full if Container is full, or if it is not
   --  initialized.

   procedure Prepend (Container : in out List; Element : in Element_Type);
   --  Raises SAL.Container_Full if Container is full, or if it is not
   --  initialized.

   function To_List (Element : in Element_Type; Size : in Peek_Type) return List;

   type Cursor is private;

   function Has_Element (Position : in Cursor) return Boolean;

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

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

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

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

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

   function Element (Container : in List; 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);

   procedure Delete_First (Container : in out List);

   function Append (Container : in out List; Element : in Element_Type) return Cursor;

   procedure Insert
     (Container : in out List;
      Before    : in     Cursor;
      Element   : in     Element_Type);
   function Insert
     (Container : in out List;
      Before    : in     Cursor;
      Element   : in     Element_Type)
     return Cursor;
   --  If Before is No_Element, insert after Last.

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

   function Constant_Ref (Container : aliased in List; 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_Ref (Container : aliased in out List; Position : in Cursor) return Variable_Reference_Type
   with Inline, Pre => Has_Element (Position);

   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 is record
      Element : aliased Element_Type;
      Prev    : Base_Peek_Type := Invalid_Peek_Index; -- index in List.Nodes
      Next    : Base_Peek_Type := Invalid_Peek_Index;
   end record;

   type Node_Array_Type is array (Peek_Type range <>) of Node_Type;

   type Index_Array is array (Peek_Type range <>) of Base_Peek_Type;
   --  We'd like to use a different index type for Free_List, but Ada
   --  does not allow Integer (Size); "discriminant in constraint must
   --  appear alone"

   type List (Size : Peek_Type) is tagged record
      Head : Base_Peek_Type := Invalid_Peek_Index;
      Tail : Base_Peek_Type := Invalid_Peek_Index;

      Nodes     : Node_Array_Type (1 .. Size);
      Free_List : Index_Array (1 .. Size);
      Free_Last : Base_Peek_Type := 0; --  Append raises Container_Full if user does not call Initialize.

      Count : Ada.Containers.Count_Type := 0;
   end record;

   type Cursor is record
      Ptr : Base_Peek_Type := Invalid_Peek_Index; -- index of Node in List.Nodes
   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;

   No_Element : constant Cursor := (Ptr => Invalid_Peek_Index);

   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_Bounded_Definite_Doubly_Linked_Lists;