Skip to content

Instantly share code, notes, and snippets.

@oisdk
Created June 14, 2015 16:58
Show Gist options
  • Save oisdk/ee65b6b978d53afbffb9 to your computer and use it in GitHub Desktop.
Save oisdk/ee65b6b978d53afbffb9 to your computer and use it in GitHub Desktop.
protocol Lazy : SequenceType {}
extension LazySequence : Lazy {}
extension LazyBidirectionalCollection : Lazy {}
extension LazyForwardCollection : Lazy {}
extension LazyRandomAccessCollection : Lazy {}
extension Lazy {
var array: [Generator.Element] {
return Array(self)
}
}
struct CycleGen<C: CollectionType> : GeneratorType {
typealias Element = C.Generator.Element
private let inner: C
private var innerGen: C.Generator
init(col: C) {
self.inner = col
self.innerGen = col.generate()
}
mutating func next() -> Element? {
for ;;innerGen = inner.generate() {
if let next = innerGen.next() {
return next
}
}
}
}
extension CollectionType {
func cycle() -> CycleGen<Self> {
return CycleGen(col: self)
}
}
struct TakeGen<G: GeneratorType> : GeneratorType {
typealias Element = G.Element
private var n: Int
private var g: G
mutating func next() -> Element? {
return --n < 0 ? nil : g.next()
}
}
struct LazyTakeSeq<S: SequenceType> : SequenceType, Lazy {
typealias Generator = TakeGen<S.Generator>
private let (seq, n): (S, Int)
func generate() -> Generator {
return TakeGen(n: n, g: seq.generate())
}
}
extension Lazy {
func take(n: Int) -> LazyTakeSeq<Self> {
return LazyTakeSeq(seq: self, n: n)
}
}
struct DropGen<G: GeneratorType> : GeneratorType {
typealias Element = G.Element
private var g: G
init(n: Int, var g: G) {
for _ in 0..<n { g.next() }
self.g = g
}
mutating func next() -> Element? {
return g.next()
}
}
struct LazyDropSeq<S: SequenceType> : SequenceType, Lazy {
typealias Generator = DropGen<S.Generator>
private let (seq, n): (S, Int)
func generate() -> Generator {
return DropGen(n: n, g: seq.generate())
}
}
extension Lazy {
func drop(n: Int) -> LazyDropSeq<Self> {
return LazyDropSeq(seq: self, n: n)
}
}
struct JumpGen<G: GeneratorType> : GeneratorType {
typealias Element = G.Element
private let n: Int
private var g: G
mutating func next() -> Element? {
for _ in 0..<n { g.next() }
return g.next()
}
}
struct HopGen<G: GeneratorType> : GeneratorType {
typealias Element = G.Element
private let n: Int
private var g: G
mutating func next() -> Element? {
defer { for _ in 0..<n { g.next() } }
return g.next()
}
}
struct LazyHopSeq<S : SequenceType> : SequenceType, Lazy {
typealias Generator = HopGen<S.Generator>
private let (seq, n): (S, Int)
func generate() -> Generator {
return HopGen(n: n, g: seq.generate())
}
}
struct LazyJumpSeq<S : SequenceType> : SequenceType, Lazy {
typealias Generator = JumpGen<S.Generator>
private let (seq, n): (S, Int)
func generate() -> Generator {
return JumpGen(n: n, g: seq.generate())
}
}
extension Lazy {
func hop(n: Int) -> LazyHopSeq<Self> {
return LazyHopSeq(seq: self, n: n)
}
func jump(n: Int) -> LazyJumpSeq<Self> {
return LazyJumpSeq(seq: self, n: n)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment