From ba57555b6f691ee5c6741acbaba8b47a52b74579 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 26 Mar 2026 13:13:16 -1000 Subject: [PATCH] Make compat owned vectors skip-on-copy to eliminate copy overhead Wrap the deprecated owned vectors in a struct with a no-op copy constructor. This way ClimateTraits copies (which happen on every get_traits() call) don't pay the 48-byte cost of copying two empty vectors. The compat data only matters for the original traits object where the deprecated setter was called. --- esphome/components/climate/climate_traits.h | 34 +++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/esphome/components/climate/climate_traits.h b/esphome/components/climate/climate_traits.h index 5cc4aa470c8..4b8a67cf6f0 100644 --- a/esphome/components/climate/climate_traits.h +++ b/esphome/components/climate/climate_traits.h @@ -159,18 +159,18 @@ class ClimateTraits { // Remove before 2026.11.0 ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_fan_modes(std::initializer_list modes) { - this->owned_custom_fan_modes_ = modes; - this->supported_custom_fan_modes_ = &this->owned_custom_fan_modes_; + this->owned_custom_modes_.fan_modes = modes; + this->supported_custom_fan_modes_ = &this->owned_custom_modes_.fan_modes; } // Remove before 2026.11.0 ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_fan_modes(const std::vector &modes) { - this->owned_custom_fan_modes_ = modes; - this->supported_custom_fan_modes_ = &this->owned_custom_fan_modes_; + this->owned_custom_modes_.fan_modes = modes; + this->supported_custom_fan_modes_ = &this->owned_custom_modes_.fan_modes; } const std::vector &get_supported_custom_fan_modes() const { - return this->supported_custom_fan_modes_ ? *this->supported_custom_fan_modes_ : this->owned_custom_fan_modes_; + return this->supported_custom_fan_modes_ ? *this->supported_custom_fan_modes_ : this->owned_custom_modes_.fan_modes; } bool supports_custom_fan_mode(const char *custom_fan_mode) const { return this->supported_custom_fan_modes_ && vector_contains(*this->supported_custom_fan_modes_, custom_fan_mode); @@ -192,18 +192,18 @@ class ClimateTraits { // Remove before 2026.11.0 ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_presets(std::initializer_list presets) { - this->owned_custom_presets_ = presets; - this->supported_custom_presets_ = &this->owned_custom_presets_; + this->owned_custom_modes_.presets = presets; + this->supported_custom_presets_ = &this->owned_custom_modes_.presets; } // Remove before 2026.11.0 ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_presets(const std::vector &presets) { - this->owned_custom_presets_ = presets; - this->supported_custom_presets_ = &this->owned_custom_presets_; + this->owned_custom_modes_.presets = presets; + this->supported_custom_presets_ = &this->owned_custom_modes_.presets; } const std::vector &get_supported_custom_presets() const { - return this->supported_custom_presets_ ? *this->supported_custom_presets_ : this->owned_custom_presets_; + return this->supported_custom_presets_ ? *this->supported_custom_presets_ : this->owned_custom_modes_.presets; } bool supports_custom_preset(const char *custom_preset) const { return this->supported_custom_presets_ && vector_contains(*this->supported_custom_presets_, custom_preset); @@ -309,8 +309,18 @@ class ClimateTraits { */ const std::vector *supported_custom_fan_modes_{nullptr}; const std::vector *supported_custom_presets_{nullptr}; - std::vector owned_custom_fan_modes_{}; ///< Compat: used when deprecated setters are called on traits - std::vector owned_custom_presets_{}; ///< Compat: used when deprecated setters are called on traits + /** Compat storage for deprecated setters — skipped on copy to avoid overhead. + * Remove in 2026.11.0 along with the deprecated overloads. + */ + struct OwnedCustomModes { + std::vector fan_modes; + std::vector presets; + OwnedCustomModes() = default; + OwnedCustomModes(const OwnedCustomModes &) {} // NOLINT - no-op copy: compat data is not propagated + OwnedCustomModes &operator=(const OwnedCustomModes &) { return *this; } // NOLINT + OwnedCustomModes(OwnedCustomModes &&) = default; + OwnedCustomModes &operator=(OwnedCustomModes &&) = default; + } owned_custom_modes_; }; } // namespace esphome::climate