Skip to content

Commit 197d441

Browse files
committed
up
1 parent 5e10ecc commit 197d441

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

example/coro/example_stm.cpp

+25-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <coroutine>
77
#include <iostream>
88
#include <unordered_map>
9+
#include <concepts>
10+
#include <any>
911

1012
#include "generator.h"
1113

@@ -55,6 +57,16 @@ using coro_t = std::coroutine_handle<>;
5557
enum class Sym : char { A, B, Term };
5658
enum class State { A, B };
5759

60+
template <class State, class Sym>
61+
class StateMachine;
62+
63+
using stm_t = StateMachine<State, Sym>;
64+
65+
template <class F>
66+
concept CanInvokeWithStm = requires(F f, stm_t& stm) {
67+
{ f(stm) } -> std::same_as<Resumable>;
68+
};
69+
5870
Generator<Sym> input_seq(std::string seq) {
5971
for (char c : seq) {
6072
switch (c) {
@@ -86,9 +98,12 @@ struct stm_awaiter : public F {
8698
auto new_state = F::operator()(sym);
8799
return stm[new_state];
88100
}
89-
bool await_resume() const noexcept { return stm.genval() == Sym::Term; }
101+
[[nodiscard]] bool await_resume() const noexcept {
102+
return stm.genval() == Sym::Term;
103+
}
90104
};
91105

106+
92107
template <class State, class Sym>
93108
class StateMachine final {
94109
public:
@@ -101,14 +116,14 @@ class StateMachine final {
101116
return stm_awaiter(transition, *this);
102117
}
103118

104-
template <class F>
119+
template <CanInvokeWithStm F>
105120
void add_state(State state, F stf) {
106121
states[state] = stf(*this).handle();
107122
}
108123

109124
void run(State initial) {
110125
current_state = initial;
111-
states[initial].resume();
126+
states[current_state].resume();
112127
}
113128

114129
Sym genval() const { return gen.current_value(); }
@@ -118,39 +133,37 @@ class StateMachine final {
118133
State current() const { return current_state; }
119134

120135
private:
121-
State current_state;
122-
std::unordered_map<State, coro_t> states;
136+
State current_state{};
137+
std::unordered_map<State, coro_t> states{};
123138
Generator<Sym> gen;
124139
};
125140

126-
using stm_t = StateMachine<State, Sym>;
127-
128141
Resumable StateA(stm_t& stm) {
129-
auto transmition = [](auto sym) {
142+
auto transmission = [](auto sym) {
130143
if (sym == Sym::B) {
131144
return State::B;
132145
}
133146
return State::A;
134147
};
135148
for (;;) {
136149
std::cout << "State A" << std::endl;
137-
bool finish = co_await stm.get_awaiter(transmition);
150+
bool finish = co_await stm.get_awaiter(transmission);
138151
if (finish) {
139152
break;
140153
}
141154
}
142155
}
143156

144157
Resumable StateB(stm_t& stm) {
145-
auto transmition = [](auto sym) {
158+
auto transmission = [](auto sym) {
146159
if (sym == Sym::A) {
147160
return State::A;
148161
}
149162
return State::B;
150163
};
151164
for (;;) {
152165
std::cout << "State B" << std::endl;
153-
bool finish = co_await stm.get_awaiter(transmition);
166+
bool finish = co_await stm.get_awaiter(transmission);
154167
if (finish) {
155168
break;
156169
}
@@ -159,7 +172,7 @@ Resumable StateB(stm_t& stm) {
159172

160173
int main() {
161174
auto gen = input_seq("aaabbaba");
162-
stm_t stm(std::move(gen));
175+
stm_t stm(gen);
163176
stm.add_state(State::A, StateA);
164177
stm.add_state(State::B, StateB);
165178

0 commit comments

Comments
 (0)