Skip to content

Instantly share code, notes, and snippets.

@RoshanNindrai
Last active May 21, 2017 23:10
Show Gist options
  • Select an option

  • Save RoshanNindrai/b12b4fb3684a6a2ef354c7d32aaedf27 to your computer and use it in GitHub Desktop.

Select an option

Save RoshanNindrai/b12b4fb3684a6a2ef354c7d32aaedf27 to your computer and use it in GitHub Desktop.
This is an exercise to implement List using swift mutable pointers
// List implementation using UnsafeMutablePointer.
final class InternalList<T> {
var count: Int
var size: Int
var ptr: UnsafeMutablePointer<T>?
init(count: Int, ptrs: UnsafeMutablePointer<T>? = nil) {
self.count = count
size = count
ptr = ptrs
}
func append(_ data: T) {
// Time to allocate some memory ohh yeah
if size == count {
let newSize = max(2 * size, 16)
let newPtr = UnsafeMutablePointer<T>.allocate(capacity: newSize)
if ptr != nil {
newPtr.moveInitialize(from: ptr!, count: count)
}
ptr?.deallocate(capacity: size)
ptr = newPtr
}
(ptr! + count).initialize(to: data)
count += 1
}
func remove(at index: Int) {
guard count != 0, index < count else {
return
}
(ptr! + index).deinitialize()
ptr!.moveInitialize(from: ptr! + index + 1, count: count - index - 1)
count -= 1
}
func at(_ index: Int) -> T {
guard index < count else {
fatalError("Index out of range")
}
return ptr![index]
}
func update(at index: Int, data: T) {
guard index <= count else {
return
}
(ptr! + index).initialize(to: data)
count += 1
}
func copy() -> InternalList<T> {
return InternalList(count: count, ptrs: ptr)
}
}
struct List<T> {
fileprivate var _internalData: InternalList<T> = InternalList<T>(count: 0)
var count: Int {
return _internalData.count ?? 0
}
var isEmpty: Bool {
return count == 0
}
}
extension List {
mutating func append(_ data: T) {
copyIfNeeded()
_internalData.append(data)
}
mutating func remove(at index: Int) {
copyIfNeeded()
_internalData.remove(at: index)
}
subscript(_ index: Int) -> T {
get {
return _internalData.at(index)
}
set {
copyIfNeeded()
_internalData.update(at: index, data: newValue)
}
}
}
extension List {
mutating func copyIfNeeded() {
if !isKnownUniquelyReferenced(&_internalData) {
_internalData = _internalData.copy()
}
}
}
var testList = List<Int>()
assert(testList.isEmpty)
assert(testList.count == 0)
testList.append(1)
assert(testList.count == 1)
assert(!testList.isEmpty)
XCAssertTrue(testList[0] == 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment