@@ -36,249 +36,8 @@ Controlled Types
36
36
37
37
.. container :: PRELUDE END
38
38
39
- ==============
40
- Introduction
41
- ==============
42
-
43
- -------------------------
44
- Constructor / Destructor
45
- -------------------------
46
-
47
- * Possible to specify behavior of object initialization, finalization, and assignment
48
-
49
- - Based on type definition
50
- - Type must derive from `Controlled ` or `Limited_Controlled ` in package `Ada.Finalization `
51
-
52
- * This derived type is called a *controlled type *
53
-
54
- - User may override any or all subprograms in `Ada.Finalization `
55
- - Default implementation is a null body
56
-
57
- ==================
58
- Ada.Finalization
59
- ==================
60
-
61
- ---------------
62
- Package Spec
63
- ---------------
64
-
65
- .. code :: Ada
66
-
67
- package Ada.Finalization is
68
-
69
- type Controlled is abstract tagged private;
70
- procedure Initialize (Object : in out Controlled)
71
- is null;
72
- procedure Adjust (Object : in out Controlled)
73
- is null;
74
- procedure Finalize (Object : in out Controlled)
75
- is null;
76
-
77
- type Limited_Controlled is abstract tagged limited private;
78
- procedure Initialize (Object : in out Limited_Controlled)
79
- is null;
80
- procedure Finalize (Object : in out Limited_Controlled)
81
- is null;
82
-
83
- private
84
- -- implementation defined
85
- end Ada.Finalization;
86
-
87
- -------
88
- Uses
89
- -------
90
-
91
- * Prevent "resource leak"
92
-
93
- - Logic centralized in service rather than distributed across clients
94
-
95
- * Examples: heap reclamation, "mutex" unlocking
96
- * User-defined assignment
97
-
98
- ----------------
99
- Initialization
100
- ----------------
101
-
102
- * Subprogram `Initialize ` invoked after object created
103
-
104
- - Either by object declaration or allocator
105
- - Only if no explicit initialization expression
106
-
107
- * Often default initialization expressions on record components are sufficient
108
-
109
- - No need for an explicit call to `Initialize `
110
-
111
- * Similar to C++ constructor
112
-
113
- ----------------
114
- Finalization
115
- ----------------
116
-
117
- * Subprogram `Finalize ` invoked just before object is destroyed
118
-
119
- - Leaving the scope of a declared object
120
- - Unchecked deallocation of an allocated object
121
-
122
- * Similar to C++ destructor
123
-
124
- ------------
125
- Assignment
126
- ------------
127
-
128
- * Subprogram `Adjust ` invoked as part of an assignment operation
129
- * Assignment statement `Target := Source; ` is basically:
130
-
131
- - `Finalize (Target) `
132
- - Copy Source to Target
133
- - `Adjust (Target) `
134
- - *Actual rules are more complicated, e.g. to allow cases where Target and Source are the same object *
135
-
136
- * Typical situations where objects are access values
137
-
138
- - `Finalize ` does unchecked deallocation or decrements a reference count
139
- - The copy step copies the access value
140
- - `Adjust ` either clones a "deep copy" of the referenced object or increments a reference count
141
-
142
- =========
143
- Example
144
- =========
145
-
146
- ----------------------------------
147
- Unbounded String Via Access Type
148
- ----------------------------------
149
-
150
- * Type contains a pointer to a string type
151
- * We want the provider to allocate and free memory "safely"
152
-
153
- - No sharing
154
- - `Adjust ` allocates referenced String
155
- - `Finalize ` frees the referenced String
156
- - Assignment deallocates target string and assigns copy of source string to target string
157
-
158
- ------------------------
159
- Unbounded String Usage
160
- ------------------------
161
-
162
- .. code :: Ada
163
-
164
- with Unbounded_String_Pkg; use Unbounded_String_Pkg;
165
- procedure Test is
166
- U1 : Ustring_T;
167
- begin
168
- U1 := To_Ustring_T ("Hello");
169
- declare
170
- U2 : Ustring_T;
171
- begin
172
- U2 := To_Ustring_T ("Goodbye");
173
- U1 := U2; -- Reclaims U1 memory
174
- end; -- Reclaims U2 memory
175
- end Test; -- Reclaims U1 memory
176
-
177
- -----------------------------
178
- Unbounded String Definition
179
- -----------------------------
180
-
181
- .. code :: Ada
182
-
183
- with Ada.Finalization; use Ada.Finalization;
184
- package Unbounded_String_Pkg is
185
- -- Implement unbounded strings
186
- type Ustring_T is private;
187
- function "=" (L, R : Ustring_T) return Boolean;
188
- function To_Ustring_T (Item : String) return Ustring_T;
189
- function To_String (Item : Ustring_T) return String;
190
- function Length (Item : Ustring_T) return Natural;
191
- function "&" (L, R : Ustring_T) return Ustring_T;
192
- private
193
- type String_Ref is access String;
194
- type Ustring_T is new Controlled with record
195
- Ref : String_Ref := new String (1 .. 0);
196
- end record;
197
- procedure Finalize (Object : in out Ustring_T);
198
- procedure Adjust (Object : in out Ustring_T);
199
- end Unbounded_String_Pkg;
200
-
201
- ---------------------------------
202
- Unbounded String Implementation
203
- ---------------------------------
204
-
205
- .. code :: Ada
206
-
207
- with Ada.Unchecked_Deallocation;
208
- package body Unbounded_String_Pkg is
209
- procedure Free_String is new Ada.Unchecked_Deallocation
210
- (String, String_Ref);
211
-
212
- function "=" (L, R : Ustring_T) return Boolean is
213
- (L.Ref.all = R.Ref.all);
214
-
215
- function To_Ustring_T (Item : String) return Ustring_T is
216
- (Controlled with Ref => new String'(Item));
217
-
218
- function To_String (Item : Ustring_T) return String is
219
- (Item.Ref.all);
220
-
221
- function Length (Item : Ustring_T) return Natural is
222
- (Item.Ref.all'Length);
223
-
224
- function "&" (L, R : Ustring_T) return Ustring_T is
225
- (Controlled with Ref => new String'(L.Ref.all & R.Ref.all);
226
-
227
- procedure Finalize (Object : in out Ustring_T) is
228
- begin
229
- Free_String (Object.Ref);
230
- end Finalize;
231
-
232
- procedure Adjust (Object : in out Ustring_T) is
233
- begin
234
- Object.Ref := new String'(Object.Ref.all);
235
- end Adjust;
236
- end Unbounded_String_Pkg;
237
-
238
- ------------------
239
- Finalizable Aspect
240
- ------------------
241
-
242
- * Uses the GNAT-specific :ada: `with Finalizable ` aspect
243
-
244
- .. code :: Ada
245
-
246
- type Ctrl is record
247
- Id : Natural := 0;
248
- end record
249
- with Finalizable => (Initialize => Initialize,
250
- Adjust => Adjust,
251
- Finalize => Finalize,
252
- Relaxed_Finalization => True);
253
-
254
- procedure Adjust (Obj : in out Ctrl);
255
- procedure Finalize (Obj : in out Ctrl);
256
- procedure Initialize (Obj : in out Ctrl);
257
-
258
- * :ada: `Initialize `, :ada: `Adjust ` same definition as previously
259
- * :ada: `Finalize ` has the :ada: `No_Raise ` aspect: it cannot raise exceptions
260
- * :ada: `Relaxed_Finalization `
261
-
262
- * Performance on-par with C++'s destructor
263
- * No automatic finalization of **heap-allocated ** objects
264
-
265
- ========
266
- Lab
267
- ========
268
-
39
+ .. include :: 260_controlled_types/01-introduction.rst
40
+ .. include :: 260_controlled_types/02-ada_finalization.rst
41
+ .. include :: 260_controlled_types/03-example.rst
269
42
.. include :: labs/260_controlled_types.lab.rst
270
-
271
- =========
272
- Summary
273
- =========
274
-
275
- ---------
276
- Summary
277
- ---------
278
-
279
- * Controlled types allow access to object construction, assignment, destruction
280
- * `Ada.Finalization ` can be expensive to use
281
-
282
- - Other mechanisms may be more efficient
283
-
284
- * But require more rigor in usage
43
+ .. include :: 260_controlled_types/99-summary.rst
0 commit comments