Removing enable_shared_from_this stub, simplifying existing code, clang-format.

Open question, with respect to the original code:
76a160070b/include/pybind11/pybind11.h (L1510)
To me it looks like the exact situation marked as `std::shared_ptr<Good> gp1 = not_so_good.getptr();` here: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
The comment there is: `// undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)`
Does the existing code have UB pre C++17?

I'll leave handling of enable_shared_from_this for later, as the need arises.
This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-01-15 11:00:36 -08:00
parent b41a0db1b1
commit 86ba2081af

View File

@ -1,10 +1,11 @@
#pragma once #pragma once
#include "smart_holder_poc.h"
#include "pybind11.h" #include "pybind11.h"
#include "smart_holder_poc.h"
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
// clang-format off
template <typename type_, typename... options> template <typename type_, typename... options>
class classh : public detail::generic_type { class classh : public detail::generic_type {
template <typename T> using is_subtype = detail::is_strict_base_of<type_, T>; template <typename T> using is_subtype = detail::is_strict_base_of<type_, T>;
@ -266,38 +267,31 @@ public:
} }
private: private:
template <typename T> // clang-format on
static void init_holder(bool /*owned*/, detail::value_and_holder &/*v_h*/, static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
holder_type * /* unused */, const std::enable_shared_from_this<T> * /* dummy */) { // Need for const_cast is a consequence of the type_info::init_instance type:
throw std::runtime_error("Not implemented: classh::init_holder enable_shared_from_this."); // void (*init_instance)(instance *, const void *);
} auto holder_void_ptr = const_cast<void *>(holder_const_void_ptr);
static void init_holder(bool owned, detail::value_and_holder &v_h,
holder_type *holder_ptr, const void * /* dummy -- not enable_shared_from_this<T>) */) {
if (holder_ptr) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(
std::move(*holder_ptr));
} else if (owned) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(
holder_type::from_raw_ptr_take_ownership(v_h.value_ptr<type>()));
}
else {
new (std::addressof(v_h.holder<holder_type>())) holder_type(
holder_type::from_raw_ptr_unowned(v_h.value_ptr<type>()));
}
v_h.set_holder_constructed();
}
static void init_instance(detail::instance *inst, const void *holder_ptr) {
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type))); auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
if (!v_h.instance_registered()) { if (!v_h.instance_registered()) {
register_instance(inst, v_h.value_ptr(), v_h.type); register_instance(inst, v_h.value_ptr(), v_h.type);
v_h.set_instance_registered(); v_h.set_instance_registered();
} }
// Need for const_cast is a consequence of the type_info::init_instance type: if (holder_void_ptr) {
// void (*init_instance)(instance *, const void *); // Note: inst->owned ignored.
init_holder(inst->owned, v_h, static_cast<holder_type *>(const_cast<void *>(holder_ptr)), v_h.value_ptr<type>()); auto holder_ptr = static_cast<holder_type *>(holder_void_ptr);
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(*holder_ptr));
} else if (inst->owned) {
new (std::addressof(v_h.holder<holder_type>()))
holder_type(holder_type::from_raw_ptr_take_ownership(v_h.value_ptr<type>()));
} else {
new (std::addressof(v_h.holder<holder_type>()))
holder_type(holder_type::from_raw_ptr_unowned(v_h.value_ptr<type>()));
}
v_h.set_holder_constructed();
} }
// clang-format off
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete. /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
static void dealloc(detail::value_and_holder &v_h) { static void dealloc(detail::value_and_holder &v_h) {