adacl_5.15.1_e7c1515b/src/adacl-pointer-holder.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
------------------------------------------------------------------------------
--: Copyright © 2003 … 2023 Martin Krischik «krischik@users.sourceforge.net»
------------------------------------------------------------------------------
--: This library is free software; you can redistribute it and/or modify it
--: under the terms of the GNU Library General Public License as published by
--: the Free Software Foundation; either version 2 of the License, 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 Library General Public
--: License for more details.
--:
--: You should have received a copy of the GNU Library General Public License
--: along with this library; if not, write to the Free Software Foundation,
--: Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
----------------------------------------------------------------------------
pragma License (Modified_Gpl);
pragma Ada_2022;

with Ada.Finalization;
with AdaCL.Limited_Base;
with AdaCL.Pointer.Element;

---
--  @summary
--  AdaCL Reference counted smart pointer.
--
--  @description
--  Element and Holder: A reference counted smart pointer for tagged types where the reference is keept inside the
--  tagged type. This is sligtly faster, uses less memory and is more reliable. However it can only be uses for
--  limited tagged types.
--
--  Holder class for the actual element
generic
   ---
   --  Type for which we want to supply a reference counter. since, in Ada one can not overload the ":=" operator the
   --  type need to be limited so the counter is not damaged by assignment.
   --
   --  Mind you, in C++ I almost allways make the operator = private in Reference counted classes as well.
   type Element_Type (<>) is abstract limited new Element.Object_Interface with private;

   ---
   --  an access type to match the element type.
   type Element_Class is access Element_Type'Class;

package AdaCL.Pointer.Holder is

   ---
   --  Parametrized Class AdaCL.Pointer.Reference : Object
   --
   --  Access for Reference Counted Instances.
   --
   --  Most smart pointer library's keep the counter inside the smart pointer. While this implementations allows the
   --  use with existing classes it is also very error prune: The counted instance always need to be handled with the
   --  smart pointer and is never allowed to be used any other way.
   --
   --  I prefer to count inside the instance itself. This keeps the pointer far more reliable.
   type Object is new Ada.Finalization.Controlled with private;

   ---
   --  Creates a new smart pointer from normal pointer.
   --
   --  Pointer to reference counted object
   function Create (Referent : in Element_Class := null) return Object;

   ---
   --  Checks if a pointers is set
   --
   --: @param This    Object itself.
   --: @return        true when pointer is not null
   function Exist (This : in Object) return Boolean;

   ---
   --  Returns the Pointer to the counted Object.
   --
   --  Object itself.
   function Get (This : in Object) return Element_Class;

   ---
   --  Returns the Pointer to the counted Object as base.
   --
   --  Object itself.
   function Get_Base (This : in Object) return AdaCL.Limited_Base.Object_Class;

   ---
   --  Set a new Pointer. This decreases the counter for the previous instance and increases the Pointer to the newly
   --  set instance.
   --
   --: @param This      Object itself.
   --: @param Referent  The Object. Set to null to clean the pointer.
   procedure Reset (This : in out Object; Referent : Element_Class := null);

   ---
   --  Set a new Pointer. This decreases the counter for the previous instance and increases the Pointer to the newly
   --  set instance.
   --
   --: @param This       Object itself.
   --: @param Reference  The Object. Set to null to clean the pointer.
   procedure Reset (This : in out Object; Reference : Object);

private

   ---
   --  A Pointer to an counted Object.
   --
   --: @field Referent class instance referenced.
   type Object is new Ada.Finalization.Controlled with record
      Referent : Element_Class := null;
   end record;

   procedure Initialize (Object : in out Ada.Finalization.Controlled) renames Ada.Finalization.Initialize;

   ---
   --  When asjusting we need to increase the counter.
   --
   --: @param This  Object itself.
   overriding procedure Adjust (This : in out Object);

   ---
   --  When finalizing we need to decrease the counter. When the counter reaches 0 we delete the insanz.
   --
   --: @param This  Object itself.
   overriding procedure Finalize (This : in out Object);

   ---
   --  Returns the Pointer to the conted Object.
   --
   --  Object itself.
   function Get_Base (This : in Object) return AdaCL.Limited_Base.Object_Class is
      (AdaCL.Limited_Base.Object_Class (This.Get));

end AdaCL.Pointer.Holder;

---------------------------------------------------------------- {{{ ----------
--: vim: set textwidth=0 nowrap tabstop=8 shiftwidth=3 softtabstop=3 expandtab :
--: vim: set filetype=ada fileencoding=utf-8 fileformat=unix foldmethod=expr :
--: vim: set spell spelllang=en_gb :