Skip to content

Instantly share code, notes, and snippets.

@kemchenj
Last active December 2, 2018 01:53
Show Gist options
  • Save kemchenj/a61676ed13b7c17de5daaa0e3587dbf3 to your computer and use it in GitHub Desktop.
Save kemchenj/a61676ed13b7c17de5daaa0e3587dbf3 to your computer and use it in GitHub Desktop.
CustomArray
import Foundation
struct CustomArray<Element>: MutableCollection, RangeReplaceableCollection, RandomAccessCollection {
typealias Index = Int
typealias SubSequence = CustomArray<Element>
private var storage = NSMutableArray()
var startIndex: Int {
return 0
}
var endIndex: Int {
return storage.count
}
private mutating func copyBufferIfNeeded() {
guard !isKnownUniquelyReferenced(&storage) else { return }
storage = storage.mutableCopy() as! NSMutableArray
}
subscript(position: Int) -> Element {
get {
return storage.object(at: position) as! Element
}
mutating set(newValue) {
copyBufferIfNeeded()
if storage.count == position {
storage.add(newValue)
} else {
storage.replaceObject(at: position, with: newValue)
}
}
}
subscript(bounds: Range<Index>) -> SubSequence {
get {
return CustomArray<Element>(storage.objects(at: IndexSet(integersIn: bounds)) as! [Element])
}
set {
copyBufferIfNeeded()
let range = NSRange(bounds)
storage.replaceObjects(in: range, withObjectsFrom: Array(newValue))
}
}
mutating func replaceSubrange<C, R>(_ subrange: R, with newElements: C) where C : Collection, R : RangeExpression, Element == C.Element, CustomArray<Element>.Index == R.Bound {
copyBufferIfNeeded()
let range = NSRange(subrange)
storage.replaceObjects(in: range, withObjectsFrom: Array(newElements))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment