//===--- Utils.swift - some SIL utilities ---------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// import SILBridging //===----------------------------------------------------------------------===// // Lists //===----------------------------------------------------------------------===// public protocol ListNode : AnyObject { associatedtype Element var next: Element? { get } var previous: Element? { get } } public struct List : Sequence, IteratorProtocol, CustomReflectable where NodeType.Element == NodeType { private var currentNode: NodeType? public init(startAt: NodeType?) { currentNode = startAt } public mutating func next() -> NodeType? { if let node = currentNode { currentNode = node.next return node } return nil } public var customMirror: Mirror { let c: [Mirror.Child] = map { (label: nil, value: $0) } return Mirror(self, children: c) } } public struct ReverseList : Sequence, IteratorProtocol, CustomReflectable where NodeType.Element == NodeType { private var currentNode: NodeType? public init(startAt: NodeType?) { currentNode = startAt } public mutating func next() -> NodeType? { if let node = currentNode { currentNode = node.previous return node } return nil } public var customMirror: Mirror { let c: [Mirror.Child] = map { (label: nil, value: $0) } return Mirror(self, children: c) } } //===----------------------------------------------------------------------===// // General Utilities //===----------------------------------------------------------------------===// extension Sequence { public var isEmpty: Bool { !contains(where: { _ in true }) } } //===----------------------------------------------------------------------===// // Bridging Utilities //===----------------------------------------------------------------------===// extension BridgedStringRef { public var string: String { let buffer = UnsafeBufferPointer(start: data, count: Int(length)) return String(decoding: buffer, as: UTF8.self) } func takeString() -> String { let str = string freeBridgedStringRef(self) return str } } extension String { public func withBridgedStringRef(_ c: (BridgedStringRef) -> T) -> T { var str = self return str.withUTF8 { buffer in return c(BridgedStringRef(data: buffer.baseAddress, length: buffer.count)) } } } extension Array where Element == Value { public func withBridgedValues(_ c: (BridgedValueArray) -> T) -> T { return self.withUnsafeBytes { valPtr in assert(valPtr.count == self.count * 16) return c(BridgedValueArray(data: valPtr.baseAddress, count: self.count)) } } } public typealias SwiftObject = UnsafeMutablePointer extension UnsafeMutablePointer where Pointee == BridgedSwiftObject { init(_ object: T) { let ptr = Unmanaged.passUnretained(object).toOpaque() self = ptr.bindMemory(to: BridgedSwiftObject.self, capacity: 1) } func getAs(_ objectType: T.Type) -> T { return Unmanaged.fromOpaque(self).takeUnretainedValue() } } extension Optional where Wrapped == UnsafeMutablePointer { func getAs(_ objectType: T.Type) -> T? { if let pointer = self { return Unmanaged.fromOpaque(pointer).takeUnretainedValue() } return nil } }