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
?