元のソースをすこしアップグレードして、swift3b6への適用も完了しました。
https://gist.github.com/singcodes/15614c428b83d8eb47dd42f3de1bf4cd
###swift 3
- mutable関数を削除し、全ての機能をcast関数で含めました。
- pointeeの短いバージョンのo変数を追加しました。
- mutable pointerの場合setが出来、ただのpointerの場合、エラーなしで無視されます。
- ただし、無視されるのはswift的のことではないので、どう修正すればいいか考えています。できれば、protocolのextension中で解決したいんですが…いい考えがある方は是非お願いします。
- raw pointerへの変更も出来るように、castRaw関数を追加しました。
//
// Castable.swift
// Castable
//
// Created by jayios on 2016. 6. 23..
// Copyright © 2016년 ngenii. All rights reserved.
//
import Foundation
import CoreGraphics
public protocol PointerCastable {}
public protocol UnsafePointerable {
init(_ other: UnsafePointer<Pointee>)
init?(_ other: UnsafePointer<Pointee>?)
init(_ other: UnsafeMutablePointer<Pointee>)
init?(_ other: UnsafeMutablePointer<Pointee>?)
associatedtype Pointee
var pointee: Pointee { get }
func withMemoryRebound<T, Result>(to: T.Type, capacity count: Int, _ body: (UnsafeMutablePointer<T>) throws -> Result) rethrows -> Result
}
public protocol PointerShortener {
associatedtype Pointee
/// meaning for o(bject)
var o: Pointee { get set }
var pointee: Pointee { get }
}
extension PointerShortener where Self: UnsafePointerable {
public var o: Pointee {
set {
if let mutable = self as? UnsafeMutablePointer<Pointee> {
mutable.pointee = newValue
}
}
get {
return self.pointee
}
}
}
extension UnsafePointer: PointerCastable, UnsafePointerable, PointerShortener {}
extension UnsafeMutablePointer: PointerCastable, UnsafePointerable, PointerShortener {}
public protocol UnsafeRawPointerable{
init<T>(_ other: UnsafePointer<T>)
init?<T>(_ other: UnsafePointer<T>?)
init<T>(_ other: UnsafeMutablePointer<T>)
init?<T>(_ other: UnsafeMutablePointer<T>?)
}
extension UnsafeRawPointer: UnsafeRawPointerable, PointerCastable {}
extension UnsafeMutableRawPointer: UnsafeRawPointerable, PointerCastable {}
extension PointerCastable where Self: UnsafePointerable {
public func cast<P: UnsafePointerable, M>() -> P? where P.Pointee == M {
if self is P {
return self as? P
}
let ptr = self.withMemoryRebound(to: M.self, capacity: MemoryLayout<M>.stride){$0}
return P(ptr)
}
public func cast<P: UnsafePointerable, M>() -> P where P.Pointee == M {
if self is P {
return self as! P
}
let ptr = self.withMemoryRebound(to: M.self, capacity: MemoryLayout<M>.stride){$0}
return P(ptr)
}
public func castRaw<R: UnsafeRawPointerable, T>(from: T.Type) -> R? {
if R.self == UnsafeRawPointer.self {
let ptr: UnsafePointer<T> = self.cast()
return R(ptr)
}
let ptr: UnsafeMutablePointer<T> = self.cast()
return R(ptr)
}
public func castRaw<R: UnsafeRawPointerable, T>(from: T.Type) -> R {
if R.self == UnsafeRawPointer.self {
let ptr: UnsafePointer<T> = self.cast()
return R(ptr)
}
let ptr: UnsafeMutablePointer<T> = self.cast()
return R(ptr)
}
}
extension PointerCastable where Self: UnsafeRawPointerable {
public func cast<P: UnsafePointerable, M>(to: M.Type) -> P where P.Pointee == M {
if self is UnsafeRawPointer {
let raw = self as! UnsafeRawPointer
let ptr = raw.assumingMemoryBound(to: M.self)
return P(ptr)
} else {
let raw: UnsafeMutableRawPointer = self as! UnsafeMutableRawPointer
let ptr = raw.assumingMemoryBound(to: M.self)
return P(ptr)
}
}
}
###swift 2
Usage:
let a = malloc(sizeof(Int)) -> Intのサイズを持つUnsafePointer<Void>を作成
let b: UnsafeMutablePointer<Int> = a.mutable() -> UnsafeMutablePointer<Int>にキャストされます。
protocol Castable {}
protocol UnsafePointerProtocol: NilLiteralConvertible {
associatedtype Memory
init(nilLiteral: ())
init<Memory>(_ from: UnsafeMutablePointer<Memory>)
init<Memory>(_ from: UnsafePointer<Memory>)
var memory: Memory { get }
func mutable<M>() -> UnsafeMutablePointer<M>
}
extension UnsafeMutablePointer : UnsafePointerProtocol, Castable{}
extension UnsafePointer : UnsafePointerProtocol, Castable{}
extension UnsafePointerProtocol where Self: Castable {
func cast<P: UnsafePointerProtocol, M where M == P.Memory>() -> P {
switch self {
case let ptr as UnsafePointer<Memory>:
return P(ptr)
case let ptr as UnsafeMutablePointer<Memory>:
return P(ptr)
default:
return nil
}
}
func mutable<M>() -> UnsafeMutablePointer<M> {
switch self {
case let ptr as UnsafePointer<Memory>:
return UnsafeMutablePointer<M>(ptr)
case let ptr as UnsafeMutablePointer<Memory>:
return UnsafeMutablePointer<M>(ptr)
default:
return nil
}
}
}
protocol Pointerable {
associatedtype Element
var pointer: UnsafePointer<Element> {get}
}
extension Array : Pointerable {}
extension ArraySlice : Pointerable {
func array() -> Array<Element> {
return Array<Element>(self)
}
}
extension Pointerable where Self: SequenceType {
var pointer: UnsafePointer<Element> {
switch self {
case let a as Array<Element>:
return UnsafePointer<Element>(a)
case let s as ArraySlice<Element>:
return UnsafePointer<Element>(s.array())
default:
return nil
}
}
}