Last active
August 20, 2016 12:03
-
-
Save oozoofrog/15614c428b83d8eb47dd42f3de1bf4cd to your computer and use it in GitHub Desktop.
freeing Unsafe<Mutable>Pointer casing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 MutablePointerShortener { | |
associatedtype Pointee | |
/// meaning for o(bject) | |
var o: Pointee { get set } | |
var pointee: Pointee { get set } | |
} | |
public protocol PointerShortener { | |
associatedtype Pointee | |
/// meaning for o(bject) | |
var o: Pointee { get } | |
var pointee: Pointee { get } | |
} | |
extension MutablePointerShortener where Self: UnsafePointerable { | |
public var o: Pointee { | |
set { | |
self.pointee = newValue | |
} | |
get { | |
return self.pointee | |
} | |
} | |
} | |
extension PointerShortener where Self: UnsafePointerable { | |
public var o: Pointee { | |
return self.pointee | |
} | |
} | |
extension UnsafePointer: PointerCastable, UnsafePointerable, PointerShortener {} | |
extension UnsafeMutablePointer: PointerCastable, UnsafePointerable, MutablePointerShortener {} | |
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) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment