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 | ---------------------------------------------------------------------------- |
18 | pragma License (Modified_Gpl); |
19 | pragma Ada_2022; |
20 | |
21 | with Ada.Finalization; |
22 | with AdaCL.Limited_Base; |
23 | with AdaCL.Pointer.Element; |
24 | with Ada.Strings; |
25 | with Ada.Strings.Text_Buffers; |
26 | with 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. |
43 | generic |
44 | type Element_Type (<>) is abstract limited new Element.Object_Interface with private; |
45 | package 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 | |
105 | private |
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 | |
139 | end 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 : |