mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
Split out (almost) pure refactoring from https://github.com/pybind/pybind11/pull/5332 (#5334)
PREPARATION for: PR #5332 — Fix handling of const unique_ptr<T, D> & (do not disown). Splitting out so that the functional changes under PR #5332 will be more obvious. The only functional change under this PR is that ``` assert(custom_deleter_ptr != nullptr); ``` is replaced with: ``` if (custom_deleter_ptr == nullptr) { throw std::runtime_error( std::string("smart_holder::extract_deleter() precondition failure (") + context + ")."); } ```
This commit is contained in:
parent
bf54ecdf9c
commit
0e49463169
@ -231,6 +231,22 @@ struct smart_holder {
|
|||||||
vptr_del_ptr->armed_flag = armed_flag;
|
vptr_del_ptr->armed_flag = armed_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caller is responsible for precondition: ensure_compatible_rtti_uqp_del<T, D>() must succeed.
|
||||||
|
template <typename T, typename D>
|
||||||
|
std::unique_ptr<D> extract_deleter(const char *context) const {
|
||||||
|
auto *gd = std::get_deleter<guarded_delete>(vptr);
|
||||||
|
if (gd && gd->use_del_fun) {
|
||||||
|
const auto &custom_deleter_ptr = gd->del_fun.template target<custom_deleter<T, D>>();
|
||||||
|
if (custom_deleter_ptr == nullptr) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
std::string("smart_holder::extract_deleter() precondition failure (") + context
|
||||||
|
+ ").");
|
||||||
|
}
|
||||||
|
return std::unique_ptr<D>(new D(std::move(custom_deleter_ptr->deleter)));
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static smart_holder from_raw_ptr_unowned(void *raw_ptr) {
|
static smart_holder from_raw_ptr_unowned(void *raw_ptr) {
|
||||||
smart_holder hld;
|
smart_holder hld;
|
||||||
hld.vptr.reset(raw_ptr, [](void *) {});
|
hld.vptr.reset(raw_ptr, [](void *) {});
|
||||||
|
@ -794,22 +794,7 @@ struct load_helper : value_and_holder_helper {
|
|||||||
"instance cannot safely be transferred to C++.");
|
"instance cannot safely be transferred to C++.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary variable to store the extracted deleter in.
|
std::unique_ptr<D> extracted_deleter = holder().template extract_deleter<T, D>(context);
|
||||||
std::unique_ptr<D> extracted_deleter;
|
|
||||||
|
|
||||||
auto *gd = std::get_deleter<pybindit::memory::guarded_delete>(holder().vptr);
|
|
||||||
if (gd && gd->use_del_fun) { // Note the ensure_compatible_rtti_uqp_del<T, D>() call above.
|
|
||||||
// In struct_smart_holder, a custom deleter is always stored in a guarded delete.
|
|
||||||
// The guarded delete's std::function<void(void*)> actually points at the
|
|
||||||
// custom_deleter type, so we can verify it is of the custom deleter type and
|
|
||||||
// finally extract its deleter.
|
|
||||||
using custom_deleter_D = pybindit::memory::custom_deleter<T, D>;
|
|
||||||
const auto &custom_deleter_ptr = gd->del_fun.template target<custom_deleter_D>();
|
|
||||||
assert(custom_deleter_ptr != nullptr);
|
|
||||||
// Now that we have confirmed the type of the deleter matches the desired return
|
|
||||||
// value we can extract the function.
|
|
||||||
extracted_deleter = std::unique_ptr<D>(new D(std::move(custom_deleter_ptr->deleter)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Critical transfer-of-ownership section. This must stay together.
|
// Critical transfer-of-ownership section. This must stay together.
|
||||||
if (self_life_support != nullptr) {
|
if (self_life_support != nullptr) {
|
||||||
|
Loading…
Reference in New Issue
Block a user