Add static_asserts for forwarder size, widen type hint

- static_assert that forwarders are pointer-sized and trivially
  copyable so future field additions can't silently cause heap
  allocation in Callback::create().
- Widen forwarder parameter type hint to MockObj | MockObjClass.
This commit is contained in:
J. Nick Koston
2026-03-25 15:36:08 -10:00
parent bd69737878
commit 150e0775b9
2 changed files with 13 additions and 1 deletions
+1 -1
View File
@@ -671,7 +671,7 @@ async def build_callback_automation(
callback_method: str,
args: TemplateArgsType,
config: ConfigType,
forwarder: MockObjClass | None = None,
forwarder: MockObj | MockObjClass | None = None,
) -> None:
"""Build an Automation and register it as a callback on the parent.
+12
View File
@@ -494,12 +494,14 @@ template<typename... Ts> class Automation {
/// Callback forwarder that triggers an Automation directly.
/// One operator() instantiation per Automation<Ts...> signature, shared across all call sites.
/// Must stay pointer-sized to fit inline in Callback::ctx_ without heap allocation.
template<typename... Ts> struct TriggerForwarder {
Automation<Ts...> *automation;
void operator()(const Ts &...args) const { this->automation->trigger(args...); }
};
/// Callback forwarder that triggers an Automation<> only when the bool arg is true.
/// Must stay pointer-sized to fit inline in Callback::ctx_ without heap allocation.
struct TriggerOnTrueForwarder {
Automation<> *automation;
void operator()(bool state) const {
@@ -509,6 +511,7 @@ struct TriggerOnTrueForwarder {
};
/// Callback forwarder that triggers an Automation<> only when the bool arg is false.
/// Must stay pointer-sized to fit inline in Callback::ctx_ without heap allocation.
struct TriggerOnFalseForwarder {
Automation<> *automation;
void operator()(bool state) const {
@@ -517,4 +520,13 @@ struct TriggerOnFalseForwarder {
}
};
// Ensure forwarders fit in Callback::ctx_ (pointer-sized inline storage).
// If these fail, the forwarder would heap-allocate in Callback::create().
static_assert(sizeof(TriggerForwarder<>) <= sizeof(void *));
static_assert(sizeof(TriggerOnTrueForwarder) <= sizeof(void *));
static_assert(sizeof(TriggerOnFalseForwarder) <= sizeof(void *));
static_assert(std::is_trivially_copyable_v<TriggerForwarder<>>);
static_assert(std::is_trivially_copyable_v<TriggerOnTrueForwarder>);
static_assert(std::is_trivially_copyable_v<TriggerOnFalseForwarder>);
} // namespace esphome