diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index 7f620f27a..23e05bacf 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -168,6 +168,42 @@ void construct(value_and_holder &v_h, Alias &&result, bool) { v_h.value_ptr() = new Alias(std::move(result)); } +//DETAIL/SMART_HOLDER_INIT_H/BEGIN///////////////////////////////////////////////////////////////// + +template >, + detail::enable_if_t>::value, int> = 0> +void construct(value_and_holder &v_h, std::unique_ptr, D> &&unq_ptr, bool need_alias) { + auto *ptr = unq_ptr.get(); + no_nullptr(ptr); + // If we need an alias, check that the held pointer is actually an alias instance + if (Class::has_alias && need_alias && !is_alias(ptr)) + throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " + "is not an alias instance"); + + auto smhldr = pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr)); + + v_h.value_ptr() = ptr; + v_h.type->init_instance(v_h.inst, &smhldr); +} + +template >::value, int> = 0> +void construct(value_and_holder &v_h, std::shared_ptr> &&shd_ptr, bool need_alias) { + auto *ptr = shd_ptr.get(); + no_nullptr(ptr); + // If we need an alias, check that the held pointer is actually an alias instance + if (Class::has_alias && need_alias && !is_alias(ptr)) + throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " + "is not an alias instance"); + + auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(std::move(shd_ptr)); + + v_h.value_ptr() = ptr; + v_h.type->init_instance(v_h.inst, &smhldr); +} + +//DETAIL/SMART_HOLDER_INIT_H/END/////////////////////////////////////////////////////////////////// + // Implementing class for py::init<...>() template struct constructor { diff --git a/tests/test_class_sh_factory_constructors.cpp b/tests/test_class_sh_factory_constructors.cpp index 1cf45087f..33bb50af2 100644 --- a/tests/test_class_sh_factory_constructors.cpp +++ b/tests/test_class_sh_factory_constructors.cpp @@ -63,11 +63,11 @@ PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constru PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_mref) PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_cptr) PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_mptr) -// PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_shmp) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_shmp) PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_shcp) -// PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_uqmp) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_uqmp) PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_uqcp) -// PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_udmp) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_udmp) PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::test_class_sh_factory_constructors::atyp_udcp) TEST_SUBMODULE(class_sh_factory_constructors, m) { @@ -103,23 +103,18 @@ TEST_SUBMODULE(class_sh_factory_constructors, m) { .def(py::init(&rtrn_mptr)) .def("get_mtxt", get_mtxt); - // NEEDED FOR FEATURE PARITY: shmp - py::class_>(m, "atyp_shmp") - // py::classh(m, "atyp_shmp") - // classh: ... cannot pass object of non-trivial type ... + py::classh(m, "atyp_shmp") .def(py::init(&rtrn_shmp)) .def("get_mtxt", get_mtxt); - // py::class_>(m, "atyp_shcp") py::classh(m, "atyp_shcp") + // py::class_>(m, "atyp_shcp") // class_: ... must return a compatible ... // classh: ... cannot pass object of non-trivial type ... // .def(py::init(&rtrn_shcp)) .def("get_mtxt", get_mtxt); - // NEEDED FOR FEATURE PARITY: uqmp - py::class_(m, "atyp_uqmp") - // classh: ... cannot pass object of non-trivial type ... + py::classh(m, "atyp_uqmp") .def(py::init(&rtrn_uqmp)) .def("get_mtxt", get_mtxt); @@ -129,15 +124,12 @@ TEST_SUBMODULE(class_sh_factory_constructors, m) { // .def(py::init(&rtrn_uqcp)) .def("get_mtxt", get_mtxt); - // NEEDED FOR FEATURE PARITY: udmp - py::class_>(m, "atyp_udmp") - // py::classh(m, "atyp_udmp") - // classh: ... cannot pass object of non-trivial type ... + py::classh(m, "atyp_udmp") .def(py::init(&rtrn_udmp)) .def("get_mtxt", get_mtxt); - // py::class_>(m, "atyp_udcp") py::classh(m, "atyp_udcp") + // py::class_>(m, "atyp_udcp") // class_: ... must return a compatible ... // classh: ... cannot pass object of non-trivial type ... // .def(py::init(&rtrn_udcp))