From 0c9b6489cd3fe8a0a5a858e364983e99b06101ce Mon Sep 17 00:00:00 2001 From: Wilfried Karel Date: Thu, 9 Nov 2023 13:13:36 +0100 Subject: [PATCH] type_caster: support non-assignable types (#358) --- include/nanobind/stl/optional.h | 2 +- tests/test_stl.cpp | 11 +++++++++++ tests/test_stl.py | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/nanobind/stl/optional.h b/include/nanobind/stl/optional.h index 9e63b9f9..64c62ae0 100644 --- a/include/nanobind/stl/optional.h +++ b/include/nanobind/stl/optional.h @@ -45,7 +45,7 @@ struct type_caster> { "type caster was registered to intercept this particular " "type, which is not allowed."); - value = caster.operator cast_t(); + value.emplace(caster.operator cast_t()); return true; } diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index 1ede2e56..8a46d2af 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp @@ -44,6 +44,12 @@ struct Copyable { ~Copyable() { destructed++; } }; +struct NonAssignable { + int value = 5; + + NonAssignable &operator=(const NonAssignable &) = delete; +}; + struct StructWithReadonlyMap { std::map map; }; @@ -102,6 +108,10 @@ NB_MODULE(test_stl_ext, m) { .def(nb::init()) .def_rw("value", &Copyable::value); + nb::class_(m, "NonAssignable") + .def(nb::init<>()) + .def_rw("value", &NonAssignable::value); + nb::class_(m, "StructWithReadonlyMap") .def(nb::init<>()) .def_ro("map", &StructWithReadonlyMap::map); @@ -254,6 +264,7 @@ NB_MODULE(test_stl_ext, m) { m.def("optional_ret_opt_none", []() { return std::optional(); }); m.def("optional_unbound_type", [](std::optional &x) { return x; }, nb::arg("x") = nb::none()); m.def("optional_unbound_type_with_nullopt_as_default", [](std::optional &x) { return x; }, nb::arg("x") = std::nullopt); + m.def("optional_non_assignable", [](std::optional &x) { return x; }); // ----- test43-test50 ------ m.def("variant_copyable", [](std::variant &) {}); diff --git a/tests/test_stl.py b/tests/test_stl.py index e591973e..cc32f21a 100644 --- a/tests/test_stl.py +++ b/tests/test_stl.py @@ -448,6 +448,10 @@ def test42_std_optional_unbound_type(): ) +def test42a_std_optional_non_assignable(): + assert t.optional_non_assignable(t.NonAssignable()).value == 5 + + def test43_std_variant_copyable(clean): t.variant_copyable(t.Copyable()) t.variant_copyable(5)