From 8d1f30bc8499a1368bbe0894962e378dd8e530f7 Mon Sep 17 00:00:00 2001 From: Ivor Wanders Date: Tue, 7 Nov 2023 08:01:02 -0500 Subject: [PATCH] fix(smart_holder): Add unit tests for the default constructible deleter. --- tests/test_class_sh_basic.cpp | 24 ++++++++++++++++++++++-- tests/test_class_sh_basic.py | 8 ++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tests/test_class_sh_basic.cpp b/tests/test_class_sh_basic.cpp index 55d934c3470..65c81a9dd4b 100644 --- a/tests/test_class_sh_basic.cpp +++ b/tests/test_class_sh_basic.cpp @@ -28,10 +28,11 @@ struct uconsumer { // unique_ptr consumer const std::unique_ptr &rtrn_cref() const { return held; } }; +/// Custom deleter that is default constructible. struct custom_deleter { std::string trace_txt; - custom_deleter() = delete; + custom_deleter() = default; explicit custom_deleter(const std::string &trace_txt_) : trace_txt(trace_txt_) {} custom_deleter(const custom_deleter &other) { trace_txt = other.trace_txt + "_CpCtor"; } @@ -55,6 +56,14 @@ struct custom_deleter { void operator()(atyp *p) const { std::default_delete()(p); } void operator()(const atyp *p) const { std::default_delete()(p); } }; +static_assert(std::is_default_constructible::value); + +/// Custom deleter that is not default constructible. +struct custom_deleter_nd : custom_deleter { + custom_deleter_nd() = delete; + explicit custom_deleter_nd(const std::string &trace_txt_) : custom_deleter(trace_txt_) {} +}; +static_assert(!std::is_default_constructible::value); // clang-format off @@ -92,13 +101,18 @@ std::unique_ptr rtrn_udcp() { return std::unique_ptr obj) { return "pass_udmp:" + obj->mtxt; } std::string pass_udcp(std::unique_ptr obj) { return "pass_udcp:" + obj->mtxt; } - std::unique_ptr rtrn_udmp_del() { return std::unique_ptr(new atyp{"rtrn_udmp_del"}, custom_deleter{"udmp_deleter"}); } std::unique_ptr rtrn_udcp_del() { return std::unique_ptr(new atyp{"rtrn_udcp_del"}, custom_deleter{"udcp_deleter"}); } std::string pass_udmp_del(std::unique_ptr obj) { return "pass_udmp_del:" + obj->mtxt + "," + obj.get_deleter().trace_txt; } std::string pass_udcp_del(std::unique_ptr obj) { return "pass_udcp_del:" + obj->mtxt + "," + obj.get_deleter().trace_txt; } +std::unique_ptr rtrn_udmp_del_nd() { return std::unique_ptr(new atyp{"rtrn_udmp_del_nd"}, custom_deleter_nd{"udmp_deleter_nd"}); } +std::unique_ptr rtrn_udcp_del_nd() { return std::unique_ptr(new atyp{"rtrn_udcp_del_nd"}, custom_deleter_nd{"udcp_deleter_nd"}); } + +std::string pass_udmp_del_nd(std::unique_ptr obj) { return "pass_udmp_del_nd:" + obj->mtxt + "," + obj.get_deleter().trace_txt; } +std::string pass_udcp_del_nd(std::unique_ptr obj) { return "pass_udcp_del_nd:" + obj->mtxt + "," + obj.get_deleter().trace_txt; } + // clang-format on // Helpers for testing. @@ -171,6 +185,12 @@ TEST_SUBMODULE(class_sh_basic, m) { m.def("pass_udmp_del", pass_udmp_del); m.def("pass_udcp_del", pass_udcp_del); + m.def("rtrn_udmp_del_nd", rtrn_udmp_del_nd); + m.def("rtrn_udcp_del_nd", rtrn_udcp_del_nd); + + m.def("pass_udmp_del_nd", pass_udmp_del_nd); + m.def("pass_udcp_del_nd", pass_udcp_del_nd); + py::classh(m, "uconsumer") .def(py::init<>()) .def("valid", &uconsumer::valid) diff --git a/tests/test_class_sh_basic.py b/tests/test_class_sh_basic.py index 5f441508915..b3e9709dd24 100644 --- a/tests/test_class_sh_basic.py +++ b/tests/test_class_sh_basic.py @@ -68,8 +68,12 @@ def test_load_with_rtrn_f(pass_f, rtrn_f, expected): @pytest.mark.parametrize( ("pass_f", "rtrn_f", "expected"), [ - (m.pass_udmp_del, m.rtrn_udmp_del, "pass_udmp_del:rtrn_udmp_del,udmp_deleter_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo"), - (m.pass_udcp_del, m.rtrn_udcp_del, "pass_udcp_del:rtrn_udcp_del,udcp_deleter_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo_MvCtorTo"), + (m.pass_udmp_del, m.rtrn_udmp_del, "pass_udmp_del:rtrn_udmp_del,udmp_deleter_" + "_".join(["MvCtorTo"] * 6)), + (m.pass_udcp_del, m.rtrn_udcp_del, "pass_udcp_del:rtrn_udcp_del,udcp_deleter_" + "_".join(["MvCtorTo"] * 8)), + (m.pass_udmp_del_nd, m.rtrn_udmp_del_nd, + "pass_udmp_del_nd:rtrn_udmp_del_nd,udmp_deleter_nd_" + "_".join(["MvCtorTo"] * 6)), + (m.pass_udcp_del_nd, m.rtrn_udcp_del_nd, + "pass_udcp_del_nd:rtrn_udcp_del_nd,udcp_deleter_nd_" + "_".join(["MvCtorTo"] * 8)), ], ) def test_deleter_roundtrip(pass_f, rtrn_f, expected):