agpl_1.0.0_b5da3320/src/agpl-containers-indefinite_matrix2d.adb

  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
with Ada.Containers.Indefinite_Ordered_Sets;

package body Agpl.Containers.Indefinite_Matrix2d is

   use Index_Index_Value_Maps;

   package IVM renames Index_Value_Maps;

   --------------
   -- Contains --
   --------------

   function Contains (This : Matrix; R, C : Index) return Boolean is
      X      : constant access Matrix := This'Unrestricted_Access;
      --  Necessary for Update_Element
      --  Safe since Matrix is tagged and this is used locally

      I      : constant Cursor  := This.Find (R);
      Result :          Boolean := False;
   begin
      if not Has_Element (I) then
         return False;
      end if;

      declare
         procedure Contains (Key : Index; RMap : in out IVM.Map) is
            pragma Unreferenced (Key);
         begin
            Result := RMap.Contains (C);
         end Contains;
      begin
         X.Update_Element (I, Contains'Access);
      end;

      return Result;
   end Contains;

   ---------
   -- Get --
   ---------

   function Get (This : Matrix; R, C : Index) return Value is
      X : constant access Matrix := This'Unrestricted_Access;
      I : constant Cursor := This.Find (R);
      J :          IVM.Cursor;

      procedure Get (Key : Index; RMap : in out IVM.Map) is
         pragma Unreferenced (Key);
      begin
         J := RMap.Find (C);
      end Get;
   begin
      X.Update_Element (I, Get'Access);
      return IVM.Element (J);
   end Get;

   ---------
   -- Get --
   ---------

   procedure Get
     (This : Matrix;
      R, C : Index;
      V : out Value;
      Found : out Boolean)
   is
      X : constant access Matrix := This'Unrestricted_Access;
      I : constant Cursor := This.Find (R);
      J : IVM.Cursor;

      procedure Get (Key : Index; RMap : in out IVM.Map) is
         pragma Unreferenced (Key);
      begin
         J := RMap.Find (C);
         if IVM.Has_Element (J) then
            V     := IVM.Element (J);
            Found := True;
         else
            Found := False;
         end if;
      end Get;
   begin
      if Has_Element (I) then
         X.Update_Element (I, Get'Access);
      else
         Found := False;
      end if;
   end Get;

   ---------
   -- Set --
   ---------

   procedure Set (This : in out Matrix; R, C : Index; V : Value) is
      I  : Cursor  := This.Find (R);
      Ok : Boolean := False;

      procedure Set (Key : Index; RMap : in out IVM.Map) is
         pragma Unreferenced (Key);
      begin
         RMap.Include (C, V);
      end Set;
   begin
      if not Has_Element (I) then
         This.Insert (R, IVM.Empty_Map, I, Ok);
         if not Ok then
            raise Constraint_Error with "Row creation failed";
         end if;
      end if;

      This.Update_Element (I, Set'Access);
   end Set;

   -----------------
   -- Row_Indexes --
   -----------------

   function Row_Indexes (This : Matrix) return Index_Vector is
      Result : Index_Vector;

      procedure X (I : Cursor) is
      begin
         Result.Append (Key (I));
      end X;
   begin
      This.Iterate (X'Access);
      return Result;
   end Row_Indexes;

   --------------------
   -- Column_Indexes --
   --------------------

   function Column_Indexes (This : Matrix) return Index_Vector is
      Thix : constant access Matrix := This'Unrestricted_Access;

      package Index_Sets is new Ada.Containers.Indefinite_Ordered_Sets (Index);

      Set : Index_Sets.Set;

      procedure X (I : Cursor) is
         procedure Y (Key : Index; Val : in out Index_Value_Maps.Map) is
            pragma Unreferenced (Key);
            procedure Z (I : IVM.Cursor) is
            begin
               Set.Include (IVM.Key (I));
            end Z;
         begin
            Val.Iterate (Z'Access);
         end Y;
      begin
         Thix.Update_Element (I, Y'Access);
      end X;
   begin
      This.Iterate (X'Access);

      declare
         Result : Index_Vector;
         procedure X (I : Index_Sets.Cursor) is
         begin
            Result.Append (Index_Sets.Element (I));
         end X;
      begin
         Set.Iterate (X'Access);
         return Result;
      end;
   end Column_Indexes;

end Agpl.Containers.Indefinite_Matrix2d;