| 69 | |
| 70 | // Representation of a connection on a node. |
| 71 | class Port { |
| 72 | public: |
| 73 | // A port may be inbound or outbound. |
| 74 | // Negative ids (canonically -1) mean a control port. |
| 75 | Port(bool inbound, int32_t id) : value_(id << 1) { |
| 76 | if (inbound) { |
| 77 | value_ |= 1; |
| 78 | } |
| 79 | } |
| 80 | Port(const Port&) = default; |
| 81 | Port& operator=(const Port&) = default; |
| 82 | |
| 83 | bool IsInbound() const { return (value_ & 0x1); } |
| 84 | |
| 85 | bool IsControl() const { return (value_ < 0); } |
| 86 | |
| 87 | int32_t Id() const { |
| 88 | // Arithmetic shift preserves the sign. |
| 89 | return (value_ >> 1); |
| 90 | } |
| 91 | |
| 92 | // Integer type used to represent the encoded port value. |
| 93 | using IntPort = int32_t; |
| 94 | |
| 95 | // Returns the encoded form of this port, so that it can be used |
| 96 | // as various map indexes. |
| 97 | IntPort Encoded() const { return value_; } |
| 98 | |
| 99 | static Port Decode(IntPort encoded) { return Port(encoded); } |
| 100 | |
| 101 | bool operator==(const Port& other) const { return value_ == other.value_; } |
| 102 | bool operator<(const Port& other) const { return value_ < other.value_; } |
| 103 | |
| 104 | struct Hasher { |
| 105 | size_t operator()(const Port& port) const noexcept { |
| 106 | return hasher(port.Encoded()); |
| 107 | } |
| 108 | std::hash<int32_t> hasher; |
| 109 | }; |
| 110 | |
| 111 | // Convenient for printing. I've really wanted it to be implicit but |
| 112 | // ClangTidy insists on making it explicit. |
| 113 | explicit operator string() const; |
| 114 | |
| 115 | private: |
| 116 | explicit Port(IntPort value) : value_(value) {} |
| 117 | |
| 118 | IntPort value_; |
| 119 | }; |
| 120 | |
| 121 | struct LinkTarget { |
| 122 | GenNode* node; // Node where this link points. |