Skip to content

Instantly share code, notes, and snippets.

@airspeedswift
Created October 26, 2018 04:33
Show Gist options
  • Save airspeedswift/5731f0b8eadd4a4bc0b8f1034a81c1e4 to your computer and use it in GitHub Desktop.
Save airspeedswift/5731f0b8eadd4a4bc0b8f1034a81c1e4 to your computer and use it in GitHub Desktop.
Bound a sequence with a start and end marker
struct BoundedSequence<Base: Sequence> {
let _base: Base
}
extension BoundedSequence {
struct Iterator {
enum State { case starting, iterating, ended }
var _state: State
var _iterator: Base.Iterator
}
}
extension BoundedSequence.Iterator: IteratorProtocol {
enum Element {
case start, end
case middle(Base.Element)
}
mutating func next() -> Element? {
switch _state {
case .starting:
_state = .iterating
return .start
case .iterating:
if let x = _iterator.next() {
return .middle(x)
} else {
_state = .ended
return .end
}
case .ended: return nil
}
}
}
extension BoundedSequence: Sequence {
func makeIterator() -> Iterator {
return Iterator(_state: .starting, _iterator: _base.makeIterator())
}
}
extension Sequence {
func bounded() -> BoundedSequence<Self> {
return BoundedSequence(_base: self)
}
}
for bounded in "foo".bounded() {
switch bounded {
case .start: print("started")
case .middle(let x): print(x)
case .end: print("ended")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment