#ifndef INTCODE_INTERPRETER_HPP_ #define INTCODE_INTERPRETER_HPP_ #include #include #include #include namespace intcode { struct Input { ValueType &input; }; struct Output { ValueType output; }; struct Halt {}; auto StepInput(Machine & m, ValueType input) -> void; auto StepOutput(Machine & m) -> ValueType; auto Step(Machine & m) -> std::variant; struct BadInstruction : public std::runtime_error { explicit BadInstruction(char const* what); }; template Fin, std::invocable Fout, std::invocable<> Fhalt> auto Advance(Machine & machine, Fin input, Fout output, Fhalt halt) { return std::visit(overloaded{ [&](Halt) { return halt(); }, [&](Input i) { return input(i.input); }, [&](Output o) { return output(o.output); }, }, Step(machine)); } template Fin, std::invocable Fout> auto Run(Machine & machine, Fin input, Fout output) -> void { while (Advance(machine, [&](ValueType &i) { i = input(); return true; }, [&](ValueType o) { output(o); return true; }, []() { return false; } )) {} } } // namespace #endif