mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-30 08:57:11 +00:00
WIP snapshot: replacing std::shared_ptr<bool> flag_ptr
with simple bool armed_flag
.
This commit is contained in:
parent
459301d9a8
commit
362e64e1ca
@ -57,26 +57,24 @@ namespace pybindit {
|
|||||||
namespace memory {
|
namespace memory {
|
||||||
|
|
||||||
struct guarded_operator_call {
|
struct guarded_operator_call {
|
||||||
std::shared_ptr<bool> flag_ptr;
|
bool armed_flag;
|
||||||
explicit guarded_operator_call(std::shared_ptr<bool> armed_flag_ptr)
|
explicit guarded_operator_call(bool armed_flag) : armed_flag{armed_flag} {}
|
||||||
: flag_ptr{armed_flag_ptr} {}
|
|
||||||
virtual void operator()(void *) = 0;
|
virtual void operator()(void *) = 0;
|
||||||
virtual ~guarded_operator_call() = default;
|
virtual ~guarded_operator_call() = default;
|
||||||
guarded_operator_call(guarded_operator_call &&) = default;
|
guarded_operator_call(guarded_operator_call &&) = default;
|
||||||
guarded_operator_call(guarded_operator_call &) = delete;
|
guarded_operator_call(guarded_operator_call &) = default;
|
||||||
guarded_operator_call &operator=(guarded_operator_call &&) = delete;
|
guarded_operator_call &operator=(guarded_operator_call &&) = delete;
|
||||||
guarded_operator_call &operator=(const guarded_operator_call &) = delete;
|
guarded_operator_call &operator=(const guarded_operator_call &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct guarded_builtin_delete : guarded_operator_call {
|
struct guarded_builtin_delete : guarded_operator_call {
|
||||||
explicit guarded_builtin_delete(std::shared_ptr<bool> armed_flag_ptr)
|
explicit guarded_builtin_delete(bool armed_flag) : guarded_operator_call{armed_flag} {}
|
||||||
: guarded_operator_call(armed_flag_ptr) {}
|
|
||||||
void operator()(void *raw_ptr) override { delete_impl<T>(raw_ptr); }
|
void operator()(void *raw_ptr) override { delete_impl<T>(raw_ptr); }
|
||||||
template <typename T_ = T,
|
template <typename T_ = T,
|
||||||
typename std::enable_if<std::is_destructible<T_>::value, int>::type = 0>
|
typename std::enable_if<std::is_destructible<T_>::value, int>::type = 0>
|
||||||
void delete_impl(void *raw_ptr) {
|
void delete_impl(void *raw_ptr) {
|
||||||
if (*flag_ptr)
|
if (armed_flag)
|
||||||
delete (T *) raw_ptr;
|
delete (T *) raw_ptr;
|
||||||
}
|
}
|
||||||
template <typename T_ = T,
|
template <typename T_ = T,
|
||||||
@ -109,10 +107,9 @@ guarded_delete make_guarded_builtin_delete(bool armed_flag) {
|
|||||||
|
|
||||||
template <typename T, typename D>
|
template <typename T, typename D>
|
||||||
struct guarded_custom_deleter : guarded_operator_call {
|
struct guarded_custom_deleter : guarded_operator_call {
|
||||||
explicit guarded_custom_deleter(std::shared_ptr<bool> armed_flag_ptr)
|
explicit guarded_custom_deleter(bool armed_flag) : guarded_operator_call{armed_flag} {}
|
||||||
: guarded_operator_call(armed_flag_ptr) {}
|
|
||||||
virtual void operator()(void *raw_ptr) override {
|
virtual void operator()(void *raw_ptr) override {
|
||||||
if (*flag_ptr)
|
if (armed_flag)
|
||||||
D()((T *) raw_ptr);
|
D()((T *) raw_ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -125,6 +122,7 @@ inline bool is_std_default_delete(const std::type_info &rtti_deleter) {
|
|||||||
|
|
||||||
struct smart_holder {
|
struct smart_holder {
|
||||||
const std::type_info *rtti_uqp_del = nullptr;
|
const std::type_info *rtti_uqp_del = nullptr;
|
||||||
|
guarded_operator_call *vptr_del = nullptr;
|
||||||
std::shared_ptr<void> vptr;
|
std::shared_ptr<void> vptr;
|
||||||
bool vptr_is_using_noop_deleter : 1;
|
bool vptr_is_using_noop_deleter : 1;
|
||||||
bool vptr_is_using_builtin_delete : 1;
|
bool vptr_is_using_builtin_delete : 1;
|
||||||
@ -228,7 +226,8 @@ struct smart_holder {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
static smart_holder from_raw_ptr_unowned(T *raw_ptr) {
|
static smart_holder from_raw_ptr_unowned(T *raw_ptr) {
|
||||||
smart_holder hld;
|
smart_holder hld;
|
||||||
hld.vptr.reset(raw_ptr, [](void *) {});
|
hld.vptr.reset(raw_ptr, guarded_builtin_delete<T>(false));
|
||||||
|
hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr);
|
||||||
hld.vptr_is_using_noop_deleter = true;
|
hld.vptr_is_using_noop_deleter = true;
|
||||||
hld.is_populated = true;
|
hld.is_populated = true;
|
||||||
return hld;
|
return hld;
|
||||||
@ -259,12 +258,21 @@ struct smart_holder {
|
|||||||
static smart_holder from_raw_ptr_take_ownership(T *raw_ptr) {
|
static smart_holder from_raw_ptr_take_ownership(T *raw_ptr) {
|
||||||
ensure_pointee_is_destructible<T>("from_raw_ptr_take_ownership");
|
ensure_pointee_is_destructible<T>("from_raw_ptr_take_ownership");
|
||||||
smart_holder hld;
|
smart_holder hld;
|
||||||
hld.vptr.reset(raw_ptr, make_guarded_builtin_delete<T>(true));
|
hld.vptr.reset(raw_ptr, guarded_builtin_delete<T>(true));
|
||||||
|
hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr);
|
||||||
hld.vptr_is_using_builtin_delete = true;
|
hld.vptr_is_using_builtin_delete = true;
|
||||||
hld.is_populated = true;
|
hld.is_populated = true;
|
||||||
return hld;
|
return hld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_vptr_deleter_armed_flag(bool armed_flag) {
|
||||||
|
if (vptr_del == nullptr) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"smart_holder::reset_vptr_deleter_armed_flag() called in an invalid context.");
|
||||||
|
}
|
||||||
|
vptr_del->armed_flag = armed_flag;
|
||||||
|
}
|
||||||
|
|
||||||
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
|
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
|
||||||
void disown() {
|
void disown() {
|
||||||
reset_vptr_deleter_armed_flag(false);
|
reset_vptr_deleter_armed_flag(false);
|
||||||
@ -278,7 +286,10 @@ struct smart_holder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
|
// Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details).
|
||||||
void release_disowned() { vptr.reset(); }
|
void release_disowned() {
|
||||||
|
vptr.reset();
|
||||||
|
vptr_del = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// SMART_HOLDER_WIP: review this function.
|
// SMART_HOLDER_WIP: review this function.
|
||||||
void ensure_can_release_ownership(const char *context = "ensure_can_release_ownership") const {
|
void ensure_can_release_ownership(const char *context = "ensure_can_release_ownership") const {
|
||||||
@ -306,17 +317,13 @@ struct smart_holder {
|
|||||||
smart_holder hld;
|
smart_holder hld;
|
||||||
hld.rtti_uqp_del = &typeid(D);
|
hld.rtti_uqp_del = &typeid(D);
|
||||||
hld.vptr_is_using_builtin_delete = is_std_default_delete<T>(*hld.rtti_uqp_del);
|
hld.vptr_is_using_builtin_delete = is_std_default_delete<T>(*hld.rtti_uqp_del);
|
||||||
guarded_operator_call *vptr_del = nullptr;
|
|
||||||
if (hld.vptr_is_using_builtin_delete) {
|
if (hld.vptr_is_using_builtin_delete) {
|
||||||
hld.vptr.reset(unq_ptr.get(),
|
hld.vptr.reset(unq_ptr.get(), guarded_builtin_delete<T>(true));
|
||||||
guarded_builtin_delete<T>(hld.vptr_deleter_armed_flag_ptr));
|
hld.vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr);
|
||||||
vptr_del = std::get_deleter<guarded_builtin_delete<T>>(hld.vptr);
|
|
||||||
} else {
|
} else {
|
||||||
hld.vptr.reset(unq_ptr.get(),
|
hld.vptr.reset(unq_ptr.get(), guarded_custom_deleter<T, D>(true));
|
||||||
guarded_custom_deleter<T, D>(hld.vptr_deleter_armed_flag_ptr));
|
hld.vptr_del = std::get_deleter<guarded_custom_deleter<T, D>>(hld.vptr);
|
||||||
vptr_del = std::get_deleter<guarded_custom_deleter<T, D>>(hld.vptr);
|
|
||||||
}
|
}
|
||||||
assert(vptr_del != nullptr);
|
|
||||||
unq_ptr.release();
|
unq_ptr.release();
|
||||||
hld.is_populated = true;
|
hld.is_populated = true;
|
||||||
return hld;
|
return hld;
|
||||||
|
Loading…
Reference in New Issue
Block a user