template <typename T> T accept(Visitor<T> &&v) const { return accept(&v); }
public:
+ /**
+ * @brief Op mutator interface
+ *
+ * WARN Use this interface only for coco-internal classes
+ * (to minimize changes upon Instr extension)
+ */
+ struct IMutator
+ {
+ virtual ~IMutator() = default;
+
+#define OP(Name) virtual void mutate(Name *) = 0;
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ struct Mutator : public IMutator
+ {
+ virtual ~Mutator() = default;
+
+#define OP(Name) \
+ void mutate(Name *) override { throw std::runtime_error{"NYI"}; }
+#include "coco/IR/Op.lst"
+#undef OP
+ };
+
+ void accept(IMutator *m)
+ {
+#define OP(Name) \
+ if (auto op = as##Name()) \
+ { \
+ return m->mutate(op); \
+ }
+#include "coco/IR/Op.lst"
+#undef OP
+ throw std::runtime_error{"unreachable"};
+ }
+
+ void accept(IMutator &m) { return accept(&m); }
+ void accept(IMutator &&m) { return accept(&m); }
+
+public:
Instr *parent(void) const;
// @brief Return a pointer to the parent Op