I'm currently trying to implement my own DynamicArray
data type in Swift. To do so I'm using pointers a bit. As my root
I'm using an UnsafeMutablePointer
of a generic type T
:
struct DynamicArray<T> {
private var root: UnsafeMutablePointer<T> = nil
private var capacity = 0 {
didSet {
//...
}
}
//...
init(capacity: Int) {
root = UnsafeMutablePointer<T>.alloc(capacity)
self.capacity = capacity
}
init(count: Int, repeatedValue: T) {
self.init(capacity: count)
for index in 0..<count {
(root + index).memory = repeatedValue
}
self.count = count
}
//...
}
Now as you can see I've also implemented a capacity
property which tells me how much memory is currently allocated for root
. Accordingly one can create an instance of DynamicArray
using the init(capacity:)
initializer, which allocates the appropriate amount of memory, and sets the capacity
property.
But then I also implemented the init(count:repeatedValue:)
initializer, which first allocates the needed memory using init(capacity: count)
. It then sets each segment in that part of memory to the repeatedValue
.
When using the init(count:repeatedValue:)
initializer with number types like Int
, Double
, or Float
it works perfectly fine. Then using Character
, or String
though it crashes. It doesn't crash consistently though, but actually works sometimes, as can be seen here, by compiling a few times.
var a = DynamicArray<Character>(count: 5, repeatedValue: "A")
println(a.description) //prints [A, A, A, A, A]
//crashes most of the time
var b = DynamicArray<Int>(count: 5, repeatedValue: 1)
println(a.description) //prints [1, 1, 1, 1, 1]
//works consistently
Why is this happening? Does it have to do with String
and Character
holding values of different length?
Update #1:
Now @AirspeedVelocity addressed the problem with init(count:repeatedValue:)
. The DynamicArray
contains another initializer though, which at first worked in a similar fashion as init(count:repeatedValue:)
. I changed it to work, as @AirspeedVelocity described for init(count:repeatedValue:)
though:
init<C: CollectionType where C.Generator.Element == T, C.Index.Distance == Int>(collection: C) {
let collectionCount = countElements(collection)
self.init(capacity: collectionCount)
root.initializeFrom(collection)
count = collectionCount
}
I'm using the initializeFrom(source:)
method as described here. And since collection
conforms to CollectionType
it should work fine.
I'm now getting this error though:
<stdin>:144:29: error: missing argument for parameter 'count' in call
root.initializeFrom(collection)
^
Is this just a misleading error message again?