Last active
May 2, 2017 03:32
-
-
Save karwa/5228974a0b4dfd000a916f0aac2721c6 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
extension Collection { | |
/// Repeats the collection _itself_ N times. | |
/// | |
/// ``` | |
/// > [1, 2, 3].repeated(3).forEach { print($0) } | |
/// [1, 2, 3] | |
/// [1, 2, 3] | |
/// [1, 2, 3] | |
/// ``` | |
/// | |
func repeated(_ times: Int) -> RepeatCollection<CollectionOfOne<Self>> { | |
return CollectionOfOne(self).repeatElements(times) | |
} | |
/// Repeats the collection's _contents_ N times. | |
/// | |
/// ``` | |
/// > [1, 2, 3].repeatElements(3).forEach { print($0) } | |
/// 1 | |
/// 2 | |
/// 3 | |
/// 1 | |
/// 2 | |
/// 3 | |
/// 1 | |
/// 2 | |
/// 3 | |
/// ``` | |
/// | |
func repeatElements(_ times: Int) -> RepeatCollection<Self> { | |
return RepeatCollection(base: self, count: numericCast(count) * times) | |
} | |
/// Loops the collection’s contents to present a Collection of length N. | |
/// | |
/// ``` | |
/// > [1, 2, 3].repeatElements(count: 4).forEach { print($0) } | |
/// 1 | |
/// 2 | |
/// 3 | |
/// 1 | |
/// ``` | |
/// | |
func repeatElements(count: Int) -> RepeatCollection<Self> { | |
return RepeatCollection(base: self, count: count) | |
} | |
} | |
struct RepeatCollection<Base>: Collection where Base: Collection { | |
let base: Base | |
let count: Int | |
var startIndex: Index { return Index(baseIdx: base.startIndex, idx: 0) } | |
var endIndex: Index { return Index(baseIdx: base.startIndex, idx: count) } | |
func index(after i: Index) -> Index { | |
var i = i; formIndex(after: &i); return i | |
} | |
func formIndex(after i: inout Index) { | |
precondition(i < endIndex, "Cannot increment endIndex") | |
i.idx += 1 | |
i.baseIdx = base.index(after: i.baseIdx) | |
if i.baseIdx == base.endIndex { | |
i.baseIdx = base.startIndex | |
} | |
} | |
subscript(i: Index) -> Base.Iterator.Element { | |
return base[i.baseIdx] | |
} | |
} | |
// FIXME: SWIFT(SR-3779): Should be nested inside RepeatCollection, | |
// but crashes with bogus "cyclic metadata dependency" failure. | |
extension RepeatCollection { | |
typealias Index = RepeatCollectionIndex<Base> | |
} | |
struct RepeatCollectionIndex<Base: Collection>: Comparable { | |
var baseIdx: Base.Index | |
var idx: Int | |
static func <(l: RepeatCollectionIndex, r: RepeatCollectionIndex) -> Bool { | |
return l.idx < r.idx | |
} | |
static func ==(l: RepeatCollectionIndex, r: RepeatCollectionIndex) -> Bool { | |
return l.idx == r.idx | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment