source: libcfa/src/virtual_dtor.hfa @ 433e2c3

Last change on this file since 433e2c3 was a1f0cb6, checked in by caparsons <caparson@…>, 17 months ago

added pragma once

  • Property mode set to 100644
File size: 2.0 KB
Line 
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
12struct 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
18static inline void __CFA_set_virt_dtor( virtual_dtor & this, void (*v_dtor)(virtual_dtor &)) {
19    this.__virtual_dtor_ptr = v_dtor;
20}
21static inline void __CFA_set_virt_start( virtual_dtor & this, void * start) {
22    this.__virtual_obj_start = start;
23}
24static inline void __CFA_setup_dtor( virtual_dtor & this ) with(this) {
25    __virtual_dtor_ptr = 0p;
26    __virtual_obj_start = &this;
27}
28static 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}
39static inline void __CFA_virt_free( virtual_dtor & this ) { free( this.__virtual_obj_start ); }
40static inline void * __CFA_get_virt_start( virtual_dtor & this ) { return this.__virtual_obj_start; }
41static inline void ?{}( virtual_dtor & this ) {}
42static inline void ^?{}( virtual_dtor & this ) {}
Note: See TracBrowser for help on using the repository browser.