#pragma once #include #include #include #include "infra/sim.h" namespace infra { template struct port : public sim { std::optional consumer_side; std::optional producer_side; bool can_read() { return consumer_side.has_value(); } bool can_write() { return !producer_side.has_value(); } T read() { assert(can_read()); auto x = std::move(*consumer_side); consumer_side.reset(); return x; } T & peek() { assert(can_read()); return *consumer_side; } void discard() { consumer_side.reset(); } void write(T &&x) { assert(can_write()); producer_side = std::move(x); } void unclock() { if (!consumer_side && producer_side) { consumer_side = std::move(*producer_side); producer_side.reset(); } } }; }