diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index 75d25c119..a2cfd8e61 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -156,8 +156,7 @@ void construct(value_and_holder &v_h, Alias *alias_ptr, bool) { // holder. This also handles types like std::shared_ptr and std::unique_ptr where T is a // derived type (through those holder's implicit conversion from derived class holder // constructors). -template , smart_holder>::value, int> = 0> +template >::value, int> = 0> void construct(value_and_holder &v_h, Holder holder, bool need_alias) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias); auto *ptr = holder_helper>::get(holder); @@ -199,6 +198,8 @@ void construct(value_and_holder &v_h, Alias &&result, bool) { v_h.value_ptr() = new Alias(std::move(result)); } +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + namespace originally_smart_holder_type_casters_h { template smart_holder smart_holder_from_unique_ptr(std::unique_ptr &&unq_ptr, @@ -215,7 +216,7 @@ smart_holder smart_holder_from_shared_ptr(std::shared_ptr shd_ptr) { template >, - detail::enable_if_t, smart_holder>::value, int> = 0> + detail::enable_if_t>::value, int> = 0> void construct(value_and_holder &v_h, std::unique_ptr, D> &&unq_ptr, bool need_alias) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias); auto *ptr = unq_ptr.get(); @@ -237,7 +238,7 @@ void construct(value_and_holder &v_h, std::unique_ptr, D> &&unq_ptr, template >, - detail::enable_if_t, smart_holder>::value, int> = 0> + detail::enable_if_t>::value, int> = 0> void construct(value_and_holder &v_h, std::unique_ptr, D> &&unq_ptr, bool /*need_alias*/) { @@ -249,8 +250,7 @@ void construct(value_and_holder &v_h, v_h.type->init_instance(v_h.inst, &smhldr); } -template , smart_holder>::value, int> = 0> +template >::value, int> = 0> void construct(value_and_holder &v_h, std::shared_ptr> &&shd_ptr, bool need_alias) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias); auto *ptr = shd_ptr.get(); @@ -264,8 +264,7 @@ void construct(value_and_holder &v_h, std::shared_ptr> &&shd_ptr, boo v_h.type->init_instance(v_h.inst, &smhldr); } -template , smart_holder>::value, int> = 0> +template >::value, int> = 0> void construct(value_and_holder &v_h, std::shared_ptr> &&shd_ptr, bool /*need_alias*/) { @@ -276,6 +275,8 @@ void construct(value_and_holder &v_h, v_h.type->init_instance(v_h.inst, &smhldr); } +#endif // PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + // Implementing class for py::init<...>() template struct constructor { diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 1c6a82526..82a9860e0 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -472,6 +472,8 @@ inline PyThreadState *get_thread_state_unchecked() { void keep_alive_impl(handle nurse, handle patient); inline PyObject *make_new_instance(PyTypeObject *type); +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + // SMART_HOLDER_WIP: Needs refactoring of existing pybind11 code. inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo); @@ -828,6 +830,8 @@ struct load_helper : value_and_holder_helper { PYBIND11_NAMESPACE_END(smart_holder_type_caster_support) +#endif // PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + class type_caster_generic { public: PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info) diff --git a/include/pybind11/detail/using_smart_holder.h b/include/pybind11/detail/using_smart_holder.h index ef95ea7fc..c47b691d4 100644 --- a/include/pybind11/detail/using_smart_holder.h +++ b/include/pybind11/detail/using_smart_holder.h @@ -4,17 +4,30 @@ #pragma once +#include "common.h" #include "internals.h" -#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT +#include -# include "common.h" +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT # include "smart_holder_poc.h" +#endif PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT using pybindit::memory::smart_holder; - -PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) - #endif + +PYBIND11_NAMESPACE_BEGIN(detail) + +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT +template +using is_smart_holder = std::is_same; +#else +template +struct is_smart_holder : std::false_type {}; +#endif + +PYBIND11_NAMESPACE_END(detail) +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 6fb8ca6f8..d79b36b02 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2194,7 +2194,7 @@ private: /// an optional pointer to an existing holder to use; if not specified and the instance is /// `.owned`, a new holder will be constructed to manage the value pointer. template ::value, int> = 0> + detail::enable_if_t::value, int> = 0> 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))); if (!v_h.instance_registered()) { @@ -2229,8 +2229,9 @@ private: return true; } +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT template ::value, int> = 0> + detail::enable_if_t::value, int> = 0> static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) { // Need for const_cast is a consequence of the type_info::init_instance type: // void (*init_instance)(instance *, const void *); @@ -2263,6 +2264,7 @@ private: = pointee_depends_on_holder_owner; v_h.set_holder_constructed(); } +#endif // PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT /// Deallocates an instance; via holder, if constructed; otherwise via operator delete. static void dealloc(detail::value_and_holder &v_h) { diff --git a/include/pybind11/trampoline_self_life_support.h b/include/pybind11/trampoline_self_life_support.h index eac509438..068835726 100644 --- a/include/pybind11/trampoline_self_life_support.h +++ b/include/pybind11/trampoline_self_life_support.h @@ -4,9 +4,13 @@ #pragma once -#include "detail/common.h" -#include "detail/using_smart_holder.h" -#include "detail/value_and_holder.h" +#include "detail/internals.h" + +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + +# include "detail/common.h" +# include "detail/using_smart_holder.h" +# include "detail/value_and_holder.h" PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) @@ -59,3 +63,5 @@ struct trampoline_self_life_support { }; PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#endif // PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT diff --git a/tests/test_class_sh_trampoline_basic.cpp b/tests/test_class_sh_trampoline_basic.cpp index 856f274c2..faadb4024 100644 --- a/tests/test_class_sh_trampoline_basic.cpp +++ b/tests/test_class_sh_trampoline_basic.cpp @@ -34,6 +34,7 @@ struct AbaseAlias : Abase { } }; +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT template <> struct AbaseAlias<1> : Abase<1>, py::trampoline_self_life_support { using Abase<1>::Abase; @@ -45,6 +46,7 @@ struct AbaseAlias<1> : Abase<1>, py::trampoline_self_life_support { other_val); } }; +#endif // PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT template int AddInCppRawPtr(const Abase *obj, int other_val) { diff --git a/tests/test_class_sh_trampoline_self_life_support.cpp b/tests/test_class_sh_trampoline_self_life_support.cpp index 3b202deb3..9b67323f3 100644 --- a/tests/test_class_sh_trampoline_self_life_support.cpp +++ b/tests/test_class_sh_trampoline_self_life_support.cpp @@ -37,9 +37,11 @@ protected: Big5() : history{"DefaultConstructor"} {} }; +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT struct Big5Trampoline : Big5, py::trampoline_self_life_support { using Big5::Big5; }; +#endif } // namespace diff --git a/tests/test_class_sh_trampoline_shared_from_this.cpp b/tests/test_class_sh_trampoline_shared_from_this.cpp index 38b36e1b0..aaf5a8750 100644 --- a/tests/test_class_sh_trampoline_shared_from_this.cpp +++ b/tests/test_class_sh_trampoline_shared_from_this.cpp @@ -71,9 +71,11 @@ struct SftSharedPtrStash { } }; +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT struct SftTrampoline : Sft, py::trampoline_self_life_support { using Sft::Sft; }; +#endif long use_count(const std::shared_ptr &obj) { return obj.use_count(); } diff --git a/tests/test_class_sh_trampoline_unique_ptr.cpp b/tests/test_class_sh_trampoline_unique_ptr.cpp index 26ddf7750..af0fb16ef 100644 --- a/tests/test_class_sh_trampoline_unique_ptr.cpp +++ b/tests/test_class_sh_trampoline_unique_ptr.cpp @@ -32,7 +32,6 @@ private: }; #ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT - class PyClass : public Class, public py::trampoline_self_life_support { public: std::unique_ptr clone() const override { @@ -41,7 +40,6 @@ public: int foo() const override { PYBIND11_OVERRIDE_PURE(int, Class, foo); } }; - #endif } // namespace class_sh_trampoline_basic diff --git a/tests/test_class_sh_virtual_py_cpp_mix.cpp b/tests/test_class_sh_virtual_py_cpp_mix.cpp index c8477d483..f85c87b27 100644 --- a/tests/test_class_sh_virtual_py_cpp_mix.cpp +++ b/tests/test_class_sh_virtual_py_cpp_mix.cpp @@ -31,6 +31,8 @@ int get_from_cpp_plainc_ptr(const Base *b) { return b->get() + 4000; } int get_from_cpp_unique_ptr(std::unique_ptr b) { return b->get() + 5000; } +#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT + struct BaseVirtualOverrider : Base, py::trampoline_self_life_support { using Base::Base; @@ -43,6 +45,8 @@ struct CppDerivedVirtualOverrider : CppDerived, py::trampoline_self_life_support int get() const override { PYBIND11_OVERRIDE(int, CppDerived, get); } }; +#endif + } // namespace class_sh_virtual_py_cpp_mix } // namespace pybind11_tests