@@ -18,12 +18,50 @@ struct VirtBase {
18
18
using VirtBaseSH = VirtBase<0 >; // for testing with py::smart_holder
19
19
using VirtBaseSP = VirtBase<1 >; // for testing with std::shared_ptr as holder
20
20
21
- struct PyVirtBaseSH : VirtBaseSH, py::trampoline_self_life_support {
21
+ // Similar to trampoline_self_life_support
22
+ struct trampoline_is_alive_simple {
23
+ std::uint64_t magic_token = 197001010000u ;
24
+
25
+ trampoline_is_alive_simple () = default ;
26
+
27
+ ~trampoline_is_alive_simple () { magic_token = 20380118191407u ; }
28
+
29
+ trampoline_is_alive_simple (const trampoline_is_alive_simple &other) {
30
+ magic_token = other.magic_token ;
31
+ }
32
+ trampoline_is_alive_simple (trampoline_is_alive_simple &&other) noexcept {
33
+ magic_token = other.magic_token ;
34
+ other.magic_token = 20380118191407u ;
35
+ }
36
+
37
+ trampoline_is_alive_simple &operator =(const trampoline_is_alive_simple &) = delete ;
38
+ trampoline_is_alive_simple &operator =(trampoline_is_alive_simple &&) = delete ;
39
+ };
40
+
41
+ template <typename VB>
42
+ const char *determine_trampoline_state (const std::shared_ptr<VB> &sp) {
43
+ if (!sp) {
44
+ return " sp nullptr" ;
45
+ }
46
+ auto *tias = dynamic_cast <trampoline_is_alive_simple *>(sp.get ());
47
+ if (!tias) {
48
+ return " dynamic_cast failed" ;
49
+ }
50
+ if (tias->magic_token == 197001010000u ) {
51
+ return " trampoline alive" ;
52
+ }
53
+ if (tias->magic_token == 20380118191407u ) {
54
+ return " trampoline DEAD" ;
55
+ }
56
+ return " UNDEFINED BEHAVIOR" ;
57
+ }
58
+
59
+ struct PyVirtBaseSH : VirtBaseSH, py::trampoline_self_life_support, trampoline_is_alive_simple {
22
60
using VirtBaseSH::VirtBaseSH;
23
61
int get_code () override { PYBIND11_OVERRIDE (int , VirtBaseSH, get_code); }
24
62
};
25
63
26
- struct PyVirtBaseSP : VirtBaseSP { // self-life-support not available
64
+ struct PyVirtBaseSP : VirtBaseSP, trampoline_is_alive_simple { // self-life-support not available
27
65
using VirtBaseSP::VirtBaseSP;
28
66
int get_code () override { PYBIND11_OVERRIDE (int , VirtBaseSP, get_code); }
29
67
};
@@ -42,13 +80,15 @@ template <typename VB>
42
80
struct SpOwner {
43
81
void set_sp (const std::shared_ptr<VB> &sp_) { sp = sp_; }
44
82
45
- int get_code () {
83
+ int get_code () const {
46
84
if (!sp) {
47
85
return -888 ;
48
86
}
49
87
return sp->get_code ();
50
88
}
51
89
90
+ const char *get_trampoline_state () const { return determine_trampoline_state (sp); }
91
+
52
92
private:
53
93
std::shared_ptr<VB> sp;
54
94
};
@@ -57,14 +97,16 @@ template <typename VB>
57
97
struct WpOwner {
58
98
void set_wp (const std::shared_ptr<VB> &sp) { wp = sp; }
59
99
60
- int get_code () {
100
+ int get_code () const {
61
101
auto sp = wp.lock ();
62
102
if (!sp) {
63
103
return -999 ;
64
104
}
65
105
return sp->get_code ();
66
106
}
67
107
108
+ const char *get_trampoline_state () const { return determine_trampoline_state (wp.lock ()); }
109
+
68
110
private:
69
111
std::weak_ptr<VB> wp;
70
112
};
@@ -81,7 +123,8 @@ void wrap(py::module_ &m,
81
123
py::classh<SpOwner<VB>>(m, spo_pyname)
82
124
.def (py::init<>())
83
125
.def (" set_sp" , &SpOwner<VB>::set_sp)
84
- .def (" get_code" , &SpOwner<VB>::get_code);
126
+ .def (" get_code" , &SpOwner<VB>::get_code)
127
+ .def (" get_trampoline_state" , &SpOwner<VB>::get_trampoline_state);
85
128
86
129
py::classh<WpOwner<VB>>(m, wpo_pyname)
87
130
.def (py::init<>())
@@ -90,7 +133,8 @@ void wrap(py::module_ &m,
90
133
[](WpOwner<VB> &self, py::handle obj) {
91
134
self.set_wp (py::potentially_slicing_shared_ptr<VB>(obj));
92
135
})
93
- .def (" get_code" , &WpOwner<VB>::get_code);
136
+ .def (" get_code" , &WpOwner<VB>::get_code)
137
+ .def (" get_trampoline_state" , &WpOwner<VB>::get_trampoline_state);
94
138
}
95
139
96
140
} // namespace potentially_slicing_shared_ptr
0 commit comments