#include #include "pybind11_tests.h" #include namespace pybind11_tests { namespace class_sh_trampoline_basic { template // Using int as a trick to easily generate a series of types. struct Abase { int val = 0; virtual ~Abase() = default; explicit Abase(int val_) : val{val_} {} int Get() const { return val * 10 + 3; } virtual int Add(int other_val) const = 0; // Some compilers complain about implicitly defined versions of some of the following: Abase(const Abase &) = default; Abase(Abase &&) noexcept = default; Abase &operator=(const Abase &) = default; Abase &operator=(Abase &&) noexcept = default; }; template struct AbaseAlias : Abase { using Abase::Abase; int Add(int other_val) const override { PYBIND11_OVERRIDE_PURE(int, /* Return type */ Abase, /* Parent class */ Add, /* Name of function in C++ (must match Python name) */ other_val); } }; #ifdef PYBIND11_SMART_HOLDER_ENABLED template <> struct AbaseAlias<1> : Abase<1>, py::trampoline_self_life_support { using Abase<1>::Abase; int Add(int other_val) const override { PYBIND11_OVERRIDE_PURE(int, /* Return type */ Abase<1>, /* Parent class */ Add, /* Name of function in C++ (must match Python name) */ other_val); } }; #endif // PYBIND11_SMART_HOLDER_ENABLED template int AddInCppRawPtr(const Abase *obj, int other_val) { return obj->Add(other_val) * 10 + 7; } template int AddInCppSharedPtr(std::shared_ptr> obj, int other_val) { return obj->Add(other_val) * 100 + 11; } template int AddInCppUniquePtr(std::unique_ptr> obj, int other_val) { return obj->Add(other_val) * 100 + 13; } #ifdef PYBIND11_SMART_HOLDER_ENABLED template void wrap(py::module_ m, const char *py_class_name) { py::classh, AbaseAlias>(m, py_class_name) .def(py::init(), py::arg("val")) .def("Get", &Abase::Get) .def("Add", &Abase::Add, py::arg("other_val")); m.def("AddInCppRawPtr", AddInCppRawPtr, py::arg("obj"), py::arg("other_val")); m.def("AddInCppSharedPtr", AddInCppSharedPtr, py::arg("obj"), py::arg("other_val")); m.def("AddInCppUniquePtr", AddInCppUniquePtr, py::arg("obj"), py::arg("other_val")); } #endif } // namespace class_sh_trampoline_basic } // namespace pybind11_tests using namespace pybind11_tests::class_sh_trampoline_basic; PYBIND11_SMART_HOLDER_TYPE_CASTERS(Abase<0>) PYBIND11_SMART_HOLDER_TYPE_CASTERS(Abase<1>) TEST_SUBMODULE(class_sh_trampoline_basic, m) { m.attr("defined_PYBIND11_SMART_HOLDER_ENABLED") = #ifndef PYBIND11_SMART_HOLDER_ENABLED false; #else true; wrap<0>(m, "Abase0"); wrap<1>(m, "Abase1"); #endif // PYBIND11_SMART_HOLDER_ENABLED }