Created
June 14, 2015 16:58
-
-
Save oisdk/ee65b6b978d53afbffb9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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