[core] Inline ContinuationAction in If/While/RepeatAction (#16040)

This commit is contained in:
J. Nick Koston
2026-04-28 21:26:25 -04:00
committed by GitHub
parent 8af499b591
commit 1363f661e6
+24 -4
View File
@@ -273,18 +273,32 @@ template<typename... Ts> class WhileLoopContinuation : public Action<Ts...> {
WhileAction<Ts...> *parent_;
};
// Wraps a ContinuationAction when Enabled, empty otherwise.
// Lets IfAction elide the else continuation when HasElse is false.
template<bool Enabled, typename... Ts> struct OptionalContinuation {
ContinuationAction<Ts...> action;
explicit OptionalContinuation(Action<Ts...> *parent) : action(parent) {}
};
template<typename... Ts> struct OptionalContinuation<false, Ts...> {
explicit OptionalContinuation(Action<Ts...> * /*parent*/) {}
};
template<bool HasElse, typename... Ts> class IfAction : public Action<Ts...> {
public:
explicit IfAction(Condition<Ts...> *condition) : condition_(condition) {}
// Precondition: add_then/add_else must be called at most once per instance.
// Codegen always batches the full action list into a single call. Calling
// twice would re-append the same inline continuation pointer and form a
// self-loop in the next_ chain.
void add_then(const std::initializer_list<Action<Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new ContinuationAction<Ts...>(this));
this->then_.add_action(&this->then_continuation_);
}
void add_else(const std::initializer_list<Action<Ts...> *> &actions) requires(HasElse) {
this->else_.add_actions(actions);
this->else_.add_action(new ContinuationAction<Ts...>(this));
this->else_.add_action(&this->else_continuation_.action);
}
void play_complex(const Ts &...x) override {
@@ -316,17 +330,20 @@ template<bool HasElse, typename... Ts> class IfAction : public Action<Ts...> {
protected:
Condition<Ts...> *condition_;
ActionList<Ts...> then_;
ContinuationAction<Ts...> then_continuation_{this};
struct NoElse {};
[[no_unique_address]] std::conditional_t<HasElse, ActionList<Ts...>, NoElse> else_;
[[no_unique_address]] OptionalContinuation<HasElse, Ts...> else_continuation_{this};
};
template<typename... Ts> class WhileAction : public Action<Ts...> {
public:
WhileAction(Condition<Ts...> *condition) : condition_(condition) {}
// Precondition: must be called at most once per instance (see IfAction::add_then).
void add_then(const std::initializer_list<Action<Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new WhileLoopContinuation<Ts...>(this));
this->then_.add_action(&this->loop_continuation_);
}
friend class WhileLoopContinuation<Ts...>;
@@ -354,6 +371,7 @@ template<typename... Ts> class WhileAction : public Action<Ts...> {
protected:
Condition<Ts...> *condition_;
ActionList<Ts...> then_;
WhileLoopContinuation<Ts...> loop_continuation_{this};
};
// Implementation of WhileLoopContinuation::play
@@ -386,9 +404,10 @@ template<typename... Ts> class RepeatAction : public Action<Ts...> {
public:
TEMPLATABLE_VALUE(uint32_t, count)
// Precondition: must be called at most once per instance (see IfAction::add_then).
void add_then(const std::initializer_list<Action<uint32_t, Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new RepeatLoopContinuation<Ts...>(this));
this->then_.add_action(&this->loop_continuation_);
}
friend class RepeatLoopContinuation<Ts...>;
@@ -409,6 +428,7 @@ template<typename... Ts> class RepeatAction : public Action<Ts...> {
protected:
ActionList<uint32_t, Ts...> then_;
RepeatLoopContinuation<Ts...> loop_continuation_{this};
};
// Implementation of RepeatLoopContinuation::play