Skip to content

Instantly share code, notes, and snippets.

@karwa
Last active May 2, 2017 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karwa/5228974a0b4dfd000a916f0aac2721c6 to your computer and use it in GitHub Desktop.
Save karwa/5228974a0b4dfd000a916f0aac2721c6 to your computer and use it in GitHub Desktop.
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