[automation] Use std::array in And/Or/Xor conditions (#15282)

This commit is contained in:
J. Nick Koston
2026-03-29 13:36:08 -10:00
committed by GitHub
parent 3520ef7480
commit 29419d9d97
3 changed files with 33 additions and 15 deletions
+15 -5
View File
@@ -250,7 +250,9 @@ async def and_condition_to_code(
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
return cg.new_Pvariable(
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
)
@register_condition("or", OrCondition, validate_condition_list)
@@ -261,7 +263,9 @@ async def or_condition_to_code(
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
return cg.new_Pvariable(
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
)
@register_condition("all", AndCondition, validate_condition_list)
@@ -272,7 +276,9 @@ async def all_condition_to_code(
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
return cg.new_Pvariable(
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
)
@register_condition("any", OrCondition, validate_condition_list)
@@ -283,7 +289,9 @@ async def any_condition_to_code(
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
return cg.new_Pvariable(
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
)
@register_condition("not", NotCondition, validate_potentially_and_condition)
@@ -305,7 +313,9 @@ async def xor_condition_to_code(
args: TemplateArgsType,
) -> MockObj:
conditions = await build_condition_list(config, template_arg, args)
return cg.new_Pvariable(condition_id, template_arg, conditions)
return cg.new_Pvariable(
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
)
@register_condition("lambda", LambdaCondition, cv.returning_lambda)
+16 -9
View File
@@ -9,14 +9,17 @@
#include "esphome/core/application.h"
#include "esphome/core/helpers.h"
#include <array>
#include <list>
#include <vector>
namespace esphome {
template<typename... Ts> class AndCondition : public Condition<Ts...> {
template<size_t N, typename... Ts> class AndCondition : public Condition<Ts...> {
public:
explicit AndCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
explicit AndCondition(std::initializer_list<Condition<Ts...> *> conditions) {
init_array_from(this->conditions_, conditions);
}
bool check(const Ts &...x) override {
for (auto *condition : this->conditions_) {
if (!condition->check(x...))
@@ -27,12 +30,14 @@ template<typename... Ts> class AndCondition : public Condition<Ts...> {
}
protected:
FixedVector<Condition<Ts...> *> conditions_;
std::array<Condition<Ts...> *, N> conditions_{};
};
template<typename... Ts> class OrCondition : public Condition<Ts...> {
template<size_t N, typename... Ts> class OrCondition : public Condition<Ts...> {
public:
explicit OrCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
explicit OrCondition(std::initializer_list<Condition<Ts...> *> conditions) {
init_array_from(this->conditions_, conditions);
}
bool check(const Ts &...x) override {
for (auto *condition : this->conditions_) {
if (condition->check(x...))
@@ -43,7 +48,7 @@ template<typename... Ts> class OrCondition : public Condition<Ts...> {
}
protected:
FixedVector<Condition<Ts...> *> conditions_;
std::array<Condition<Ts...> *, N> conditions_{};
};
template<typename... Ts> class NotCondition : public Condition<Ts...> {
@@ -55,9 +60,11 @@ template<typename... Ts> class NotCondition : public Condition<Ts...> {
Condition<Ts...> *condition_;
};
template<typename... Ts> class XorCondition : public Condition<Ts...> {
template<size_t N, typename... Ts> class XorCondition : public Condition<Ts...> {
public:
explicit XorCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
explicit XorCondition(std::initializer_list<Condition<Ts...> *> conditions) {
init_array_from(this->conditions_, conditions);
}
bool check(const Ts &...x) override {
size_t result = 0;
for (auto *condition : this->conditions_) {
@@ -68,7 +75,7 @@ template<typename... Ts> class XorCondition : public Condition<Ts...> {
}
protected:
FixedVector<Condition<Ts...> *> conditions_;
std::array<Condition<Ts...> *, N> conditions_{};
};
template<typename... Ts> class LambdaCondition : public Condition<Ts...> {
+2 -1
View File
@@ -500,7 +500,8 @@ template<typename T, size_t MAX_CAPACITY = std::numeric_limits<uint16_t>::max()>
/// Initialize a std::array from an initializer_list. Uses memcpy for trivially copyable types (optimal codegen),
/// falls back to element-wise copy for non-trivially copyable types (e.g. TemplatableValue).
/// N is set by code generation; assert catches mismatches in debug/integration tests.
/// N is always set by code generation — the caller is responsible for ensuring src.size() == N.
/// The debug assert is a safety net for development, not a runtime check.
template<typename T, size_t N> inline void init_array_from(std::array<T, N> &dest, std::initializer_list<T> src) {
#ifdef ESPHOME_DEBUG
assert(src.size() == N);