title: How to get next case of enum(i.e. write a circulating method) in Swift 4.2
body: <p>Swift 4.2 introduces a new <code>CaseIterable</code> protocol that automatically generates an array property of all cases in an enum.<br>
  Now I want to implement a default method for Enum inherits from <code>CaseIterable</code> that can return the next case of a giving case. If this case is the last case, return the first case. Like a circle.<br>
  If I write this for specific Enum, it works correctly:</p>
  
  <pre><code>enum Direction: CaseIterable {
    case east, south, west, north
  
    func next() -&gt; Direction {
      let all = type(of: self).allCases // 1
      if self == all.last! {
        return all.first!
      } else {
        let index = all.firstIndex(of: self)!
        return all[index + 1]
      }
    }
  }
  
  print(Direction.east.next()) // south  
  print(Direction.north.next()) // east  
  </code></pre>
  
  <p>But I want to implement this function to many Enum. Copying and pasting code repeatedly are not good (Not to mention this code is totally the same for every Enum).<br>
  So I tried this. But something went wrong.<br>
  (I suggest you copy following code to playground that you can understand this problem more quickly):</p>
  
  <pre><code>extension CaseIterable {
    func next() -&gt; Self {
      let all = type(of: self).allCases // 1
      if self == all.last { // 2
        return all.first!
      } else {
        let index = all.firstIndex { (ele) -&gt; Bool in
          self == ele // 3
        }
        return all[index + 1]
      }
    }
  }
  </code></pre>
  
  <p>Three points:</p>
  
  <ol>
  <li><code>all</code>'s type is <code>Self.AllCases</code>, which is a <code>Collection</code> type. But in the method above, it's <code>[Direction]</code>.</li>
  <li>There's an error at line 2 says <code>Value of type 'Self.AllCases' has no member 'last'</code>
  (Even I avoid to use <code>last</code>, the error at line 3 can't be avoided.)</li>
  <li>At line 3, the error is <code>Binary operator '==' cannot be applied to two 'Self' operands</code></li>
  </ol>
  
  <p>And even I use generic constraints, it's the same.</p>
  
  <pre><code>func next&lt;T: CaseIterable&gt;(element: T) -&gt; T {...}
  </code></pre>
  
  <p>Any solutions? :)</p>