acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
ptr.h
1//
2// simple_pointer.h
3// acme
4//
5// Created by Camilo Sasuke Thomas Borregaard Soerensen on 31/05/22.
6// Copyright (c) 2022 Camilo Sasuke Thomas Borregaard Soerensen. All rights reserved.
7//
8#pragma once
9
10
11#define __pointer_is_null(p) (((uptr)(void *) p) < 4096)
12
13#define __pointer_is_set(p) (!__pointer_is_null(p))
14
15
16template < typename TYPE >
17class ptr
18{
19public:
20
21 using POINTER_TYPE_TAG = pointer_type_t;
22
23 TYPE * m_p;
24#if REFERENCING_DEBUGGING
25 reference_referer * m_preferer;
26#endif
27
28 ptr()
29 {
30
31 m_p = nullptr;
32
33#if REFERENCING_DEBUGGING
34 m_preferer = nullptr;
35#endif
36 }
37
38
40 ptr(const TYPE * p)
41 {
42
43 if(p)
44 {
45
46#if REFERENCING_DEBUGGING
47
48 m_preferer = ::allocator::defer_push_referer(p, {this, __FUNCTION_FILE_LINE__});
49
50#endif
51
52 ((TYPE *)p)->increment_reference_count();
53
54 m_p = (TYPE*)p;
55
56 }
57 else
58 {
59
60 m_p = nullptr;
61
62#if REFERENCING_DEBUGGING
63
64 m_preferer = nullptr;
65
66#endif
67
68 }
69
70 }
71
73 template < typename TYPE2 >
74 ptr(const TYPE2 * p)
75 {
76
77 if (::is_set(p))
78 {
79
80#if REFERENCING_DEBUGGING
81
82 m_preferer = ::allocator::defer_push_referer(p, { this, __FUNCTION_FILE_LINE__ });
83
84#endif
85
86 ((TYPE2*)p)->increment_reference_count();
87
88 m_p = dynamic_cast < TYPE * > ((TYPE2*)p);
89
90 }
91 else
92 {
93
94 m_p = nullptr;
95
96#if REFERENCING_DEBUGGING
97
98 m_preferer = nullptr;
99
100#endif
101
102 }
103
104 }
105
107 ptr(const ptr & ptr)
108 {
109
110 if(ptr.m_p)
111 {
112
113#if REFERENCING_DEBUGGING
114
115 m_preferer = ::allocator::defer_push_referer(ptr.m_p, {this, __FUNCTION_FILE_LINE__});
116
117#endif
118
119 ptr.m_p->increment_reference_count();
120
121 m_p = ptr.m_p;
122
123 }
124 else
125 {
126
127#if REFERENCING_DEBUGGING
128
129 m_preferer = nullptr;
130
131#endif
132
133 m_p = nullptr;
134
135 }
136
137 }
138
139
141 ptr(ptr && ptr)
142 {
143
144 m_p = ptr.m_p;
145
146#if REFERENCING_DEBUGGING
147
148 m_preferer = ptr.m_preferer;
149
150#endif
151
152 ptr.m_p = nullptr;
153
154#if REFERENCING_DEBUGGING
155
156 ptr.m_preferer = nullptr;
157
158#endif
159
160 }
161
162
164 ptr(transfer_t, const TYPE * p)
165 {
166
167 m_p = (TYPE*) p;
168
169 }
170
171
172 ptr(const ::pointer < TYPE > & p);
173
174 ptr(::pointer < TYPE > && p);
175
176 template < typename T2 >
177 ptr(const ::pointer < T2 > & p);
178
179 template < typename T2 >
180 ptr(::pointer < T2 > && p);
181
182
183 ~ptr()
184 {
185
186 release();
187
188 }
189
190
191 TYPE * operator ->() {return m_p; }
192 TYPE * operator ->() const {return m_p; }
193 operator TYPE *() {return m_p; }
194 operator TYPE *() const {return m_p; }
195 TYPE * get() { return m_p; }
196 TYPE * get() const { return m_p; }
197
198 ptr & operator = (const TYPE * p)
199 {
200
201 auto pOld = m_p;
202
203 if(pOld != p)
204 {
205
206#if REFERENCING_DEBUGGING
207
208 auto prefererOld = m_preferer;
209
210 ::reference_referer * prefererNew = nullptr;
211
212 if(p->is_referencing_debugging_enabled())
213 {
214
215 prefererNew = ::allocator::defer_push_referer(p, { this, __FUNCTION_FILE_LINE__ });
216
217 }
218
219#endif
220
221 ((TYPE *)p)->increment_reference_count();
222
223 m_p = ((TYPE *)p);
224
225 if(__pointer_is_set(pOld))
226 {
227
228#if REFERENCING_DEBUGGING
229
230 ::allocator::add_releaser(prefererOld);
231
232#endif
233
234 pOld->release();
235
236 }
237
238#if REFERENCING_DEBUGGING
239
240 m_preferer = prefererNew;
241
242#endif
243
244 }
245
246 return *this;
247
248 }
249
250
251 template < typename T2 >
252 ptr & operator = (const T2 * p2)
253 {
254
255 auto p = dynamic_cast < TYPE * >((T2 *) p2);
256
257 return this->operator=(p);
258
259 }
260
261 ::ptr < TYPE > & operator = (const ::ptr < TYPE > & p)
262 {
263
264 auto pOld = m_p;
265
266 if(pOld != p.m_p)
267 {
268
269#if REFERENCING_DEBUGGING
270
271 auto prefererOld = m_preferer;
272
273 ::reference_referer * prefererNew = nullptr;
274
275 if(p->is_referencing_debugging_enabled())
276 {
277
278 prefererNew = ::allocator::defer_push_referer(p, { this, __FUNCTION_FILE_LINE__ });
279
280 }
281
282#endif
283
284 p.m_p->increment_reference_count();
285
286 m_p = p.m_p;
287
288 if (__pointer_is_set(pOld))
289 {
290
291#if REFERENCING_DEBUGGING
292
293 ::allocator::add_releaser(prefererOld);
294
295#endif
296
297 pOld->release();
298
299 }
300
301#if REFERENCING_DEBUGGING
302
303 m_preferer = prefererNew;
304
305#endif
306
307 }
308
309 return *this;
310
311 }
312
313
314 ::ptr < TYPE > & operator = (::ptr < TYPE > && p)
315 {
316
317 auto pOld = m_p;
318
319 if (pOld != p.m_p)
320 {
321
322#if REFERENCING_DEBUGGING
323
324 auto prefererOld = m_preferer;
325
326 auto prefererNew = p.m_preferer;
327
328#endif
329
330 m_p = p.m_p;
331
332 p.m_p = nullptr;
333
334 if (__pointer_is_set(pOld))
335 {
336
337#if REFERENCING_DEBUGGING
338
339 ::allocator::add_releaser(prefererOld);
340
341#endif
342
343 pOld->release();
344
345 }
346
347#if REFERENCING_DEBUGGING
348
349 m_preferer = prefererNew;
350
351#endif
352
353 }
354
355 return *this;
356
357 }
358
359
360 ::ptr < TYPE > & transfer(TYPE * p)
361 {
362
363 auto pOld = m_p;
364
365 if (pOld != p)
366 {
367
368#if REFERENCING_DEBUGGING
369
370 auto prefererOld = m_preferer;
371
372 auto prefererNew = p->m_preferer;
373
374#endif
375
376 m_p = (TYPE *)p;
377
378 if (__pointer_is_set(pOld))
379 {
380
381#if REFERENCING_DEBUGGING
382
383 ::allocator::add_releaser(prefererOld);
384
385#endif
386
387 pOld->release();
388
389 }
390
391#if REFERENCING_DEBUGGING
392
393 m_preferer = prefererNew;
394
395#endif
396
397 }
398
399 return *this;
400
401 }
402
403
404 ptr & operator = (const ::pointer < TYPE > & p);
405
406 ptr & operator = (::pointer < TYPE > && p);
407
408 template < typename T2 >
409 ptr & operator = (const ::pointer < T2 > & p);
410
411 template < typename T2 >
412 ptr & operator = (::pointer < T2 > && p);
413
414 //ptr & transfer(TYPE * p)
415 //{
416 //
417 // m_p = p;
418 //
419 // return *this;
420 //
421 //}
422 //
423 //
424 void release()
425 {
426
427 auto p = m_p;
428
429 if (__pointer_is_set(p))
430 {
431
432#if REFERENCING_DEBUGGING
433
434 auto prefererReleaser = m_preferer;
435
436#endif
437
438 m_p = nullptr;
439
440#if REFERENCING_DEBUGGING
441
442 m_preferer = nullptr;
443
444#endif
445
446 if (__pointer_is_set(p))
447 {
448
449#if REFERENCING_DEBUGGING
450
451 ::allocator::add_releaser(prefererReleaser);
452
453#endif
454
455 p->release();
456
457 }
458
459 }
460
461 }
462
463
464 void operator()() const
465 {
466
467 ((TYPE *)m_p)->call_run();
468
469 }
470
471
472 operator hash32() const { return { (::u32)(::uptr)m_p }; }
473
474
475 inline bool is_null() const
476 {
477
478 return ::is_null(this) || ::is_null(m_p);
479
480 }
481
482
483 inline bool is_set() const
484 {
485
486 return !is_null() && m_p->is_set();
487
488 }
489
490
491 inline bool ok() const
492 {
493
494 return is_set() && m_p->is_ok();
495
496 }
497
498
499 inline bool nok() const
500 {
501
502 return !ok();
503
504 }
505
506
507};
508
509
510
511template < typename TYPE >
512inline bool EqualElements(const ::ptr<TYPE> & element1, const TYPE * element2)
513{
514
515 return element1 == element2;
516
517}
518
Definition ptr.h:18
ptr(const ptr &ptr)
consumes a referer
Definition ptr.h:107
ptr(ptr &&ptr)
referer is transferred ?
Definition ptr.h:141
ptr(const TYPE2 *p)
consumes a referer
Definition ptr.h:74
ptr(const TYPE *p)
consumes a referer
Definition ptr.h:40
Definition _structures.h:21
Definition _structures.h:6