minimal_containers_1.0.0_592661c6/src/minimal_containers-bounded_vectors.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
--  Minimal_Containers.Bounded_Vectors (spec)
--
--  Copyright (C) 2023 Simon Wright <simon@pushface.org>
--
--  Minimal_Containers 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.  It 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.
--
--  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.
--
--  You should have received a copy of the GNU General Public License
--  and a copy of the GCC Runtime Library Exception along with this
--  program; see the files COPYING3 and COPYING.RUNTIME respectively.
--  If not, see <http://www.gnu.org/licenses/>.

with Ada.Containers;
with Ada.Iterator_Interfaces;

generic
   type Index_Type is range <>;
   type Element_Type is private;

   with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Minimal_Containers.Bounded_Vectors
is

   use Ada.Containers;

   subtype Extended_Index is Index_Type'Base
     range Index_Type'First - 1 ..
     Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;

   No_Index : constant Extended_Index := Extended_Index'First;

   subtype Capacity_Range
     is Count_Type range 0 .. Index_Type'Pos (Index_Type'Last);

   type Vector (Capacity : Capacity_Range) is tagged private
   with
     Default_Initial_Condition => Is_Empty (Vector),
     Default_Iterator          => Iterate,
     Iterator_Element          => Element_Type,
     Constant_Indexing         => Element_For_Iteration; -- see Ada Gem 128

   type Cursor is private;

   Empty_Vector : constant Vector;

   No_Element : constant Cursor;

   function Has_Element (Position : Cursor) return Boolean;

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

   function Capacity (Container : Vector) return Count_Type;

   function Length (Container : Vector) return Count_Type;

   function Is_Empty (Container : Vector) return Boolean;

   procedure Clear (Container : in out Vector)
   with
     Post => Is_Empty (Container);

   function Element (Container : Vector;
                     Index : Index_Type) return Element_Type;

   function Element (Position : Cursor) return Element_Type;

   procedure Append (Container : in out Vector; New_Item : Element_Type)
   with
     Pre  => Length (Container) < Capacity (Container),
     Post => Length (Container) = Length (Container'Old) + 1;

   procedure Delete (Container : in out Vector;
                     Index     : Extended_Index)
   with
     Pre  => Index in Index_Type'First .. Last_Index (Container),
     Post => Length (Container) = Length (Container)'Old - 1;

   procedure Delete (Container : in out Vector;
                     Position  : in out Cursor)
   with
     Pre  => Position /= No_Element,
     Post => Length (Container) = Length (Container)'Old - 1;

   procedure Delete_First (Container : in out Vector)
   with
     Pre => not Is_Empty (Container),
     Post => Length (Container) = Length (Container)'Old - 1;

   procedure Delete_Last (Container : in out Vector)
   with
     Pre => not Is_Empty (Container),
     Post => Length (Container) = Length (Container)'Old - 1;

   function First_Index (Container : Vector) return Index_Type
   with
     Post => First_Index'Result = Index_Type'First;

   function First (Container : Vector) return Cursor;

   function First_Element (Container : Vector) return Element_Type
   with
     Pre => not Is_Empty (Container);

   function Last_Index (Container : Vector) return Extended_Index;

   function Last (Container : Vector) return Cursor;

   function Last_Element (Container : Vector) return Element_Type;

   function Next (Position : Cursor) return Cursor;

   function Previous (Position : Cursor) return Cursor;

   function Find_Index (Container : Vector;
                        Item      : Element_Type;
                        Index     : Index_Type := Index_Type'First)
                       return Extended_Index;

   --  For iteration  --

   function Element_For_Iteration (Container : Vector;
                                   Position  : Cursor) return Element_Type;

   function Iterate
     (Container : Vector)
      return Vector_Iterator_Interfaces.Reversible_Iterator'Class;

   --  Sorting  --

   generic
      with function "<" (Left, Right : Element_Type) return Boolean is <>;
   package Generic_Sorting is

      function Is_Sorted (Container : Vector) return Boolean;

      procedure Sort (Container : in out Vector);

   end Generic_Sorting;

private

   subtype Array_Index is Capacity_Range range 1 .. Capacity_Range'Last;
   type Elements_Array is array (Array_Index range <>) of aliased Element_Type;

   type Generation_Type is mod 2**32; -- for tampering checks

   type Vector (Capacity : Capacity_Range) is tagged record
      Generation : Generation_Type := 0;
      Last       : Extended_Index  := No_Index;
      Elements   : Elements_Array (1 .. Capacity);
   end record;

   type Vector_Access is access constant Vector with Storage_Size => 0;

   type Cursor is record
      Container  : Vector_Access;
      Generation : Generation_Type := 0;
      Index      : Index_Type      := Index_Type'First;
   end record;

   Empty_Vector : constant Vector := (Capacity => 0, others => <>);

   No_Element : constant Cursor := (Container  => null,
                                    Generation => 0,
                                    Index      => Index_Type'First);

   type Iterator is new Vector_Iterator_Interfaces.Reversible_Iterator with
      record
         Container : Vector_Access;
         Index     : Index_Type'Base;
      end 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;

   --  Spec Implementations  --

   --  none

end Minimal_Containers.Bounded_Vectors;