#include #include #include "pybind11_tests.h" namespace pybind11_tests { // Could this be a holder for a `class_`-like `vclass`? // To enable passing of unique_ptr as in pure C++. template class vptr_holder { public: explicit vptr_holder(T *ptr = nullptr) : vptr_{std::unique_ptr(ptr)} {} explicit vptr_holder(std::unique_ptr u) : vptr_{std::move(u)} {} explicit vptr_holder(std::shared_ptr s) : vptr_{s} {} int ownership_type() const { if (std::get_if<0>(&vptr_)) { return 0; } if (std::get_if<1>(&vptr_)) { return 1; } return -1; } T *get() { auto u = std::get_if<0>(&vptr_); if (u) { return u->get(); } auto s = std::get_if<1>(&vptr_); if (s) { return s->get(); } return nullptr; } std::unique_ptr get_unique() { auto u = std::get_if<0>(&vptr_); if (u) { return std::move(*u); } throw std::runtime_error("get_unique failure."); } std::shared_ptr get_shared() { auto s = std::get_if<1>(&vptr_); if (s) { return *s; } auto u = std::get_if<0>(&vptr_); if (u) { auto result = std::shared_ptr(std::move(*u)); vptr_ = result; return result; } throw std::runtime_error("get_shared failure."); } private: std::variant, std::shared_ptr> vptr_; }; vptr_holder from_raw() { return vptr_holder{new double{3}}; } vptr_holder from_unique() { return vptr_holder{std::unique_ptr(new double{5})}; } vptr_holder from_shared() { return vptr_holder{std::shared_ptr(new double{7})}; } TEST_SUBMODULE(variant_unique_shared, m) { m.def("from_raw", from_raw); m.def("from_unique", from_unique); m.def("from_shared", from_shared); py::class_>(m, "vptr_holder_double") .def(py::init<>()) .def("ownership_type", &vptr_holder::ownership_type) .def("get_value", [](vptr_holder &v) { auto p = v.get(); if (p) return *p; return -1.; }) .def("get_unique", [](vptr_holder &v) { v.get_unique(); return; }) .def("get_shared", [](vptr_holder &v) { v.get_shared(); return; }); } } // namespace pybind11_tests