Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@
#include <memory>
#include <typeindex>
#include <type_traits>
#if defined(__has_include)
# if __has_include(<version>)
# include <version>
# endif
#endif

#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
Expand Down
32 changes: 24 additions & 8 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -1501,18 +1501,34 @@ class class_ : public detail::generic_type {
}

private:
template <typename T>
Comment thread
YannickJadoul marked this conversation as resolved.
Outdated
inline static std::shared_ptr<T> get_shared_from_this(std::enable_shared_from_this<T> *holder_value_ptr) {
#if defined(__cpp_lib_enable_shared_from_this) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
if (!holder_value_ptr->weak_from_this().expired())
return holder_value_ptr->shared_from_this();
else
return nullptr;
#else
try {
Comment thread
YannickJadoul marked this conversation as resolved.
Outdated
return holder_value_ptr->shared_from_this();
}
catch (const std::bad_weak_ptr &) {
return nullptr;
}
#endif
}

/// Initialize holder object, variant 1: object derives from enable_shared_from_this
template <typename T>
static void init_holder(detail::instance *inst, detail::value_and_holder &v_h,
const holder_type * /* unused */, const std::enable_shared_from_this<T> * /* dummy */) {
try {
auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(
v_h.value_ptr<type>()->shared_from_this());
if (sh) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
v_h.set_holder_constructed();
}
} catch (const std::bad_weak_ptr &) {}

auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(
get_shared_from_this(v_h.value_ptr<type>()));
if (sh) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
v_h.set_holder_constructed();
}

if (!v_h.holder_constructed() && inst->owned) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
Expand Down