Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Created March 19, 2024 23:23
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 JadenGeller/08ccf1fa07b2c1b284846b1da0e90b31 to your computer and use it in GitHub Desktop.
Save JadenGeller/08ccf1fa07b2c1b284846b1da0e90b31 to your computer and use it in GitHub Desktop.
struct OffsetIndexCollection<Base: RandomAccessCollection>: RandomAccessCollection {
var base: Base
var distance: Int
@inlinable @inline(__always)
var startIndex: Base.Index {
index(base.startIndex, offsetBy: distance)
}
@inlinable @inline(__always)
var endIndex: Base.Index {
index(base.endIndex, offsetBy: distance)
}
@inlinable @inline(__always)
subscript(position: Base.Index) -> Base.Element {
base[index(position, offsetBy: distance)]
}
@inlinable @inline(__always)
func index(before i: Base.Index) -> Base.Index {
base.index(before: i)
}
@inlinable @inline(__always)
func index(after i: Base.Index) -> Base.Index {
base.index(after: i)
}
@inlinable @inline(__always)
func index(_ i: Base.Index, offsetBy distance: Int) -> Base.Index {
base.index(i, offsetBy: distance)
}
@inlinable @inline(__always)
func distance(from start: Base.Index, to end: Base.Index) -> Int {
base.distance(from: start, to: end)
}
}
extension OffsetIndexCollection: MutableCollection where Base: MutableCollection {
@inlinable @inline(__always)
subscript(position: Index) -> Base.Element {
get { base[index(position, offsetBy: distance)] }
set { base[index(position, offsetBy: distance)] = newValue }
}
}
extension OffsetIndexCollection: RangeReplaceableCollection where Base: RangeReplaceableCollection {
@inlinable @inline(__always)
init(distance: Int) {
self.init(base: .init(), distance: distance)
}
@inlinable @inline(__always)
init() {
fatalError("must call init(distance:)")
}
@inlinable @inline(__always)
mutating func replaceSubrange(_ subrange: Range<Index>, with newElements: some Collection<Base.Element>) {
base.replaceSubrange(index(subrange.lowerBound, offsetBy: distance)..<index(subrange.lowerBound, offsetBy: distance), with: newElements)
}
}
extension RandomAccessCollection {
func offsettingIndices(by distance: Int) -> OffsetIndexCollection<Self> {
.init(base: self, distance: distance)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment