Line data Source code
1 : #pragma once
2 :
3 : #include <libassert/assert.hpp>
4 :
5 : #include <cstdint>
6 : #include <functional>
7 : #include <queue>
8 : #include <string_view>
9 : #include <vector>
10 :
11 : class Computer {
12 : public:
13 : using Address = uint64_t;
14 : using AddressOffset = int64_t;
15 : using OutputFunction = std::function<void(int64_t)>;
16 : enum class Status : uint8_t { HALTED, PAUSED };
17 : using enum Status;
18 :
19 : Computer(std::string_view const programString);
20 :
21 : Status run();
22 : void queueInput(int64_t value);
23 :
24 22 : void registerOutput(OutputFunction f) { _output.push_back(std::move(f)); }
25 :
26 : void writeMemory(Address address, int64_t value);
27 : int64_t readMemory(Address address);
28 :
29 : void reset();
30 : void reset(std::vector<int64_t> const &memory);
31 :
32 3 : [[nodiscard]] std::vector<int64_t> memdump() const { return _memory; }
33 5313 : void setMemory(std::vector<int64_t> const &memory) { _memory = memory; }
34 :
35 : private:
36 1426826 : [[nodiscard]] int64_t opcode() { return opcode(_ip); }
37 : [[nodiscard]] int64_t opcode(Address address);
38 :
39 : [[nodiscard]] int64_t parameterMode(Address address, size_t param);
40 3274708 : [[nodiscard]] int64_t parameterMode(size_t param) { return parameterMode(_ip, param); }
41 :
42 : bool performOp();
43 : [[nodiscard]] int64_t readParam(size_t param);
44 : void writeParam(size_t param, int64_t value);
45 :
46 : Address _ip = 0;
47 : AddressOffset _rb = 0;
48 : Status _status{PAUSED};
49 : std::vector<int64_t> _memory;
50 : std::queue<int64_t> _inputs;
51 : std::vector<OutputFunction> _output;
52 : };
|