@@ -57,26 +57,24 @@ namespace pybindit {
57
57
namespace memory {
58
58
59
59
struct guarded_operator_call {
60
- std::shared_ptr<bool > flag_ptr;
61
- explicit guarded_operator_call (std::shared_ptr<bool > armed_flag_ptr)
62
- : flag_ptr{armed_flag_ptr} {}
60
+ bool armed_flag;
61
+ explicit guarded_operator_call (bool armed_flag) : armed_flag{armed_flag} {}
63
62
virtual void operator ()(void *) = 0;
64
63
virtual ~guarded_operator_call () = default ;
65
64
guarded_operator_call (guarded_operator_call &&) = default ;
66
- guarded_operator_call (guarded_operator_call &) = delete ;
65
+ guarded_operator_call (guarded_operator_call &) = default ;
67
66
guarded_operator_call &operator =(guarded_operator_call &&) = delete ;
68
67
guarded_operator_call &operator =(const guarded_operator_call &) = delete ;
69
68
};
70
69
71
70
template <typename T>
72
71
struct guarded_builtin_delete : guarded_operator_call {
73
- explicit guarded_builtin_delete (std::shared_ptr<bool > armed_flag_ptr)
74
- : guarded_operator_call(armed_flag_ptr) {}
72
+ explicit guarded_builtin_delete (bool armed_flag) : guarded_operator_call{armed_flag} {}
75
73
void operator ()(void *raw_ptr) override { delete_impl<T>(raw_ptr); }
76
74
template <typename T_ = T,
77
75
typename std::enable_if<std::is_destructible<T_>::value, int >::type = 0 >
78
76
void delete_impl (void *raw_ptr) {
79
- if (*flag_ptr )
77
+ if (armed_flag )
80
78
delete (T *) raw_ptr;
81
79
}
82
80
template <typename T_ = T,
@@ -109,10 +107,9 @@ guarded_delete make_guarded_builtin_delete(bool armed_flag) {
109
107
110
108
template <typename T, typename D>
111
109
struct guarded_custom_deleter : guarded_operator_call {
112
- explicit guarded_custom_deleter (std::shared_ptr<bool > armed_flag_ptr)
113
- : guarded_operator_call(armed_flag_ptr) {}
110
+ explicit guarded_custom_deleter (bool armed_flag) : guarded_operator_call{armed_flag} {}
114
111
virtual void operator ()(void *raw_ptr) override {
115
- if (*flag_ptr )
112
+ if (armed_flag )
116
113
D ()((T *) raw_ptr);
117
114
}
118
115
};
@@ -125,6 +122,7 @@ inline bool is_std_default_delete(const std::type_info &rtti_deleter) {
125
122
126
123
struct smart_holder {
127
124
const std::type_info *rtti_uqp_del = nullptr ;
125
+ guarded_operator_call *vptr_del = nullptr ;
128
126
std::shared_ptr<void > vptr;
129
127
bool vptr_is_using_noop_deleter : 1 ;
130
128
bool vptr_is_using_builtin_delete : 1 ;
@@ -228,7 +226,8 @@ struct smart_holder {
228
226
template <typename T>
229
227
static smart_holder from_raw_ptr_unowned (T *raw_ptr) {
230
228
smart_holder hld;
231
- hld.vptr .reset (raw_ptr, [](void *) {});
229
+ hld.vptr .reset (raw_ptr, guarded_builtin_delete<T>(false ));
230
+ hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr );
232
231
hld.vptr_is_using_noop_deleter = true ;
233
232
hld.is_populated = true ;
234
233
return hld;
@@ -259,12 +258,21 @@ struct smart_holder {
259
258
static smart_holder from_raw_ptr_take_ownership (T *raw_ptr) {
260
259
ensure_pointee_is_destructible<T>(" from_raw_ptr_take_ownership" );
261
260
smart_holder hld;
262
- hld.vptr .reset (raw_ptr, make_guarded_builtin_delete<T>(true ));
261
+ hld.vptr .reset (raw_ptr, guarded_builtin_delete<T>(true ));
262
+ hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr );
263
263
hld.vptr_is_using_builtin_delete = true ;
264
264
hld.is_populated = true ;
265
265
return hld;
266
266
}
267
267
268
+ void reset_vptr_deleter_armed_flag (bool armed_flag) {
269
+ if (vptr_del == nullptr ) {
270
+ throw std::runtime_error (
271
+ " smart_holder::reset_vptr_deleter_armed_flag() called in an invalid context." );
272
+ }
273
+ vptr_del->armed_flag = armed_flag;
274
+ }
275
+
268
276
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
269
277
void disown () {
270
278
reset_vptr_deleter_armed_flag (false );
@@ -278,7 +286,10 @@ struct smart_holder {
278
286
}
279
287
280
288
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
281
- void release_disowned () { vptr.reset (); }
289
+ void release_disowned () {
290
+ vptr.reset ();
291
+ vptr_del = nullptr ;
292
+ }
282
293
283
294
// SMART_HOLDER_WIP: review this function.
284
295
void ensure_can_release_ownership (const char *context = " ensure_can_release_ownership" ) const {
@@ -306,17 +317,13 @@ struct smart_holder {
306
317
smart_holder hld;
307
318
hld.rtti_uqp_del = &typeid (D);
308
319
hld.vptr_is_using_builtin_delete = is_std_default_delete<T>(*hld.rtti_uqp_del );
309
- guarded_operator_call *vptr_del = nullptr ;
310
320
if (hld.vptr_is_using_builtin_delete ) {
311
- hld.vptr .reset (unq_ptr.get (),
312
- guarded_builtin_delete<T>(hld.vptr_deleter_armed_flag_ptr ));
313
- vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr );
321
+ hld.vptr .reset (unq_ptr.get (), guarded_builtin_delete<T>(true ));
322
+ hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr );
314
323
} else {
315
- hld.vptr .reset (unq_ptr.get (),
316
- guarded_custom_deleter<T, D>(hld.vptr_deleter_armed_flag_ptr ));
317
- vptr_del = std::get_deleter<guarded_custom_deleter<T, D>>(hld.vptr );
324
+ hld.vptr .reset (unq_ptr.get (), guarded_custom_deleter<T, D>(true ));
325
+ hld.vptr_del = std::get_deleter<guarded_custom_deleter<T, D>>(hld.vptr );
318
326
}
319
- assert (vptr_del != nullptr );
320
327
unq_ptr.release ();
321
328
hld.is_populated = true ;
322
329
return hld;
0 commit comments