text: //===--- SILSuccessor.h - Terminator Instruction Successor ------*- C++ -*-===//
  //
  // This source file is part of the Swift.org open source project
  //
  // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
  // Licensed under Apache License v2.0 with Runtime Library Exception
  //
  // See http://swift.org/LICENSE.txt for license information
  // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  //
  //===----------------------------------------------------------------------===//
  
  #ifndef SWIFT_SIL_SILSuccessor_H
  #define SWIFT_SIL_SILSuccessor_H
  
  #include <cassert>
  #include <cstddef>
  #include <iterator>
  
  namespace swift {
  class SILBasicBlock;
  class TermInst;
  
  /// SILSuccessor - This represents a reference to a SILBasicBlock in a
  /// terminator instruction, forming a list of TermInst references to
  /// BasicBlocks.  This forms the predecessor list, ensuring that it is always
  /// kept up to date.
  class SILSuccessor {
    friend class SILSuccessorIterator;
    /// ContainingInst - This is the Terminator instruction that contains this
    /// successor.
    TermInst *ContainingInst = nullptr;
    
    /// SuccessorBlock - If non-null, this is the BasicBlock that the terminator
    /// branches to.
    SILBasicBlock *SuccessorBlock = nullptr;
    
    /// This is the prev and next terminator reference to SuccessorBlock, or
    /// null if SuccessorBlock is null.
    SILSuccessor **Prev = nullptr, *Next = nullptr;
  public:
    SILSuccessor() {}
  
    SILSuccessor(TermInst *CI)
      : ContainingInst(CI) {
    }
  
    SILSuccessor(TermInst *CI, SILBasicBlock *Succ)
      : ContainingInst(CI) {
      *this = Succ;
    }
    
    ~SILSuccessor() {
      *this = nullptr;
    }
  
    void operator=(SILBasicBlock *BB);
    
    operator SILBasicBlock*() const { return SuccessorBlock; }
    SILBasicBlock *getBB() const { return SuccessorBlock; }
    
    // Do not copy or move these.
    SILSuccessor(const SILSuccessor &) = delete;
    SILSuccessor(SILSuccessor &&) = delete;
  };
    
  /// SILSuccessorIterator - This is an iterator for walking the successor list of
  /// a SILBasicBlock.
  class SILSuccessorIterator {
    SILSuccessor *Cur;
  public:
    using difference_type = std::ptrdiff_t;
    using value_type = SILBasicBlock *;
    using pointer = SILBasicBlock **;
    using reference = SILBasicBlock *&;
    using iterator_category = std::forward_iterator_tag;
    
    SILSuccessorIterator(SILSuccessor *Cur = 0) : Cur(Cur) {}
    
    bool operator==(SILSuccessorIterator I2) const { return Cur == I2.Cur; }
    bool operator!=(SILSuccessorIterator I2) const { return Cur != I2.Cur; }
  
    SILSuccessorIterator &operator++() {
      assert(Cur && "Trying to advance past end");
      Cur = Cur->Next;
      return *this;
    }
  
    SILSuccessorIterator operator++(int) {
      SILSuccessorIterator copy = *this;
      ++copy;
      return copy;
    }
  
    SILSuccessor *getSuccessorRef() const { return Cur; }
    SILBasicBlock *operator*();
  };
    
  
  } // end swift namespace
  
  #endif
  