class Task : Comparable, CustomStringConvertible { var priority : Int var name: String init(priority: Int, name: String) { self.priority = priority self.name = name } var description: String { return "\(priority), \(name)" } } func ==(t1: Task, t2: Task) -> Bool { return t1.priority == t2.priority } func <(t1: Task, t2: Task) -> Bool { return t1.priority < t2.priority } struct TaskPriorityQueue { let heap : CFBinaryHeapRef = { var callBacks = CFBinaryHeapCallBacks(version: 0, retain: { UnsafePointer(Unmanaged.fromOpaque(COpaquePointer($1)).retain().toOpaque()) }, release: { Unmanaged.fromOpaque(COpaquePointer($1)).release() }, copyDescription: nil, compare: { (ptr1, ptr2, _) in let t1 : Task = Unmanaged.fromOpaque(COpaquePointer(ptr1)).takeUnretainedValue() let t2 : Task = Unmanaged.fromOpaque(COpaquePointer(ptr2)).takeUnretainedValue() return t1 == t2 ? CFComparisonResult.CompareEqualTo : t1 < t2 ? CFComparisonResult.CompareLessThan : CFComparisonResult.CompareGreaterThan }) return CFBinaryHeapCreate(nil, 0, &callBacks, nil) }() var count : Int { return CFBinaryHeapGetCount(heap) } mutating func push(t: Task) { CFBinaryHeapAddValue(heap, UnsafePointer(Unmanaged.passUnretained(t).toOpaque())) } func peek() -> Task { return Unmanaged.fromOpaque(COpaquePointer(CFBinaryHeapGetMinimum(heap))).takeUnretainedValue() } mutating func pop() -> Task { let result = Unmanaged.fromOpaque(COpaquePointer(CFBinaryHeapGetMinimum(heap))).takeUnretainedValue() CFBinaryHeapRemoveMinimumValue(heap) return result } } var pq = TaskPriorityQueue() pq.push(Task(priority: 3, name: "Clear drains")) pq.push(Task(priority: 4, name: "Feed cat")) pq.push(Task(priority: 5, name: "Make tea")) pq.push(Task(priority: 1, name: "Solve RC tasks")) pq.push(Task(priority: 2, name: "Tax return")) while pq.count != 0 { print(pq.pop()) }