Skip to content

Instantly share code, notes, and snippets.

@oozoofrog
Last active August 20, 2016 12:03
Show Gist options
  • Save oozoofrog/15614c428b83d8eb47dd42f3de1bf4cd to your computer and use it in GitHub Desktop.
Save oozoofrog/15614c428b83d8eb47dd42f3de1bf4cd to your computer and use it in GitHub Desktop.
freeing Unsafe<Mutable>Pointer casing
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
}
}
}
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