1 | #pragma once
|
---|
2 |
|
---|
3 | // inline virtual_dtor to have a virtual dtor.
|
---|
4 | // when using this, delete() is also virtual and will be called on the right address
|
---|
5 | // using free() directly on polymorphic types may result in unaligned memory deallocation
|
---|
6 | // in multi-inheritance or in single inheritance if the inline isn't the first field
|
---|
7 |
|
---|
8 | // This supports virtual dtors for both single and multiple inheritance,
|
---|
9 | // however it does not support multiple inheritance of the virtual_dtor. e.g.:
|
---|
10 | // given struct A { inline virtual_dtor; } and struct B { inline virtual_dtor; }
|
---|
11 | // struct C { inline A; inline B; } will result in undefined behaviour
|
---|
12 | struct virtual_dtor {
|
---|
13 | void (*__virtual_dtor_ptr)(virtual_dtor &);
|
---|
14 | void * __virtual_obj_start;
|
---|
15 | };
|
---|
16 |
|
---|
17 | // the following routines are used by the compiler and should not be called directly
|
---|
18 | static inline void __CFA_set_virt_dtor( virtual_dtor & this, void (*v_dtor)(virtual_dtor &)) {
|
---|
19 | this.__virtual_dtor_ptr = v_dtor;
|
---|
20 | }
|
---|
21 | static inline void __CFA_set_virt_start( virtual_dtor & this, void * start) {
|
---|
22 | this.__virtual_obj_start = start;
|
---|
23 | }
|
---|
24 | static inline void __CFA_setup_dtor( virtual_dtor & this ) with(this) {
|
---|
25 | __virtual_dtor_ptr = 0p;
|
---|
26 | __virtual_obj_start = &this;
|
---|
27 | }
|
---|
28 | static inline bool __CFA_dtor_shutdown( virtual_dtor & this ) with(this) {
|
---|
29 | if ( __virtual_dtor_ptr == 1p ) return true; // stop base dtors from being called twice
|
---|
30 | if ( __virtual_dtor_ptr ) {
|
---|
31 | void (*dtor_ptr)(virtual_dtor &) = __virtual_dtor_ptr;
|
---|
32 | __virtual_dtor_ptr = 0p;
|
---|
33 | dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // call most derived dtor
|
---|
34 | __virtual_dtor_ptr = 1p; // stop base dtors from being called twice
|
---|
35 | return true;
|
---|
36 | }
|
---|
37 | return false;
|
---|
38 | }
|
---|
39 | static inline void __CFA_virt_free( virtual_dtor & this ) { free( this.__virtual_obj_start ); }
|
---|
40 | static inline void * __CFA_get_virt_start( virtual_dtor & this ) { return this.__virtual_obj_start; }
|
---|
41 | static inline void ?{}( virtual_dtor & this ) {}
|
---|
42 | static inline void ^?{}( virtual_dtor & this ) {}
|
---|