File : a-cihase.ads


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT LIBRARY COMPONENTS                          --
   4 --                                                                          --
   5 --                  ADA.CONTAINERS.INDEFINITE_HASHED_SETS                   --
   6 --                                                                          --
   7 --                                 S p e c                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2004-2015, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- This specification is derived from the Ada Reference Manual for use with --
  12 -- GNAT. The copyright notice above, and the license provisions that follow --
  13 -- apply solely to the  contents of the part following the private keyword. --
  14 --                                                                          --
  15 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  16 -- terms of the  GNU General Public License as published  by the Free Soft- --
  17 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  18 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  19 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  20 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  21 --                                                                          --
  22 --                                                                          --
  23 --                                                                          --
  24 --                                                                          --
  25 --                                                                          --
  26 -- You should have received a copy of the GNU General Public License and    --
  27 -- a copy of the GCC Runtime Library Exception along with this program;     --
  28 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  29 -- <http://www.gnu.org/licenses/>.                                          --
  30 --                                                                          --
  31 -- This unit was originally developed by Matthew J Heaney.                  --
  32 ------------------------------------------------------------------------------
  33 
  34 with Ada.Iterator_Interfaces;
  35 
  36 private with Ada.Containers.Hash_Tables;
  37 with Ada.Containers.Helpers;
  38 private with Ada.Streams;
  39 private with Ada.Finalization;
  40 
  41 generic
  42    type Element_Type (<>) is private;
  43 
  44    with function Hash (Element : Element_Type) return Hash_Type;
  45 
  46    with function Equivalent_Elements (Left, Right : Element_Type)
  47                                      return Boolean;
  48 
  49    with function "=" (Left, Right : Element_Type) return Boolean is <>;
  50 
  51 package Ada.Containers.Indefinite_Hashed_Sets is
  52    pragma Annotate (CodePeer, Skip_Analysis);
  53    pragma Preelaborate;
  54    pragma Remote_Types;
  55 
  56    type Set is tagged private
  57      with Constant_Indexing => Constant_Reference,
  58           Default_Iterator  => Iterate,
  59           Iterator_Element  => Element_Type;
  60 
  61    pragma Preelaborable_Initialization (Set);
  62 
  63    type Cursor is private;
  64    pragma Preelaborable_Initialization (Cursor);
  65 
  66    Empty_Set : constant Set;
  67    --  Set objects declared without an initialization expression are
  68    --  initialized to the value Empty_Set.
  69 
  70    No_Element : constant Cursor;
  71    --  Cursor objects declared without an initialization expression are
  72    --  initialized to the value No_Element.
  73 
  74    function Has_Element (Position : Cursor) return Boolean;
  75    --  Equivalent to Position /= No_Element
  76 
  77    package Set_Iterator_Interfaces is new
  78      Ada.Iterator_Interfaces (Cursor, Has_Element);
  79 
  80    function "=" (Left, Right : Set) return Boolean;
  81    --  For each element in Left, set equality attempts to find the equal
  82    --  element in Right; if a search fails, then set equality immediately
  83    --  returns False. The search works by calling Hash to find the bucket in
  84    --  the Right set that corresponds to the Left element. If the bucket is
  85    --  non-empty, the search calls the generic formal element equality operator
  86    --  to compare the element (in Left) to the element of each node in the
  87    --  bucket (in Right); the search terminates when a matching node in the
  88    --  bucket is found, or the nodes in the bucket are exhausted. (Note that
  89    --  element equality is called here, not Equivalent_Elements. Set equality
  90    --  is the only operation in which element equality is used. Compare set
  91    --  equality to Equivalent_Sets, which does call Equivalent_Elements.)
  92 
  93    function Equivalent_Sets (Left, Right : Set) return Boolean;
  94    --  Similar to set equality, with the difference that the element in Left is
  95    --  compared to the elements in Right using the generic formal
  96    --  Equivalent_Elements operation instead of element equality.
  97 
  98    function To_Set (New_Item : Element_Type) return Set;
  99    --  Constructs a singleton set comprising New_Element. To_Set calls Hash to
 100    --  determine the bucket for New_Item.
 101 
 102    function Capacity (Container : Set) return Count_Type;
 103    --  Returns the current capacity of the set. Capacity is the maximum length
 104    --  before which rehashing in guaranteed not to occur.
 105 
 106    procedure Reserve_Capacity (Container : in out Set; Capacity : Count_Type);
 107    --  Adjusts the current capacity, by allocating a new buckets array. If the
 108    --  requested capacity is less than the current capacity, then the capacity
 109    --  is contracted (to a value not less than the current length). If the
 110    --  requested capacity is greater than the current capacity, then the
 111    --  capacity is expanded (to a value not less than what is requested). In
 112    --  either case, the nodes are rehashed from the old buckets array onto the
 113    --  new buckets array (Hash is called once for each existing element in
 114    --  order to compute the new index), and then the old buckets array is
 115    --  deallocated.
 116 
 117    function Length (Container : Set) return Count_Type;
 118    --  Returns the number of items in the set
 119 
 120    function Is_Empty (Container : Set) return Boolean;
 121    --  Equivalent to Length (Container) = 0
 122 
 123    procedure Clear (Container : in out Set);
 124    --  Removes all of the items from the set
 125 
 126    function Element (Position : Cursor) return Element_Type;
 127    --  Returns the element of the node designated by the cursor
 128 
 129    procedure Replace_Element
 130      (Container : in out Set;
 131       Position  : Cursor;
 132       New_Item  : Element_Type);
 133    --  If New_Item is equivalent (as determined by calling Equivalent_Elements)
 134    --  to the element of the node designated by Position, then New_Element is
 135    --  assigned to that element. Otherwise, it calls Hash to determine the
 136    --  bucket for New_Item. If the bucket is not empty, then it calls
 137    --  Equivalent_Elements for each node in that bucket to determine whether
 138    --  New_Item is equivalent to an element in that bucket. If
 139    --  Equivalent_Elements returns True then Program_Error is raised (because
 140    --  an element may appear only once in the set); otherwise, New_Item is
 141    --  assigned to the node designated by Position, and the node is moved to
 142    --  its new bucket.
 143 
 144    procedure Query_Element
 145      (Position : Cursor;
 146       Process  : not null access procedure (Element : Element_Type));
 147    --  Calls Process with the element (having only a constant view) of the node
 148    --  designated by the cursor.
 149 
 150    type Constant_Reference_Type
 151      (Element : not null access constant Element_Type) is private
 152         with Implicit_Dereference => Element;
 153 
 154    function Constant_Reference
 155      (Container : aliased Set;
 156       Position  : Cursor) return Constant_Reference_Type;
 157    pragma Inline (Constant_Reference);
 158 
 159    procedure Assign (Target : in out Set; Source : Set);
 160 
 161    function Copy (Source : Set; Capacity : Count_Type := 0) return Set;
 162 
 163    procedure Move (Target : in out Set; Source : in out Set);
 164    --  Clears Target (if it's not empty), and then moves (not copies) the
 165    --  buckets array and nodes from Source to Target.
 166 
 167    procedure Insert
 168      (Container : in out Set;
 169       New_Item  : Element_Type;
 170       Position  : out Cursor;
 171       Inserted  : out Boolean);
 172    --  Conditionally inserts New_Item into the set. If New_Item is already in
 173    --  the set, then Inserted returns False and Position designates the node
 174    --  containing the existing element (which is not modified). If New_Item is
 175    --  not already in the set, then Inserted returns True and Position
 176    --  designates the newly-inserted node containing New_Item. The search for
 177    --  an existing element works as follows. Hash is called to determine
 178    --  New_Item's bucket; if the bucket is non-empty, then Equivalent_Elements
 179    --  is called to compare New_Item to the element of each node in that
 180    --  bucket. If the bucket is empty, or there were no equivalent elements in
 181    --  the bucket, the search "fails" and the New_Item is inserted in the set
 182    --  (and Inserted returns True); otherwise, the search "succeeds" (and
 183    --  Inserted returns False).
 184 
 185    procedure Insert  (Container : in out Set; New_Item : Element_Type);
 186    --  Attempts to insert New_Item into the set, performing the usual insertion
 187    --  search (which involves calling both Hash and Equivalent_Elements); if
 188    --  the search succeeds (New_Item is equivalent to an element already in the
 189    --  set, and so was not inserted), then this operation raises
 190    --  Constraint_Error. (This version of Insert is similar to Replace, but
 191    --  having the opposite exception behavior. It is intended for use when you
 192    --  want to assert that the item is not already in the set.)
 193 
 194    procedure Include (Container : in out Set; New_Item : Element_Type);
 195    --  Attempts to insert New_Item into the set. If an element equivalent to
 196    --  New_Item is already in the set (the insertion search succeeded, and
 197    --  hence New_Item was not inserted), then the value of New_Item is assigned
 198    --  to the existing element. (This insertion operation only raises an
 199    --  exception if cursor tampering occurs. It is intended for use when you
 200    --  want to insert the item in the set, and you don't care whether an
 201    --  equivalent element is already present.)
 202 
 203    procedure Replace (Container : in out Set; New_Item : Element_Type);
 204    --  Searches for New_Item in the set; if the search fails (because an
 205    --  equivalent element was not in the set), then it raises
 206    --  Constraint_Error. Otherwise, the existing element is assigned the value
 207    --  New_Item. (This is similar to Insert, but with the opposite exception
 208    --  behavior. It is intended for use when you want to assert that the item
 209    --  is already in the set.)
 210 
 211    procedure Exclude (Container : in out Set; Item : Element_Type);
 212    --  Searches for Item in the set, and if found, removes its node from the
 213    --  set and then deallocates it. The search works as follows. The operation
 214    --  calls Hash to determine the item's bucket; if the bucket is not empty,
 215    --  it calls Equivalent_Elements to compare Item to the element of each node
 216    --  in the bucket. (This is the deletion analog of Include. It is intended
 217    --  for use when you want to remove the item from the set, but don't care
 218    --  whether the item is already in the set.)
 219 
 220    procedure Delete  (Container : in out Set; Item : Element_Type);
 221    --  Searches for Item in the set (which involves calling both Hash and
 222    --  Equivalent_Elements). If the search fails, then the operation raises
 223    --  Constraint_Error. Otherwise it removes the node from the set and then
 224    --  deallocates it. (This is the deletion analog of non-conditional
 225    --  Insert. It is intended for use when you want to assert that the item is
 226    --  already in the set.)
 227 
 228    procedure Delete (Container : in out Set; Position  : in out Cursor);
 229    --  Removes the node designated by Position from the set, and then
 230    --  deallocates the node. The operation calls Hash to determine the bucket,
 231    --  and then compares Position to each node in the bucket until there's a
 232    --  match (it does not call Equivalent_Elements).
 233 
 234    procedure Union (Target : in out Set; Source : Set);
 235    --  The operation first calls Reserve_Capacity if the current capacity is
 236    --  less than the sum of the lengths of Source and Target. It then iterates
 237    --  over the Source set, and conditionally inserts each element into Target.
 238 
 239    function Union (Left, Right : Set) return Set;
 240    --  The operation first copies the Left set to the result, and then iterates
 241    --  over the Right set to conditionally insert each element into the result.
 242 
 243    function "or" (Left, Right : Set) return Set renames Union;
 244 
 245    procedure Intersection (Target : in out Set; Source : Set);
 246    --  Iterates over the Target set (calling First and Next), calling Find to
 247    --  determine whether the element is in Source. If an equivalent element is
 248    --  not found in Source, the element is deleted from Target.
 249 
 250    function Intersection (Left, Right : Set) return Set;
 251    --  Iterates over the Left set, calling Find to determine whether the
 252    --  element is in Right. If an equivalent element is found, it is inserted
 253    --  into the result set.
 254 
 255    function "and" (Left, Right : Set) return Set renames Intersection;
 256 
 257    procedure Difference (Target : in out Set; Source : Set);
 258    --  Iterates over the Source (calling First and Next), calling Find to
 259    --  determine whether the element is in Target. If an equivalent element is
 260    --  found, it is deleted from Target.
 261 
 262    function Difference (Left, Right : Set) return Set;
 263    --  Iterates over the Left set, calling Find to determine whether the
 264    --  element is in the Right set. If an equivalent element is not found, the
 265    --  element is inserted into the result set.
 266 
 267    function "-" (Left, Right : Set) return Set renames Difference;
 268 
 269    procedure Symmetric_Difference (Target : in out Set; Source : Set);
 270    --  The operation first calls Reserve_Capacity if the current capacity is
 271    --  less than the sum of the lengths of Source and Target. It then iterates
 272    --  over the Source set, searching for the element in Target (calling Hash
 273    --  and Equivalent_Elements). If an equivalent element is found, it is
 274    --  removed from Target; otherwise it is inserted into Target.
 275 
 276    function Symmetric_Difference (Left, Right : Set) return Set;
 277    --  The operation first iterates over the Left set. It calls Find to
 278    --  determine whether the element is in the Right set. If no equivalent
 279    --  element is found, the element from Left is inserted into the result. The
 280    --  operation then iterates over the Right set, to determine whether the
 281    --  element is in the Left set. If no equivalent element is found, the Right
 282    --  element is inserted into the result.
 283 
 284    function "xor" (Left, Right : Set) return Set
 285      renames Symmetric_Difference;
 286 
 287    function Overlap (Left, Right : Set) return Boolean;
 288    --  Iterates over the Left set (calling First and Next), calling Find to
 289    --  determine whether the element is in the Right set. If an equivalent
 290    --  element is found, the operation immediately returns True. The operation
 291    --  returns False if the iteration over Left terminates without finding any
 292    --  equivalent element in Right.
 293 
 294    function Is_Subset (Subset : Set; Of_Set : Set) return Boolean;
 295    --  Iterates over Subset (calling First and Next), calling Find to determine
 296    --  whether the element is in Of_Set. If no equivalent element is found in
 297    --  Of_Set, the operation immediately returns False. The operation returns
 298    --  True if the iteration over Subset terminates without finding an element
 299    --  not in Of_Set (that is, every element in Subset is equivalent to an
 300    --  element in Of_Set).
 301 
 302    function First (Container : Set) return Cursor;
 303    --  Returns a cursor that designates the first non-empty bucket, by
 304    --  searching from the beginning of the buckets array.
 305 
 306    function Next (Position : Cursor) return Cursor;
 307    --  Returns a cursor that designates the node that follows the current one
 308    --  designated by Position. If Position designates the last node in its
 309    --  bucket, the operation calls Hash to compute the index of this bucket,
 310    --  and searches the buckets array for the first non-empty bucket, starting
 311    --  from that index; otherwise, it simply follows the link to the next node
 312    --  in the same bucket.
 313 
 314    procedure Next (Position : in out Cursor);
 315    --  Equivalent to Position := Next (Position)
 316 
 317    function Find (Container : Set; Item : Element_Type) return Cursor;
 318    --  Searches for Item in the set. Find calls Hash to determine the item's
 319    --  bucket; if the bucket is not empty, it calls Equivalent_Elements to
 320    --  compare Item to each element in the bucket. If the search succeeds, Find
 321    --  returns a cursor designating the node containing the equivalent element;
 322    --  otherwise, it returns No_Element.
 323 
 324    function Contains (Container : Set; Item : Element_Type) return Boolean;
 325    --  Equivalent to Find (Container, Item) /= No_Element
 326 
 327    function Equivalent_Elements (Left, Right : Cursor) return Boolean;
 328    --  Returns the result of calling Equivalent_Elements with the elements of
 329    --  the nodes designated by cursors Left and Right.
 330 
 331    function Equivalent_Elements
 332      (Left  : Cursor;
 333       Right : Element_Type) return Boolean;
 334    --  Returns the result of calling Equivalent_Elements with element of the
 335    --  node designated by Left and element Right.
 336 
 337    function Equivalent_Elements
 338      (Left  : Element_Type;
 339       Right : Cursor) return Boolean;
 340    --  Returns the result of calling Equivalent_Elements with element Left and
 341    --  the element of the node designated by Right.
 342 
 343    procedure Iterate
 344      (Container : Set;
 345       Process   : not null access procedure (Position : Cursor));
 346    --  Calls Process for each node in the set
 347 
 348    function Iterate (Container : Set)
 349      return Set_Iterator_Interfaces.Forward_Iterator'Class;
 350 
 351    generic
 352       type Key_Type (<>) is private;
 353 
 354       with function Key (Element : Element_Type) return Key_Type;
 355 
 356       with function Hash (Key : Key_Type) return Hash_Type;
 357 
 358       with function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
 359 
 360    package Generic_Keys is
 361 
 362       function Key (Position : Cursor) return Key_Type;
 363       --  Applies generic formal operation Key to the element of the node
 364       --  designated by Position.
 365 
 366       function Element (Container : Set; Key : Key_Type) return Element_Type;
 367       --  Searches (as per the key-based Find) for the node containing Key, and
 368       --  returns the associated element.
 369 
 370       procedure Replace
 371         (Container : in out Set;
 372          Key       : Key_Type;
 373          New_Item  : Element_Type);
 374       --  Searches (as per the key-based Find) for the node containing Key, and
 375       --  then replaces the element of that node (as per the element-based
 376       --  Replace_Element).
 377 
 378       procedure Exclude (Container : in out Set; Key : Key_Type);
 379       --  Searches for Key in the set, and if found, removes its node from the
 380       --  set and then deallocates it. The search works by first calling Hash
 381       --  (on Key) to determine the bucket; if the bucket is not empty, it
 382       --  calls Equivalent_Keys to compare parameter Key to the value of
 383       --  generic formal operation Key applied to element of each node in the
 384       --  bucket.
 385 
 386       procedure Delete (Container : in out Set; Key : Key_Type);
 387       --  Deletes the node containing Key as per Exclude, with the difference
 388       --  that Constraint_Error is raised if Key is not found.
 389 
 390       function Find (Container : Set; Key : Key_Type) return Cursor;
 391       --  Searches for the node containing Key, and returns a cursor
 392       --  designating the node. The search works by first calling Hash (on Key)
 393       --  to determine the bucket. If the bucket is not empty, the search
 394       --  compares Key to the element of each node in the bucket, and returns
 395       --  the matching node. The comparison itself works by applying the
 396       --  generic formal Key operation to the element of the node, and then
 397       --  calling generic formal operation Equivalent_Keys.
 398 
 399       function Contains (Container : Set; Key : Key_Type) return Boolean;
 400       --  Equivalent to Find (Container, Key) /= No_Element
 401 
 402       procedure Update_Element_Preserving_Key
 403         (Container : in out Set;
 404          Position  : Cursor;
 405          Process   : not null access
 406                        procedure (Element : in out Element_Type));
 407       --  Calls Process with the element of the node designated by Position,
 408       --  but with the restriction that the key-value of the element is not
 409       --  modified. The operation first makes a copy of the value returned by
 410       --  applying generic formal operation Key on the element of the node, and
 411       --  then calls Process with the element. The operation verifies that the
 412       --  key-part has not been modified by calling generic formal operation
 413       --  Equivalent_Keys to compare the saved key-value to the value returned
 414       --  by applying generic formal operation Key to the post-Process value of
 415       --  element. If the key values compare equal then the operation
 416       --  completes. Otherwise, the node is removed from the map and
 417       --  Program_Error is raised.
 418 
 419       type Reference_Type (Element : not null access Element_Type) is private
 420         with Implicit_Dereference => Element;
 421 
 422       function Reference_Preserving_Key
 423         (Container : aliased in out Set;
 424          Position  : Cursor) return Reference_Type;
 425 
 426       function Constant_Reference
 427         (Container : aliased Set;
 428          Key       : Key_Type) return Constant_Reference_Type;
 429 
 430       function Reference_Preserving_Key
 431         (Container : aliased in out Set;
 432          Key       : Key_Type) return Reference_Type;
 433 
 434    private
 435       type Set_Access is access all Set;
 436       for Set_Access'Storage_Size use 0;
 437 
 438       package Impl is new Helpers.Generic_Implementation;
 439 
 440       type Reference_Control_Type is
 441         new Impl.Reference_Control_Type with
 442       record
 443          Container : Set_Access;
 444          Index     : Hash_Type;
 445          Old_Pos   : Cursor;
 446          Old_Hash  : Hash_Type;
 447       end record;
 448 
 449       overriding procedure Finalize (Control : in out Reference_Control_Type);
 450       pragma Inline (Finalize);
 451 
 452       type Reference_Type (Element : not null access Element_Type) is record
 453          Control : Reference_Control_Type :=
 454            raise Program_Error with "uninitialized reference";
 455          --  The RM says, "The default initialization of an object of
 456          --  type Constant_Reference_Type or Reference_Type propagates
 457          --  Program_Error."
 458       end record;
 459 
 460       use Ada.Streams;
 461 
 462       procedure Read
 463         (Stream : not null access Root_Stream_Type'Class;
 464          Item   : out Reference_Type);
 465 
 466       for Reference_Type'Read use Read;
 467 
 468       procedure Write
 469         (Stream : not null access Root_Stream_Type'Class;
 470          Item   : Reference_Type);
 471 
 472       for Reference_Type'Write use Write;
 473    end Generic_Keys;
 474 
 475 private
 476    pragma Inline (Next);
 477 
 478    type Node_Type;
 479    type Node_Access is access Node_Type;
 480 
 481    type Element_Access is access all Element_Type;
 482 
 483    type Node_Type is limited record
 484       Element : Element_Access;
 485       Next    : Node_Access;
 486    end record;
 487 
 488    package HT_Types is
 489      new Hash_Tables.Generic_Hash_Table_Types (Node_Type, Node_Access);
 490 
 491    type Set is new Ada.Finalization.Controlled with record
 492       HT : HT_Types.Hash_Table_Type;
 493    end record;
 494 
 495    overriding procedure Adjust (Container : in out Set);
 496 
 497    overriding procedure Finalize (Container : in out Set);
 498 
 499    use HT_Types, HT_Types.Implementation;
 500    use Ada.Finalization;
 501    use Ada.Streams;
 502 
 503    procedure Write
 504      (Stream    : not null access Root_Stream_Type'Class;
 505       Container : Set);
 506 
 507    for Set'Write use Write;
 508 
 509    procedure Read
 510      (Stream    : not null access Root_Stream_Type'Class;
 511       Container : out Set);
 512 
 513    for Set'Read use Read;
 514 
 515    type Set_Access is access all Set;
 516    for Set_Access'Storage_Size use 0;
 517 
 518    type Cursor is record
 519       Container : Set_Access;
 520       Node      : Node_Access;
 521    end record;
 522 
 523    procedure Write
 524      (Stream : not null access Root_Stream_Type'Class;
 525       Item   : Cursor);
 526 
 527    for Cursor'Write use Write;
 528 
 529    procedure Read
 530      (Stream : not null access Root_Stream_Type'Class;
 531       Item   : out Cursor);
 532 
 533    for Cursor'Read use Read;
 534 
 535    subtype Reference_Control_Type is Implementation.Reference_Control_Type;
 536    --  It is necessary to rename this here, so that the compiler can find it
 537 
 538    type Constant_Reference_Type
 539      (Element : not null access constant Element_Type) is
 540       record
 541          Control : Reference_Control_Type :=
 542            raise Program_Error with "uninitialized reference";
 543          --  The RM says, "The default initialization of an object of
 544          --  type Constant_Reference_Type or Reference_Type propagates
 545          --  Program_Error."
 546       end record;
 547 
 548    procedure Read
 549      (Stream : not null access Root_Stream_Type'Class;
 550       Item   : out Constant_Reference_Type);
 551 
 552    for Constant_Reference_Type'Read use Read;
 553 
 554    procedure Write
 555      (Stream : not null access Root_Stream_Type'Class;
 556       Item   : Constant_Reference_Type);
 557 
 558    for Constant_Reference_Type'Write use Write;
 559 
 560    --  Three operations are used to optimize in the expansion of "for ... of"
 561    --  loops: the Next(Cursor) procedure in the visible part, and the following
 562    --  Pseudo_Reference and Get_Element_Access functions. See Sem_Ch5 for
 563    --  details.
 564 
 565    function Pseudo_Reference
 566      (Container : aliased Set'Class) return Reference_Control_Type;
 567    pragma Inline (Pseudo_Reference);
 568    --  Creates an object of type Reference_Control_Type pointing to the
 569    --  container, and increments the Lock. Finalization of this object will
 570    --  decrement the Lock.
 571 
 572    function Get_Element_Access
 573      (Position : Cursor) return not null Element_Access;
 574    --  Returns a pointer to the element designated by Position.
 575 
 576    Empty_Set : constant Set := (Controlled with others => <>);
 577 
 578    No_Element : constant Cursor := (Container => null, Node => null);
 579 
 580    type Iterator is new Limited_Controlled and
 581      Set_Iterator_Interfaces.Forward_Iterator with
 582    record
 583       Container : Set_Access;
 584    end record
 585      with Disable_Controlled => not T_Check;
 586 
 587    overriding procedure Finalize (Object : in out Iterator);
 588 
 589    overriding function First (Object : Iterator) return Cursor;
 590 
 591    overriding function Next
 592      (Object   : Iterator;
 593       Position : Cursor) return Cursor;
 594 
 595 end Ada.Containers.Indefinite_Hashed_Sets;