From 92ae0e9434d873255d913def37dcee2578824c23 Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Fri, 10 Oct 2025 19:57:43 -0600 Subject: [PATCH] Avoid a heap allocation on every legacy py::enum_ load --- include/pybind11/cast.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 7b014fed99..785e27fc9f 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -93,37 +93,37 @@ class type_caster_enum_type { if (!underlying_caster.load(src.attr("value"), convert)) { pybind11_fail("native_enum internal consistency failure."); } - value = static_cast(static_cast(underlying_caster)); + native_value = static_cast(static_cast(underlying_caster)); + native_loaded = true; return true; } - if (!pybind11_enum_) { - pybind11_enum_.reset(new type_caster_base()); + + type_caster_base legacy_caster; + if (legacy_caster.load(src, convert)) { + legacy_ptr = static_cast(legacy_caster); + return true; } - return pybind11_enum_->load(src, convert); + return false; } template using cast_op_type = detail::cast_op_type; // NOLINTNEXTLINE(google-explicit-constructor) - operator EnumType *() { - if (!pybind11_enum_) { - return &value; - } - return pybind11_enum_->operator EnumType *(); - } + operator EnumType *() { return native_loaded ? &native_value : legacy_ptr; } // NOLINTNEXTLINE(google-explicit-constructor) operator EnumType &() { - if (!pybind11_enum_) { - return value; + if (!native_loaded && !legacy_ptr) { + throw reference_cast_error(); } - return pybind11_enum_->operator EnumType &(); + return native_loaded ? native_value : *legacy_ptr; } private: - std::unique_ptr> pybind11_enum_; - EnumType value; + EnumType native_value; // if loading a py::native_enum + bool native_loaded = false; + EnumType *legacy_ptr = nullptr; // if loading a py::enum_ }; template