I want to be sure what it means for a type to conform to Sequence and IteratorProtocol, and thus what can be assumed about conforming types when writing extensions on Sequence.
My current interpretation of the related documentation leads me to believe that the following example type satisfies the formal and semantic requirements of Sequence and IteratorProtocol.
/// An example sequence type that is destructively consumed by iteration and
/// has shared mutable state.
final class SharedCountdown: Sequence, IteratorProtocol {
var current: Int
init(from: Int) {
print("-- initializing a new SharedCountdown instance --")
current = from
}
func makeIterator() -> SharedCountdown {
print("-- calling makeIterator() --")
return self
}
func next() -> Int? {
if current == 0 {
return nil
} else {
defer { current -= 1 }
return current
}
}
}
// Some examples to demonstrate its behavior:
let a = SharedCountdown(from: 3)
for e in a { print(e) } // Will print 3 2 1
for e in a { print(e) } // Will not print anything (as expected).
let b = SharedCountdown(from: 3)
print(Array(b)) // [3, 2, 1]
print(Array(b)) // []
let c = SharedCountdown(from: 3)
print(Array(c.prefix(1))) // [3]
print(Array(c)) // [2, 1]
let d = SharedCountdown(from: 3)
print(Array(d.dropFirst())) // [2, 1]
print(Array(d)) // []
let e = SharedCountdown(from: 3)
print(e.contains(2)) // true
print(e.contains(2)) // false
let f = SharedCountdown(from: 3)
let g = SharedCountdown(from: 3)
let h = SharedCountdown(from: 3)
print(f.elementsEqual(g)) // true
print(g.elementsEqual(f)) // true (but because they have both been consumed)
print(f.elementsEqual(h)) // false (because f has been consumed but h has not)
let x = SharedCountdown(from: 3)
let y = SharedCountdown(from: 3)
print(x.elementsEqual([3, 2, 1])) // true
print(x.elementsEqual([3, 2, 1])) // false (!)
print(x.elementsEqual(y)) // false (!)
print(x.elementsEqual(y)) // false (!)
print(x.elementsEqual(y)) // false (!)
print(x.elementsEqual(y)) // true (!!!)
So, in short, does this SharedCountdown type satisfy the requirements of IteratorProtocol and Sequence?
