Last active
December 2, 2018 01:53
-
-
Save kemchenj/a61676ed13b7c17de5daaa0e3587dbf3 to your computer and use it in GitHub Desktop.
CustomArray
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
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