adacl-pointer-holder.ads

1------------------------------------------------------------------------------
2--: Copyright © 2003 … 2023 Martin Krischik «krischik@users.sourceforge.net»
3------------------------------------------------------------------------------
4--: This library is free software; you can redistribute it and/or modify it
5--: under the terms of the GNU Library General Public License as published by
6--: the Free Software Foundation; either version 2 of the License, or (at your
7--: option) any later version.
8--:
9--: This library is distributed in the hope that it will be useful, but
10--: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11--: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12--: License for more details.
13--:
14--: You should have received a copy of the GNU Library General Public License
15--: along with this library; if not, write to the Free Software Foundation,
16--: Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17----------------------------------------------------------------------------
18pragma License (Modified_Gpl);
19pragma Ada_2022;
20
21with Ada.Finalization;
22with AdaCL.Limited_Base;
23with AdaCL.Pointer.Element;
24with Ada.Strings;
25with Ada.Strings.Text_Buffers;
26with AdaCL.Base;
27
28---
29-- @summary
30-- AdaCL Reference counted smart pointer.
31--
32-- @description
33-- Element and Holder: A reference counted smart pointer for tagged types where the reference count is kept inside
34-- the tagged type. This is slightly faster, uses less memory and is more reliable. However it can only be uses for
35-- limited tagged types.
36--
37-- Holder class for the actual element
38--
39--: @formal Element_Type Type for which we want to supply a reference counter. Since, in Ada one can not overload the
40-- ":=" operator the type need to be limited so the counter is not damaged by assignment.
41-- Mind you, in C++ I almost always make the operator = private in Reference counted classes as
42-- well.
43generic
44 type Element_Type (<>) is abstract limited new Element.Object_Interface with private;
45package AdaCL.Pointer.Holder is
46
47 ---
48 -- an access type to match the element type.
49 --
50 type Element_Class is access Element_Type'Class;
51
52 ---
53 -- Parametrized Class AdaCL.Pointer.Reference : Object
54 --
55 -- Access for Reference Counted Instances.
56 --
57 -- Most smart pointer library's keep the counter inside the smart pointer. While this implementations allows the
58 -- use with existing classes it is also very error prune: The counted instance always need to be handled with the
59 -- smart pointer and is never allowed to be used any other way.
60 --
61 -- I prefer to count inside the instance itself. This keeps the pointer far more reliable.
62 type Object is new AdaCL.Base.Object with private;
63
64 ---
65 -- Creates a new smart pointer from normal pointer.
66 --
67 -- Pointer to reference counted object
68 function Create (Referent : in Element_Class := null) return Object;
69
70 ---
71 -- Checks if a pointers is set
72 --
73 --: @param This Object itself.
74 --: @return true when pointer is not null
75 function Exist (This : in Object) return Boolean;
76
77 ---
78 -- Returns the Pointer to the counted Object.
79 --
80 -- Object itself.
81 function Get (This : in Object) return Element_Class;
82
83 ---
84 -- Returns the Pointer to the counted Object as base.
85 --
86 -- Object itself.
87 function Get_Base (This : in Object) return AdaCL.Limited_Base.Object_Class;
88
89 ---
90 -- Set a new Pointer. This decreases the counter for the previous instance and increases the Pointer to the newly
91 -- set instance.
92 --
93 --: @param This Object itself.
94 --: @param Referent The Object. Set to null to clean the pointer.
95 procedure Reset (This : in out Object; Referent : Element_Class := null);
96
97 ---
98 -- Set a new Pointer. This decreases the counter for the previous instance and increases the Pointer to the newly
99 -- set instance.
100 --
101 --: @param This Object itself.
102 --: @param Reference The Object. Set to null to clean the pointer.
103 procedure Reset (This : in out Object; Reference : Object);
104
105private
106
107 ---
108 -- A Pointer to an counted Object.
109 --
110 --: @field Referent class instance referenced.
111 type Object is new AdaCL.Base.Object with record
112 Referent : Element_Class := null;
113 end record with
114 Put_Image => Object_Image;
115
116 procedure Object_Image (Output : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; This : Object);
117
118 procedure Initialize (Object : in out Ada.Finalization.Controlled) renames Ada.Finalization.Initialize;
119
120 ---
121 -- When adjusting we need to increase the counter.
122 --
123 --: @param This Object itself.
124 overriding procedure Adjust (This : in out Object);
125
126 ---
127 -- When finalizing we need to decrease the counter. When the counter reaches 0 we delete the insanz.
128 --
129 --: @param This Object itself.
130 overriding procedure Finalize (This : in out Object);
131
132 ---
133 -- Returns the Pointer to the counted Object.
134 --
135 -- Object itself.
136 function Get_Base (This : in Object) return AdaCL.Limited_Base.Object_Class is
137 (AdaCL.Limited_Base.Object_Class (This.Get));
138
139end AdaCL.Pointer.Holder;
140
141---------------------------------------------------------------- {{{ ----------
142--: vim: set textwidth=0 nowrap tabstop=8 shiftwidth=3 softtabstop=3 expandtab :
143--: vim: set filetype=ada fileencoding=utf-8 fileformat=unix foldmethod=expr :
144--: vim: set spell spelllang=en_gb :