Last active
October 8, 2022 19:52
-
-
Save airspeedswift/1fb7d6e3e73e53ce64f6 to your computer and use it in GitHub Desktop.
Array using ManagedBuffer
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
private class MyArrayBuffer<Element>: ManagedBuffer<Int,Element> { | |
func clone() -> MyArrayBuffer<Element> { | |
return self.withUnsafeMutablePointerToElements { elements -> MyArrayBuffer<Element> in | |
return MyArrayBuffer<Element>.create(self.allocatedElementCount) { newBuf in | |
newBuf.withUnsafeMutablePointerToElements { newElems->Void in | |
newElems.initializeFrom(elements, count: self.value) | |
} | |
return self.value | |
} as! MyArrayBuffer<Element> | |
} | |
} | |
func resize(newSize: Int) -> MyArrayBuffer<Element> { | |
return self.withUnsafeMutablePointers { (val, oldElems) -> MyArrayBuffer<Element> in | |
let elementCount = self.value | |
return MyArrayBuffer<Element>.create(newSize) { newBuf in | |
newBuf.withUnsafeMutablePointerToElements { newElems->Void in | |
newElems.moveInitializeFrom(oldElems, count: elementCount) | |
} | |
val.memory = 0 | |
return elementCount | |
} as! MyArrayBuffer<Element> | |
} | |
} | |
deinit { | |
self.withUnsafeMutablePointerToElements { elems->Void in | |
elems.destroy(self.value) | |
} | |
} | |
} | |
public struct MyArray<Element> { | |
private var _buf: MyArrayBuffer<Element> | |
public init() { | |
_buf = MyArrayBuffer<Element>.create(8) { _ in 0 } as! MyArrayBuffer<Element> | |
} | |
} | |
extension MyArray { | |
private mutating func ensureUniquelyReferenced() { | |
if !isUniquelyReferencedNonObjC(&_buf) { | |
_buf = _buf.clone() | |
} | |
} | |
private mutating func reserveCapacity(n: Int) { | |
if _buf.allocatedElementCount < n { | |
self.ensureUniquelyReferenced() | |
let newSize = max(_buf.allocatedElementCount*2, n) | |
_buf = _buf.resize(newSize) | |
} | |
} | |
} | |
extension MyArray: CollectionType { | |
public var startIndex: Int { return 0 } | |
public var endIndex: Int { return _buf.value } | |
public subscript(idx: Int) -> Element { | |
get { | |
guard idx < endIndex else { fatalError("Array index out of range") } | |
return _buf.withUnsafeMutablePointerToElements { $0[idx] } | |
} | |
set(newValue) { | |
guard idx < endIndex else { fatalError("Array index out of range") } | |
self.ensureUniquelyReferenced() | |
_buf.withUnsafeMutablePointerToElements { elems->Void in | |
elems[idx] = newValue | |
} | |
} | |
} | |
} | |
extension MyArray { | |
public mutating func append(x: Element) { | |
ensureUniquelyReferenced() | |
reserveCapacity(endIndex+1) | |
_buf.withUnsafeMutablePointers { (val, elems)->Void in | |
(elems + val.memory++).initialize(x) | |
} | |
} | |
public mutating func extend<S: SequenceType where S.Generator.Element == Element>(seq: S) { | |
for x in seq { self.append(x) } | |
} | |
} | |
extension MyArray: ArrayLiteralConvertible { | |
public init(arrayLiteral elements: Element...) { | |
self = MyArray() | |
self.extend(elements) | |
} | |
} | |
extension MyArray: CustomStringConvertible { | |
public var description: String { | |
return "[" + ", ".join(self.map { String($0) }) + "]" | |
} | |
} | |
func +=<Element, S: SequenceType where S.Generator.Element == Element>(inout lhs: MyArray<Element>, rhs: S) { | |
lhs.extend(rhs) | |
} | |
func +<Element, S: SequenceType where S.Generator.Element == Element>(var lhs: MyArray<Element>, rhs: S) -> MyArray<Element> { | |
lhs += rhs | |
return lhs | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment