Last active
July 8, 2017 12:31
-
-
Save beccadax/7d6b1e54ab13f3859227e4dc613b354c to your computer and use it in GitHub Desktop.
Explicit conversion operator for Swift.
This file contains hidden or 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 ExplicitlyConvertible | |
let i8: Int8 = 8 | |
let i64: Int64 = 64 | |
i64 + ^i8 // => 72 | |
struct Person { | |
var name: String | |
var birthDate: Date | |
} | |
let people: [Person] = [] | |
let names = people.map(^\.name) | |
type(of: names) // => Array<String> |
This file contains hidden or 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
prefix operator ^ | |
/// Conforming types can be unconditionally, losslessly converted to | |
/// another type through the explicit conversion operator, `^`. | |
public protocol ExplicitlyConvertible { | |
associatedtype ExplicitConversionSupertype | |
/// Converts `self` to an equivalent supertype, such as a wider | |
/// integer type. | |
static prefix func ^(operand: Self) -> ExplicitConversionSupertype | |
} | |
// Operators below this point simply let you indirectly convert through | |
// several explicit supertypes at once. Five is an arbitrary choice; it | |
// just happens to be more than high enough to get you from the | |
// smallest integers to the largest. | |
extension ExplicitlyConvertible where ExplicitConversionSupertype: ExplicitlyConvertible { | |
public static prefix func ^(operand: Self) -> ExplicitConversionSupertype.ExplicitConversionSupertype { | |
return ^(^operand) | |
} | |
} | |
extension ExplicitlyConvertible where ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible { | |
public static prefix func ^(operand: Self) -> ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype { | |
return ^(^(^operand)) | |
} | |
} | |
extension ExplicitlyConvertible where ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible { | |
public static prefix func ^(operand: Self) -> ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype { | |
return ^(^(^(^operand))) | |
} | |
} | |
extension ExplicitlyConvertible where ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible, ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype: ExplicitlyConvertible { | |
public static prefix func ^(operand: Self) -> ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype.ExplicitConversionSupertype { | |
return ^(^(^(^(^operand)))) | |
} | |
} |
This file contains hidden or 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
extension Int8: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = Int16 | |
} | |
extension Int16: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = Int32 | |
} | |
extension Int32: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = Int | |
} | |
extension Int: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = Int64 | |
} | |
extension UInt8: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = UInt16 | |
} | |
extension UInt16: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = UInt32 | |
} | |
extension UInt32: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = UInt | |
} | |
extension UInt: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = UInt64 | |
} | |
extension ExplicitlyConvertible where Self: BinaryInteger, ExplicitConversionSupertype: BinaryInteger { | |
/// Converts the integer to a wider integer type. | |
public static prefix func ^(operand: Self) -> ExplicitConversionSupertype { | |
return ExplicitConversionSupertype(operand) | |
} | |
} |
This file contains hidden or 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
extension KeyPath: ExplicitlyConvertible { | |
public typealias ExplicitConversionSupertype = (Root) -> Value | |
/// Converts the KeyPath to a getter function. | |
public static prefix func ^(operand: KeyPath<Root, Value>) -> (Root) -> Value { | |
return { $0[keyPath: operand] } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment