I'm trying to create a type similar to Array<U>, except that it's indexed by a type T other than Int. To reduce the complexity of the (envisioned) implementation, I planned to use an underlying ("sparse" array) [U?] variable, and to require T to be RawRepresentible so that its raw values can be used to index the underlying array. This should work well with the intended use case, where T is an 'enum E: Int' type whose cases are sequentially assigned, more or less.
However, I can't find a way of writing the type so that it satisfies CollectionType. I don't know how to fix the compiler errors in the following attempted implementation, and it's made triply hard by the fact that this code pretty much crashes SourceKit and the compiler itself (with a segmentation fault: 11). I'm open to any suggestions about how to make this compile, or alternate techniques to achieve approximately the same effect.
public struct EnumeratedArrayGenerator<T: RawRepresentable, U>: GeneratorType {
public mutating func next () -> U? {
while index < array.count {
if let element = array [index] { return element }
}
return nil
}
private var array: [U?]
private var index = 0
private init (array: [U?]) {
self.array = array
}
}
public struct EnumeratedArray<T: RawRepresentable, U where T.RawValue == Int>: SequenceType, CollectionType {
private var array: [U?] = []
public subscript (position: T) -> U {
return array [position.rawValue]!
}
public var isEmpty: Bool {
return count == 0
}
public var count: Int {
return array.filter { $0 != nil }.count
}
public func generate () -> EnumeratedArrayGenerator<T, U> {
return EnumeratedArrayGenerator<T, U> (array: array)
}
}
public var startIndex: Fit<T> {
return Fit<T> (rawValue: 0, count: array.count)
}
public var endIndex: Fit<T> {
return Fit (rawValue: nil, count: array.count)
}
and because your index is the same count as your native array, not the same count of your collectionType, you should use array.count instead of count.