acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
cfref.h
1//
2// cfref.h
3// acme
4//
5// Created by Camilo Sasuke Thomas Borregaard Sørensen on 2026-06-18 07:45.
6// Copyright © 2026 ca2 Software Development. All rights reserved.
7// <3ThomasBorregaardSørensen!! Mummi!! Bilbo!!
8//
9#pragma once
10
11
12
13template < typename CFREF >
14inline void cfref_default_release(CFREF cfref)
15{
16
17 ::CFRelease(cfref);
18
19}
20
22{
23public:
24
25 bool m_bOwnReference = false;
26
27 virtual~ref_base(){}
28
29 virtual void release_base() = 0;
30
31};
32class ref_array;
33
34template < typename REF_BASE >
35class ref :
36virtual public ref_base
37{
38public:
39
40
41 using REF_BASE_TYPE = typename REF_BASE::REF_BASE_TYPE;
42
43protected:
44 REF_BASE *m_prefbase;
45public:
46
47 ref()
48 {
49
50 m_prefbase=nullptr;
51
52 }
53
54
55 ref(ref_array & refa, REF_BASE_TYPE refbasetype);
56
57protected:
58 ref(ref * pref):
59 m_prefbase(new REF_BASE(pref->m_prefbase->operator REF_BASE_TYPE()))
60 {
61
62 m_bOwnReference = pref->m_bOwnReference;
63
64 pref->m_bOwnReference= false;
65
66 }
67public:
68
69 ~ref()
70 {
71
72 full_release();
73
74 }
75
76
77 ref & operator = (const ref & r)
78 {
79
80 if(&r != this && m_prefbase != r.m_prefbase && (!m_prefbase || !r.m_prefbase ||
81 m_prefbase->operator REF_BASE_TYPE()
82 != r.m_prefbase->operator REF_BASE_TYPE()))
83 {
84 this->full_release();
85 m_prefbase = new REF_BASE(r.m_prefbase->operator REF_BASE_TYPE());
86 m_bOwnReference = false;
87 }
88 return *this;
89 }
90 ref & operator = (REF_BASE_TYPE refbasetype)
91 {
92 this->full_release();
93 m_prefbase = new REF_BASE(refbasetype);
94 m_bOwnReference = true;
95 return *this;
96 }
97
98// cfref(CFREF cfref)
99// {
100//
101// m_cfref = cfref;
102//
103// }
104// cfref(ref_array & refa, CFREF cfref)
105// {
106//
107// m_cfref = cfref;
108//
109// refa << *this;
110//
111// }
112//
113//
114// ~cfref()
115// {
116//
117// }
118//
119 bool operator!() const {return m_prefbase == nullptr;}
120
121 ref * clone()
122 {
123
124 return new ref(this);
125 }
126// void release() override
127// {
128//
129// if(!m_cfref)
130// {
131//
132// return;
133//
134// }
135//
136// auto cfref = m_cfref;
137//
138// m_cfref = nullptr;
139//
140// t_functionRelease(cfref);
141//
142// }
143
144//
145// operator CFREF()
146// {
147//
148// return m_cfref;
149//
150// }
151//
152//
153
154 void release_base()
155 {
156
157 if(m_prefbase)
158 {
159
160 if(m_bOwnReference)
161 {
162
163 m_bOwnReference = false;
164
165 m_prefbase->release();
166
167 }
168
169 }
170
171 }
172
173 void full_release()
174 {
175
176 if(m_prefbase)
177 {
178
179 if(m_bOwnReference)
180 {
181
182 m_bOwnReference = false;
183
184 m_prefbase->release();
185
186 }
187
188 delete m_prefbase;
189
190 m_prefbase = nullptr;
191
192 }
193
194 }
195
196 void set(ref_array & refa, REF_BASE_TYPE refbasetype);
197 operator REF_BASE_TYPE()
198 {
199 if(::is_null(m_prefbase))
200 {
201
202 return nullptr;
203
204 }
205 return m_prefbase->operator REF_BASE_TYPE();
206
207 }
208
209};
210
211class ref_array
212{
213protected:
214 ::array_base<ref_base * > m_refbaseptra;
215public:
216 bool m_bAutoRelease;
217 ref_array(bool bAutoRelease = true):
218 m_bAutoRelease(bAutoRelease)
219 {
220
221 }
222 ~ref_array()
223 {
224 if(m_bAutoRelease)
225 {
226 release();
227 }
228 }
229 void release()
230 {
231 for(auto prefbase : m_refbaseptra)
232 {
233
234 if(::is_set(prefbase))
235 {
236
237 try
238 {
239
240 prefbase->release_base();
241
242 }
243 catch (...)
244 {
245
246 }
247
248 delete prefbase;
249
250 }
251
252 }
253 m_refbaseptra.clear();
254 }
255
256 template < typename REF >
257 void add(REF * pref)
258 {
259 m_refbaseptra.add(pref->clone());
260 }
261
262};
263template < typename REF_BASE >
264ref<REF_BASE>::ref(ref_array & refa, REF_BASE_TYPE refbasetype)
265{
266 m_prefbase =new REF_BASE(refbasetype);
267 m_bOwnReference = true;
268 refa.add(this);
269
270
271}
272template < typename REF_BASE >
273void ref<REF_BASE>::set(ref_array & refa, REF_BASE_TYPE refbasetype)
274{
275 full_release();
276 m_prefbase =new REF_BASE(refbasetype);
277 m_bOwnReference = true;
278 refa.add(this);
279
280
281}
282template < typename CFREF = CFTypeRef, void (* t_functionRelease)(CFREF) = ::cfref_default_release < CFREF > >
283class cfref_base
284{
285public:
286
287 using REF_BASE_TYPE = CFREF;
288
289 CFREF m_cfref;
290
291
292 cfref_base()
293 {
294
295 m_cfref = nullptr;
296
297 }
298
299 cfref_base(CFREF cfref):
300 m_cfref(cfref)
301 {
302
303
304 }
305
306 void release()
307 {
308
309 if(m_cfref)
310 {
311
312 auto cfref = m_cfref;
313
314 m_cfref=nullptr;
315
316 t_functionRelease(cfref);
317 }
318
319 }
320
321
322 operator REF_BASE_TYPE() {return m_cfref;}
323
324};
325
326
327template < typename CFREF = CFTypeRef, void (* t_functionRelease)(CFREF) = ::cfref_default_release < CFREF > >
328class cfref :
329public ::ref < cfref_base < CFREF, t_functionRelease > >
330{
331public:
332
333 using REF = ::ref < cfref_base < CFREF, t_functionRelease > >;
334
335 using REF::REF;
336
337 using REF::operator=;
338
339};
340
341
342using cftyperef = cfref < CFTypeRef, ::CFRelease >;
343
344
Definition array_base.h:12
Definition cfref.h:330
Definition cfref.h:212
Definition cfref.h:22