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 ) {} |
---|