diff --git a/esphome/components/binary_sensor/filter.h b/esphome/components/binary_sensor/filter.h index 7ee253ead5..2d473c3b64 100644 --- a/esphome/components/binary_sensor/filter.h +++ b/esphome/components/binary_sensor/filter.h @@ -114,18 +114,16 @@ class LambdaFilter : public Filter { /** Optimized lambda filter for stateless lambdas (no capture). * * Uses function pointer instead of std::function to reduce memory overhead. - * Memory: 8 bytes (function pointer) vs 32 bytes (std::function). + * Memory: 4 bytes (function pointer on 32-bit) vs 32 bytes (std::function). */ class StatelessLambdaFilter : public Filter { public: - using stateless_lambda_filter_t = optional (*)(bool); - - explicit StatelessLambdaFilter(stateless_lambda_filter_t f) : f_(f) {} + explicit StatelessLambdaFilter(optional (*f)(bool)) : f_(f) {} optional new_value(bool value) override { return this->f_(value); } protected: - stateless_lambda_filter_t f_; + optional (*f_)(bool); }; class SettleFilter : public Filter, public Component { diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 4f0840a75e..75e28a1efe 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -299,18 +299,16 @@ class LambdaFilter : public Filter { /** Optimized lambda filter for stateless lambdas (no capture). * * Uses function pointer instead of std::function to reduce memory overhead. - * Memory: 8 bytes (function pointer) vs 32 bytes (std::function). + * Memory: 4 bytes (function pointer on 32-bit) vs 32 bytes (std::function). */ class StatelessLambdaFilter : public Filter { public: - using stateless_lambda_filter_t = optional (*)(float); - - explicit StatelessLambdaFilter(stateless_lambda_filter_t lambda_filter) : lambda_filter_(lambda_filter) {} + explicit StatelessLambdaFilter(optional (*lambda_filter)(float)) : lambda_filter_(lambda_filter) {} optional new_value(float value) override { return this->lambda_filter_(value); } protected: - stateless_lambda_filter_t lambda_filter_; + optional (*lambda_filter_)(float); }; /// A simple filter that adds `offset` to each value it receives. diff --git a/esphome/components/text_sensor/filter.h b/esphome/components/text_sensor/filter.h index d8c71379ad..85acac5c8d 100644 --- a/esphome/components/text_sensor/filter.h +++ b/esphome/components/text_sensor/filter.h @@ -65,18 +65,16 @@ class LambdaFilter : public Filter { /** Optimized lambda filter for stateless lambdas (no capture). * * Uses function pointer instead of std::function to reduce memory overhead. - * Memory: 8 bytes (function pointer) vs 32 bytes (std::function). + * Memory: 4 bytes (function pointer on 32-bit) vs 32 bytes (std::function). */ class StatelessLambdaFilter : public Filter { public: - using stateless_lambda_filter_t = optional (*)(std::string); - - explicit StatelessLambdaFilter(stateless_lambda_filter_t lambda_filter) : lambda_filter_(lambda_filter) {} + explicit StatelessLambdaFilter(optional (*lambda_filter)(std::string)) : lambda_filter_(lambda_filter) {} optional new_value(std::string value) override { return this->lambda_filter_(value); } protected: - stateless_lambda_filter_t lambda_filter_; + optional (*lambda_filter_)(std::string); }; /// A simple filter that converts all text to uppercase diff --git a/esphome/core/base_automation.h b/esphome/core/base_automation.h index 683be2a9e9..1c60dd1c7a 100644 --- a/esphome/core/base_automation.h +++ b/esphome/core/base_automation.h @@ -81,7 +81,7 @@ template class LambdaCondition : public Condition { /// Optimized lambda condition for stateless lambdas (no capture). /// Uses function pointer instead of std::function to reduce memory overhead. -/// Memory: 8 bytes (function pointer) vs 32 bytes (std::function). +/// Memory: 4 bytes (function pointer on 32-bit) vs 32 bytes (std::function). template class StatelessLambdaCondition : public Condition { public: explicit StatelessLambdaCondition(bool (*f)(Ts...)) : f_(f) {} @@ -204,7 +204,7 @@ template class LambdaAction : public Action { /// Optimized lambda action for stateless lambdas (no capture). /// Uses function pointer instead of std::function to reduce memory overhead. -/// Memory: 8 bytes (function pointer) vs 32 bytes (std::function). +/// Memory: 4 bytes (function pointer on 32-bit) vs 32 bytes (std::function). template class StatelessLambdaAction : public Action { public: explicit StatelessLambdaAction(void (*f)(Ts...)) : f_(f) {} diff --git a/tests/unit_tests/test_cpp_generator.py b/tests/unit_tests/test_cpp_generator.py index b495b52064..f42ad180c7 100644 --- a/tests/unit_tests/test_cpp_generator.py +++ b/tests/unit_tests/test_cpp_generator.py @@ -213,6 +213,23 @@ class TestLambdaExpression: "+[](int32_t foo, float bar) -> float {\n return foo + bar;\n}" ) + def test_str__with_capture_no_prefix(self): + """Test lambda with capture (not stateless) does NOT get + prefix""" + target = cg.LambdaExpression( + ("return captured_var + x;",), + ((int, "x"),), + "captured_var", # Has capture (not stateless) + int, + ) + + actual = str(target) + + # Should NOT have + prefix + assert actual == ( + "[captured_var](int32_t x) -> int32_t {\n return captured_var + x;\n}" + ) + assert not actual.startswith("+") + class TestLiterals: @pytest.mark.parametrize(