mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
smart_holder hld;
|
||||
hld.vptr.reset(raw_ptr, [](void *) {});
|
||||
|
@ -794,22 +794,7 @@ struct load_helper : value_and_holder_helper {
|
||||
"instance cannot safely be transferred to C++.");
|
||||
}
|
||||
|
||||
// Temporary variable to store the extracted deleter in.
|
||||
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)));
|
||||
}
|
||||
std::unique_ptr<D> extracted_deleter = holder().template extract_deleter<T, D>(context);
|
||||
|
||||
// Critical transfer-of-ownership section. This must stay together.
|
||||
if (self_life_support != nullptr) {
|
||||
|
Loading…
Reference in New Issue
Block a user