Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c++
Subject: Re: "C++20 Coroutines" by Martin Bond
Date: Wed, 06 Oct 2021 13:19:12 -0700
Organization: A noiseless patient Spider
Lines: 46
Message-ID: <865yu9rjnj.fsf@linuxsc.com>
References: <87zgs1yby6.fsf@bsb.me.uk>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="f63a7b6827eb8960d7c84af554cfeab9"; logging-data="917"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/zKjbHuZQC4ec2BNxa/K0jqU6O+Jrf7d8="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:+KA21rrc98V0zAv7siygJVAd288= sha1:B1WqEGrq3J/LyyUlKu7pTAuOH9k=
Xref: csiph.com comp.lang.c++:81883
Ben Bacarisse writes:
> Bonita Montero writes:
>
>> State-machines are _always_ spahgetti-code (while( !end )
>> switch( state ) { ... }), even when you write them conventionally.
>
> Obviously one person's spaghetti is another person's farfalle, but
> in my opinion, if the state is a (a pointer to a) function that
> returns (a pointer to) the next state, then you just get a clean
> loop calling a function:
>
> data d = { ... };
> State state = initial;
> while (state) state = (State)state(&d);
>
> C++ has trouble writing the recursive type, so you need a cast, but
> its a safe cast.
In C++, needing a cast can be avoided by wrapping the function
pointer in a class or struct, as for example:
class State {
typedef State (*Go)( data & );
Go go;
public:
State( Go g ) : go( g ) {}
operator bool(){ return go; }
State operator()( data &data ){
return go( data );
}
};
void
run_state_machine( State initial, data &data ){
State s = initial;
while( s ) s = s( data );
}
The example above is specific to a partcular type of "data" being
acted on, but it's easy to generalize around that shortcoming by
using templates.