#include <cassert>
#include <iostream>
#include <optional>
#include <variant>

struct Idle {};
struct Running { int id; };
struct Finished { int value; };
struct Failed { int code; };
using State = std::variant<Idle, Running, Finished, Failed>;
bool start(State& state, int id) {
    if (!std::holds_alternative<Idle>(state) || id <= 0) return false;
    state = Running{id};
    return true;
}
bool complete(State& state, std::optional<int> result) {
    if (!std::holds_alternative<Running>(state)) return false;
    if (result) state = Finished{*result};
    else state = Failed{1};
    return true;
}
int main() {
    State state = Idle{};
    const bool early = complete(state, 7);
    assert(!early);
    const bool invalid = start(state, 0);
    assert(!invalid);
    const bool begun = start(state, 10);
    assert(begun);
    const bool duplicate = start(state, 20);
    assert(!duplicate);
    const bool finished = complete(state, 0);
    assert(finished);
    assert(std::get<Finished>(state).value == 0);
    const bool repeated = complete(state, 9);
    assert(!repeated);
    State failed = Idle{};
    const bool second_begun = start(failed, 11);
    assert(second_begun);
    const bool second_finished = complete(failed, std::nullopt);
    assert(second_finished);
    assert(std::get<Failed>(failed).code == 1);
    std::cout << "state transitions ok\n";
}
