diff --git a/tests/test_holder_shared_ptr.cpp b/tests/test_holder_shared_ptr.cpp new file mode 100644 index 000000000..ff248310e --- /dev/null +++ b/tests/test_holder_shared_ptr.cpp @@ -0,0 +1,69 @@ +// KEEP IN SYNC WITH test_holder_unique_ptr.cpp + +#include "pybind11_tests.h" + +#include +#include + +namespace pybind11_tests { +namespace holder_shared_ptr { + +inline void to_cout(std::string text) { std::cout << text << std::endl; } + +class pointee { // NOT copyable. + public: + pointee() { to_cout("pointee::pointee()"); } + + int get_int() const { + to_cout("pointee::get_int()"); + return 213; + } + + ~pointee() { to_cout("~pointee()"); } + + private: + pointee(const pointee &) = delete; + pointee(pointee &&) = delete; + pointee &operator=(const pointee &) = delete; + pointee &operator=(pointee &&) = delete; +}; + +inline std::unique_ptr make_unique_pointee() { + return std::unique_ptr(new pointee); +} + +inline std::shared_ptr make_shared_pointee() { + return std::unique_ptr(new pointee); +} + +inline int pass_unique_pointee(std::unique_ptr ptr) { + return 4000 + ptr->get_int(); +} + +inline int pass_shared_pointee(std::shared_ptr ptr) { + return 5000 + ptr->get_int(); +} + +inline pointee* get_static_pointee() { + static pointee cpp_instance; + return &cpp_instance; +} + +TEST_SUBMODULE(holder_shared_ptr, m) { + m.def("to_cout", to_cout); + + py::class_>(m, "pointee") + .def(py::init<>()) + .def("get_int", &pointee::get_int); + + m.def("make_unique_pointee", make_unique_pointee); + m.def("make_shared_pointee", make_shared_pointee); + // m.def("pass_unique_pointee", pass_unique_pointee); + m.def("pass_shared_pointee", pass_shared_pointee); + + m.def("get_static_pointee", + get_static_pointee, py::return_value_policy::reference); +} + +} // namespace holder_shared_ptr +} // namespace pybind11_tests diff --git a/tests/test_holder_shared_ptr.py b/tests/test_holder_shared_ptr.py new file mode 100644 index 000000000..78aa2d1a5 --- /dev/null +++ b/tests/test_holder_shared_ptr.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# KEEP IN SYNC WITH test_holder_unique_ptr.py +import pytest + +from pybind11_tests import holder_shared_ptr as m + + +def test_make_unique_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("make_unique_pointee") + obj = m.make_unique_pointee() + assert obj.get_int() == 213 + m.to_cout("") + + +def test_make_shared_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("make_shared_pointee") + obj = m.make_shared_pointee() + assert obj.get_int() == 213 + m.to_cout("") + + +def test_pass_unique_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("pass_unique_pointee") + obj = m.make_shared_pointee() + assert obj.get_int() == 213 + i = m.pass_unique_pointee(obj) + assert i == 4213 + m.to_cout("") + + +def test_pass_shared_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("pass_shared_pointee") + obj = m.make_shared_pointee() + assert obj.get_int() == 213 + i = m.pass_shared_pointee(obj) + assert i == 5213 + m.to_cout("") + + +def test_get_static_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("get_static_pointee") + obj = m.get_static_pointee() + assert obj.get_int() == 213 + with pytest.raises(RuntimeError) as excinfo: + m.pass_shared_pointee(obj) + assert "Unable to cast from non-held to held instance" in str(excinfo.value) diff --git a/tests/test_holder_unique_ptr.cpp b/tests/test_holder_unique_ptr.cpp new file mode 100644 index 000000000..d59066416 --- /dev/null +++ b/tests/test_holder_unique_ptr.cpp @@ -0,0 +1,69 @@ +// KEEP IN SYNC WITH test_holder_shared_ptr.cpp + +#include "pybind11_tests.h" + +#include +#include + +namespace pybind11_tests { +namespace holder_unique_ptr { + +inline void to_cout(std::string text) { std::cout << text << std::endl; } + +class pointee { // NOT copyable. + public: + pointee() { to_cout("pointee::pointee()"); } + + int get_int() const { + to_cout("pointee::get_int()"); + return 213; + } + + ~pointee() { to_cout("~pointee()"); } + + private: + pointee(const pointee &) = delete; + pointee(pointee &&) = delete; + pointee &operator=(const pointee &) = delete; + pointee &operator=(pointee &&) = delete; +}; + +inline std::unique_ptr make_unique_pointee() { + return std::unique_ptr(new pointee); +} + +inline std::shared_ptr make_shared_pointee() { + return std::unique_ptr(new pointee); +} + +inline int pass_unique_pointee(std::unique_ptr ptr) { + return 4000 + ptr->get_int(); +} + +inline int pass_shared_pointee(std::shared_ptr ptr) { + return 5000 + ptr->get_int(); +} + +inline pointee* get_static_pointee() { + static pointee cpp_instance; + return &cpp_instance; +} + +TEST_SUBMODULE(holder_unique_ptr, m) { + m.def("to_cout", to_cout); + + py::class_(m, "pointee") + .def(py::init<>()) + .def("get_int", &pointee::get_int); + + m.def("make_unique_pointee", make_unique_pointee); + m.def("make_shared_pointee", make_shared_pointee); + // m.def("pass_unique_pointee", pass_unique_pointee); + m.def("pass_shared_pointee", pass_shared_pointee); + + m.def("get_static_pointee", + get_static_pointee, py::return_value_policy::reference); +} + +} // namespace holder_unique_ptr +} // namespace pybind11_tests diff --git a/tests/test_holder_unique_ptr.py b/tests/test_holder_unique_ptr.py new file mode 100644 index 000000000..a82c3fda2 --- /dev/null +++ b/tests/test_holder_unique_ptr.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# KEEP IN SYNC WITH test_holder_shared_ptr.py +import pytest + +from pybind11_tests import holder_unique_ptr as m + + +def test_make_unique_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("make_unique_pointee") + obj = m.make_unique_pointee() + assert obj.get_int() == 213 + m.to_cout("") + + +def test_make_shared_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("make_shared_pointee") + obj = m.make_shared_pointee() + assert obj.get_int() == 213 + m.to_cout("") + + +def test_pass_unique_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("pass_unique_pointee") + obj = m.make_unique_pointee() + assert obj.get_int() == 213 + i = m.pass_unique_pointee(obj) + assert i == 4213 + m.to_cout("") + + +def test_pass_shared_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("pass_shared_pointee") + obj = m.make_unique_pointee() + assert obj.get_int() == 213 + i = m.pass_shared_pointee(obj) + assert i == 5213 + m.to_cout("") + + +def test_get_static_pointee(): + m.to_cout("") + m.to_cout("") + m.to_cout("get_static_pointee") + obj = m.get_static_pointee() + assert obj.get_int() == 213 + with pytest.raises(RuntimeError) as excinfo: + m.pass_unique_pointee(obj) + assert "Unable to cast from non-held to held instance" in str(excinfo.value)