libgpr2_24.0.0_eda3c693/src/lib/gpr2-project-attribute-set.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
--
--  Copyright (C) 2019-2023, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-Exception
--

with Ada.Iterator_Interfaces;

private with Ada.Containers.Indefinite_Ordered_Maps;

package GPR2.Project.Attribute.Set is

   use type Attribute_Index.Object;

   type Object is tagged private
     with Constant_Indexing => Constant_Reference,
          Variable_Indexing => Reference,
          Default_Iterator  => Iterate,
          Iterator_Element  => Attribute.Object;

   Empty_Set : constant Object;

   function Length (Self : Object) return Containers.Count_Type;

   function Is_Empty (Self : Object) return Boolean;

   function Contains
     (Self   : Object;
      Name   : Attribute_Id;
      Index  : Attribute_Index.Object := Attribute_Index.Undefined;
      At_Pos : Unit_Index             := No_Index) return Boolean;
   --  Checks whether the set contains the attribute with the given Name and
   --  possibly the given Index.

   function Contains
     (Self      : Object;
      Attribute : Project.Attribute.Object) return Boolean;
   --  Returns True if the set contains the given attribute

   procedure Clear (Self : in out Object);
   --  Removes all elements from Self

   function Element
     (Self   : Object;
      Name   : Attribute_Id;
      Index  : Attribute_Index.Object := Attribute_Index.Undefined;
      At_Pos : Unit_Index             := No_Index) return Attribute.Object
     with Post => (if Self.Contains (Name, Index, At_Pos)
                   then Element'Result.Is_Defined
                   else not Element'Result.Is_Defined),
          Inline;

   procedure Insert
     (Self : in out Object; Attribute : Project.Attribute.Object)
     with Pre  => not Self.Contains (Attribute),
          Post => Self.Contains (Attribute);
   --  Inserts Attribute into the set

   procedure Include
     (Self : in out Object; Attribute : Project.Attribute.Object)
     with Post => Self.Contains (Attribute);
   --  Inserts or replaces an Attribute into the set

   --  Iterator

   type Cursor is private;

   No_Element : constant Cursor;

   function Element (Position : Cursor) return Attribute.Object
     with Post =>
       (if Has_Element (Position)
        then Element'Result.Is_Defined
        else not Element'Result.Is_Defined);

   function Find
     (Self   : Object;
      Name   : Attribute_Id;
      Index  : Attribute_Index.Object := Attribute_Index.Undefined;
      At_Pos : Unit_Index             := No_Index) return Cursor;

   function Find
     (Self      : Object;
      Attribute : Project.Attribute.Object) return Cursor;

   function Has_Element (Position : Cursor) return Boolean;

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

   type Constant_Reference_Type
     (Attribute : not null access constant Project.Attribute.Object) is private
     with Implicit_Dereference => Attribute;

   type Reference_Type
     (Attribute : not null access Project.Attribute.Object) is private
   with Implicit_Dereference => Attribute;

   function Constant_Reference
     (Self     : aliased Object;
      Position : Cursor) return Constant_Reference_Type;

   function Reference
     (Self     : aliased in out Object;
      Position : Cursor) return Reference_Type;

   function Iterate
     (Self          : Object;
      Name          : Optional_Attribute_Id  := No_Attribute;
      Index         : Attribute_Index.Object := Attribute_Index.Undefined;
      At_Pos        : Unit_Index             := No_Index;
      With_Defaults : Boolean                := True)
      return Attribute_Iterator.Forward_Iterator'Class;

   function Filter
     (Self   : Object;
      Name   : Optional_Attribute_Id  := No_Attribute;
      Index  : Attribute_Index.Object := Attribute_Index.Undefined;
      At_Pos : Unit_Index             := No_Index) return Object
     with Post => (if Name = No_Attribute and then not Index.Is_Defined
                   then Filter'Result = Self);
   --  Returns an attribute set containing only the attribute corresponding to
   --  the given filter.

   --  Some helper routines on attributes in the set

   function Has_Languages (Self : Object) return Boolean;
   function Languages     (Self : Object) return Attribute.Object;

private

   package PRA renames GPR2.Project.Registry.Attribute;

   --  An attribute set object is:
   --
   --     1. A map at the first level with the attribute name as key
   --
   --     2. The above map point to another map containing the actual
   --        attributes. The map key is the index for the attributes.

   package Set_Attribute is new Ada.Containers.Indefinite_Ordered_Maps
     (Value_At_Pos, Attribute.Object);
   --  The key in this set is the attribute index and 'at' part

   package Set is new Ada.Containers.Indefinite_Ordered_Maps
     (Attribute_Id, Set_Attribute.Map, "<", Set_Attribute."=");
   --  The key in this Set is the attribute name (not case sensitive)

   type Cursor is record
      CM  : Set.Cursor;               -- main map cursor
      CA  : Set_Attribute.Cursor;     -- inner map cursor (Set below)
   end record;

   No_Element : constant Cursor :=
                  (Set.No_Element,
                   Set_Attribute.No_Element);

   type Constant_Reference_Type
     (Attribute : not null access constant Project.Attribute.Object)
   is record
      --  We need to keep the underlying reference so that it is not cleared
      --  upon return of the getter, and so that the container has the proper
      --  busy state
      Ref : Set_Attribute.Constant_Reference_Type (Attribute);
   end record;

   type Reference_Type
     (Attribute : not null access Project.Attribute.Object)
   is record
      --  We need to keep the underlying reference so that it is not cleared
      --  upon return of the getter, and so that the container has the proper
      --  busy state
      Ref : Set_Attribute.Reference_Type (Attribute);
   end record;

   type Object is tagged record
      Attributes : aliased Set.Map;
      Length     : Containers.Count_Type := 0;
   end record;

   Empty_Set : constant Object := (others => <>);

   function Has_Languages (Self : Object) return Boolean is
     (Self.Contains (Name => PRA.Languages.Attr));

   function Languages (Self : Object) return Attribute.Object is
     (Self.Element (Name => PRA.Languages.Attr));

end GPR2.Project.Attribute.Set;