message: Move semantics for ScopedCFG
  Summary: Add move constructor and assignment. Remove copy constructor and assignment.
diff: @@ -18,12 +18,20 @@ namespace cfg {
  */
  class ScopedCFG {
  public:
  + ScopedCFG() = default;
  +
  /** Ensure an editable CFG exists for `code`, creating one if needed. */
  inline explicit ScopedCFG(IRCode* code);
  + ScopedCFG(const ScopedCFG&) = delete;
  + inline ScopedCFG(ScopedCFG&& rhs) noexcept;
  +
  /** Clears `m_code`'s CFG, if it was created by this RAII instance. */
  inline ~ScopedCFG();
  + ScopedCFG& operator=(const ScopedCFG&) = delete;
  + inline ScopedCFG& operator=(ScopedCFG&& rhs) noexcept;
  +
  inline ControlFlowGraph* get();
  inline const ControlFlowGraph* get() const;
  @@ -34,8 +42,11 @@ class ScopedCFG {
  inline const ControlFlowGraph* operator->() const;
  private:
  - IRCode* m_code;
  - bool m_owns_cfg;
  + inline void reset();
  + inline void reset(IRCode* code, bool owns_cfg);
  +
  + IRCode* m_code{nullptr};
  + bool m_owns_cfg{false};
  };
  ScopedCFG::ScopedCFG(IRCode* code)
  @@ -45,10 +56,33 @@ ScopedCFG::ScopedCFG(IRCode* code)
  }
  }
  -ScopedCFG::~ScopedCFG() {
  +ScopedCFG::ScopedCFG(ScopedCFG&& rhs) noexcept {
  + reset(rhs.m_code, rhs.m_owns_cfg);
  + rhs.m_code = nullptr;
  + rhs.m_owns_cfg = false;
  +};
  +
  +ScopedCFG::~ScopedCFG() { reset(); }
  +
  +ScopedCFG& ScopedCFG::operator=(ScopedCFG&& rhs) noexcept {
  + if (this == &rhs) {
  + return *this;
  + }
  + reset(rhs.m_code, rhs.m_owns_cfg);
  + rhs.m_code = nullptr;
  + rhs.m_owns_cfg = false;
  + return *this;
  +}
  +
  +void ScopedCFG::reset() { reset(nullptr, false); }
  +
  +void ScopedCFG::reset(IRCode* code, bool owns_cfg) {
  if (m_owns_cfg) {
  m_code->clear_cfg();
  }
  + m_code = code;
  + m_owns_cfg = owns_cfg;
  + redex_assert(code == nullptr || !m_owns_cfg || code->cfg_built());
  }
  ControlFlowGraph* ScopedCFG::get() { return &m_code->cfg(); }
  