From dcd1286bdb6b8db066d0cb4037d9f40cbc1aaa0e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 30 Jul 2024 00:19:58 -0700 Subject: [PATCH] Use `with_internals` for all accesses to `internals.native_enum_type_map` --- include/pybind11/cast.h | 27 +++++++++++----------- include/pybind11/detail/native_enum_data.h | 26 ++++++++++++++++++++- include/pybind11/native_enum.h | 2 +- include/pybind11/pybind11.h | 4 ++-- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c35cdce7..4c97515f 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -88,10 +88,10 @@ class type_caster_enum_type { template static handle cast(SrcType &&src, return_value_policy, handle parent) { - auto const &natives = get_internals().native_enum_type_map; - auto found = natives.find(std::type_index(typeid(EnumType))); - if (found != natives.end()) { - return handle(found->second)(static_cast(src)).release(); + handle native_enum + = global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType))); + if (native_enum) { + return native_enum(static_cast(src)).release(); } return type_caster_for_class_::cast( std::forward(src), @@ -101,10 +101,10 @@ class type_caster_enum_type { } bool load(handle src, bool convert) { - auto const &natives = get_internals().native_enum_type_map; - auto found = natives.find(std::type_index(typeid(EnumType))); - if (found != natives.end()) { - if (!isinstance(src, found->second)) { + handle native_enum + = global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType))); + if (native_enum) { + if (!isinstance(src, native_enum)) { return false; } type_caster underlying_caster; @@ -180,12 +180,11 @@ struct type_caster_classh_enum_aware< template ::value, int> = 0> bool isinstance_native_enum_impl(handle obj, const std::type_info &tp) { - auto const &natives = get_internals().native_enum_type_map; - auto found = natives.find(tp); - if (found == natives.end()) { + handle native_enum = global_internals_native_enum_type_map_get_item(tp); + if (!native_enum) { return false; } - return isinstance(obj, found->second); + return isinstance(obj, native_enum); } template ::value, int> = 0> @@ -1351,8 +1350,8 @@ T cast(const handle &handle) { "Unable to cast type to reference: value is local to type caster"); #ifndef NDEBUG if (is_enum_cast && cast_is_temporary_value_reference::value) { - auto const &natives = get_internals().native_enum_type_map; - if (natives.count(std::type_index(typeid(intrinsic_t))) != 0) { + if (detail::global_internals_native_enum_type_map_contains( + std::type_index(typeid(intrinsic_t)))) { pybind11_fail("Unable to cast native enum type to reference"); } } diff --git a/include/pybind11/detail/native_enum_data.h b/include/pybind11/detail/native_enum_data.h index 83812622..5895dc6c 100644 --- a/include/pybind11/detail/native_enum_data.h +++ b/include/pybind11/detail/native_enum_data.h @@ -59,6 +59,30 @@ class native_enum_data { list docs; }; +inline void global_internals_native_enum_type_map_set_item(const std::type_index &enum_type_index, + PyObject *py_enum) { + with_internals( + [&](internals &internals) { internals.native_enum_type_map[enum_type_index] = py_enum; }); +} + +inline handle +global_internals_native_enum_type_map_get_item(const std::type_index &enum_type_index) { + return with_internals([&](internals &internals) { + auto found = internals.native_enum_type_map.find(enum_type_index); + if (found != internals.native_enum_type_map.end()) { + return handle(found->second); + } + return handle(); + }); +} + +inline bool +global_internals_native_enum_type_map_contains(const std::type_index &enum_type_index) { + return with_internals([&](internals &internals) { + return internals.native_enum_type_map.count(enum_type_index) != 0; + }); +} + inline void native_enum_add_to_parent(const object &parent, const detail::native_enum_data &data) { data.disarm_correct_use_check(); if (hasattr(parent, data.enum_name)) { @@ -92,7 +116,7 @@ inline void native_enum_add_to_parent(const object &parent, const detail::native for (auto doc : data.docs) { py_enum[doc[int_(0)]].attr("__doc__") = doc[int_(1)]; } - get_internals().native_enum_type_map[data.enum_type_index] = py_enum.release().ptr(); + global_internals_native_enum_type_map_set_item(data.enum_type_index, py_enum.release().ptr()); } PYBIND11_NAMESPACE_END(detail) diff --git a/include/pybind11/native_enum.h b/include/pybind11/native_enum.h index e05f7bce..a4120a2c 100644 --- a/include/pybind11/native_enum.h +++ b/include/pybind11/native_enum.h @@ -32,7 +32,7 @@ class native_enum : public detail::native_enum_data { "pybind11::native_enum<...>(\"" + enum_name_encoded + "\") is already registered as a `pybind11::enum_` or `pybind11::class_`!"); } - if (detail::get_internals().native_enum_type_map.count(enum_type_index)) { + if (detail::global_internals_native_enum_type_map_contains(enum_type_index)) { pybind11_fail("pybind11::native_enum<...>(\"" + enum_name_encoded + "\") is already registered!"); } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 09106dc4..32f82fe5 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2614,8 +2614,8 @@ class enum_ : public class_ { enum_(const handle &scope, const char *name, const Extra &...extra) : class_(scope, name, extra...), m_base(*this, scope) { { - if (detail::get_internals().native_enum_type_map.count(std::type_index(typeid(Type))) - != 0) { + if (detail::global_internals_native_enum_type_map_contains( + std::type_index(typeid(Type)))) { pybind11_fail("pybind11::enum_ \"" + std::string(name) + "\" is already registered as a pybind11::native_enum!"); }