[a1f0cb6] | 1 | #pragma once
|
---|
| 2 |
|
---|
| 3 | // inline virtual_dtor to have a virtual dtor.
|
---|
[8512a2f] | 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 | }
|
---|
[1e940de0] | 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
|
---|
[8512a2f] | 30 | if ( __virtual_dtor_ptr ) {
|
---|
| 31 | void (*dtor_ptr)(virtual_dtor &) = __virtual_dtor_ptr;
|
---|
| 32 | __virtual_dtor_ptr = 0p;
|
---|
[1e940de0] | 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;
|
---|
[8512a2f] | 36 | }
|
---|
[1e940de0] | 37 | return false;
|
---|
[8512a2f] | 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 ) {}
|
---|