From 2c9124bbbe736881fa8f9f33ea7817c98b43bf8b Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Sat, 3 Jun 2023 15:42:22 +0200 Subject: [PATCH] ignore duplicate bind_vector/bind_map declarations --- docs/api_extra.rst | 6 ++++++ include/nanobind/stl/bind_map.h | 6 ++++++ include/nanobind/stl/bind_vector.h | 6 ++++++ tests/test_stl_bind_vector.cpp | 3 +++ 4 files changed, 21 insertions(+) diff --git a/docs/api_extra.rst b/docs/api_extra.rst index dd2da657..29aee3dd 100644 --- a/docs/api_extra.rst +++ b/docs/api_extra.rst @@ -243,6 +243,9 @@ include directive: not comparable or copy-assignable, some of these functions will not be generated. + The binding operation is a no-op if the vector type has already been + registered with nanobind. + .. _map_bindings: STL map bindings @@ -308,6 +311,9 @@ nanobind API and require an additional include directive: * - ``items(self, arg: Map) -> Map.ItemView`` - Returns an iterable view of the map's items + The binding operation is a no-op if the map type has already been + registered with nanobind. + Unique pointer deleter ---------------------- diff --git a/include/nanobind/stl/bind_map.h b/include/nanobind/stl/bind_map.h index 9cd2de03..b598bd3a 100644 --- a/include/nanobind/stl/bind_map.h +++ b/include/nanobind/stl/bind_map.h @@ -42,6 +42,12 @@ class_ bind_map(handle scope, const char *name, Args &&...args) { using Key = typename Map::key_type; using Value = typename Map::mapped_type; + handle cl_cur = type(); + if (cl_cur.is_valid()) { + // Binding already exists, don't re-create + return borrow>(cl_cur); + } + auto cl = class_(scope, name, std::forward(args)...) .def(init<>(), "Default constructor") diff --git a/include/nanobind/stl/bind_vector.h b/include/nanobind/stl/bind_vector.h index d720c734..e7088120 100644 --- a/include/nanobind/stl/bind_vector.h +++ b/include/nanobind/stl/bind_vector.h @@ -48,6 +48,12 @@ class_ bind_vector(handle scope, const char *name, Args &&...args) { using ValueRef = typename detail::iterator_access::result_type; using Value = std::decay_t; + handle cl_cur = type(); + if (cl_cur.is_valid()) { + // Binding already exists, don't re-create + return borrow>(cl_cur); + } + auto cl = class_(scope, name, std::forward(args)...) .def(init<>(), "Default constructor") diff --git a/tests/test_stl_bind_vector.cpp b/tests/test_stl_bind_vector.cpp index 3ca76bad..98b6c052 100644 --- a/tests/test_stl_bind_vector.cpp +++ b/tests/test_stl_bind_vector.cpp @@ -8,6 +8,9 @@ NB_MODULE(test_bind_vector_ext, m) { nb::bind_vector>(m, "VectorInt"); nb::bind_vector>(m, "VectorBool"); + // Ensure that a repeated binding call is ignored + nb::bind_vector>(m, "VectorBool"); + struct El { explicit El(int v) : a(v) {} int a;