// FIXME: Replace with a tuple having named elements pending // (Naming tuple elements breaks Slice // conformance to all protocols) struct DictionaryEnumerator : Enumerator { typealias Element = (key: Key, value: Value) var elements: Optional[] var size: Int var count: Int func isEmpty() -> Bool { return size == 0 || count == elements.length } func next() -> Element { while count != elements.length && elements[count] == None { ++count } var e = Element(elements[count].get()) ++count while count != elements.length && elements[count] == None { ++count } return e } } class Dictionary : Object, Enumerable, DictionaryLiteralConvertible { typealias Key = KeyType typealias Value = ValueType typealias Element = (key: KeyType, value: ValueType) var elements: Optional[] var size: Int typealias EnumeratorType = DictionaryEnumerator constructor(bc : Int = 127) { elements = new Optional[bc] } func getBucketCount() -> Int { return elements.length } func add(k : Key, v : Value) -> Bool { var h = k.hashValue() var index = Int(UInt(h) % UInt(elements.length)) var count = 0 while elements[index] != None && elements[index].get().0 != k { ++index if index == elements.length { index = 0 } ++count if count == elements.length { return false } } if !elements[index] { ++size } elements[index] = Some((k,v)) return true } func find(k : Key) -> Optional { var h = k.hashValue() var index = Int(UInt(h) % UInt(elements.length)) var count = 0 while (!elements[index] || elements[index].get().0 != k) { ++index if index == elements.length { index = 0 } ++count if count == elements.length { return None } } return Some(elements[index].get().1) } subscript (k : Key) -> Value { get: return find(k).get() set(value): add(k, value) } func itemsAsArray() -> Element[] { var result = new Element[size] var index = 0 for i in 0..getBucketCount() { // FIXME: Can't use destructuring bind pending // (Naming tuple elements breaks Slice // conformance to all protocols) if elements[i] != None { var e = elements[i].get() result[index++] = Element(e.key, e.value) } } return result } func getEnumeratorType() -> EnumeratorType { return EnumeratorType(elements, size, 0) } // // DictionaryLiteralConvertible conformance // static func convertFromDictionaryLiteral(elements:(Key, Value)...) -> Dictionary { var dict = Dictionary() for (k, v) in elements { dict.add(k, v) } return dict } // FIXME: Disabled pending more capable generics that can make this // replPrintable when KeyType and ValueType are /* func replPrint() { print("[") var first = true for (key, value) in this { if first { first = false } else { print(", ") } print((key, value)) } print("]") } */ } func replPrint(x: Dictionary) { print("[") var prefix = "" for o in x.elements { // FIXME: Can't use destructuring bind pending // (Naming tuple elements breaks Slice // conformance to all protocols) if o != None { var (k,v) = o.get() print("\(prefix)\"\(k)\": \(v)") prefix = ", " } } print("]") }