Created
June 23, 2016 15:32
-
-
Save jcampbell05/f6b5611bd7f61840edb10500fa69fd09 to your computer and use it in GitHub Desktop.
This was the only way I could create units in Swift and mimic a generic number system as well.
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
// | |
// AngleTypes.swift | |
// Sup | |
// | |
// Created by James Campbell on 22/12/2015. | |
// Copyright © 2015 Sup. All rights reserved. | |
// | |
// This File defines representations of Degrees and Radians as Type Safe Alogrithm Types | |
import Foundation | |
//MARK: AngleType | |
protocol AngleType: Unit { | |
associatedtype UnitType = Double | |
} | |
//MARK:- Degree | |
struct Degree: AngleType { | |
var value: Double = 0 | |
init() {} | |
} | |
protocol DegreeConvertiable { | |
init(degreeLiteral value: Degree) | |
} | |
extension Degree: RadianConvertiable { | |
init(radianLiteral value: Radian) { | |
self.value = Double(value) * 180.0 / M_PI | |
} | |
init(_ value: Radian) { | |
self.init(radianLiteral: value) | |
} | |
} | |
//MARK:- Radian | |
struct Radian: AngleType { | |
var value: Double = 0 | |
init() {} | |
} | |
protocol RadianConvertiable { | |
init(radianLiteral value: Radian) | |
} | |
extension Radian: DegreeConvertiable { | |
init(degreeLiteral value: Degree) { | |
self.value = Double(value) * M_PI / 180.0 | |
} | |
init(_ value: Degree) { | |
self.init(degreeLiteral: value) | |
} | |
} |
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
// | |
// Unit.swift | |
// Project | |
// | |
// Created by James Campbell on 06/01/2016. | |
// | |
// | |
// This File implements the Unit protocol for Type Safe Alogrithm Types and other useful things. This is the equivilent of Box for Value Types. | |
//MARK:- Number Generator Functions | |
extension SignedIntegerType { | |
static func make<V>(value: V) -> Self { | |
switch value { | |
case let v as CGFloat: | |
return Self.init(IntMax(v)) | |
case let v as Double: | |
return Self.init(IntMax(v)) | |
case let v as Float: | |
return Self.init(IntMax(v)) | |
case let v as Int: | |
return Self.init(IntMax(v)) | |
case let v as Int8: | |
return Self.init(IntMax(v)) | |
case let v as Int16: | |
return Self.init(IntMax(v)) | |
case let v as Int32: | |
return Self.init(IntMax(v)) | |
case let v as UInt: | |
return Self.init(IntMax(v)) | |
case let v as UInt8: | |
return Self.init(IntMax(v)) | |
case let v as UInt16: | |
return Self.init(IntMax(v)) | |
case let v as UInt32: | |
return Self.init(IntMax(v)) | |
default: | |
fatalError("Unsupported Type please use a valid Number type") | |
break | |
} | |
return Self.init(0) | |
} | |
} | |
extension UnsignedIntegerType { | |
static func make<V>(value: V) -> Self { | |
switch value { | |
case let v as CGFloat: | |
return Self.init(UIntMax(v)) | |
case let v as Double: | |
return Self.init(UIntMax(v)) | |
case let v as Float: | |
return Self.init(UIntMax(v)) | |
case let v as Int: | |
return Self.init(UIntMax(v)) | |
case let v as Int8: | |
return Self.init(UIntMax(v)) | |
case let v as Int16: | |
return Self.init(UIntMax(v)) | |
case let v as Int32: | |
return Self.init(UIntMax(v)) | |
case let v as UInt: | |
return Self.init(UIntMax(v)) | |
case let v as UInt8: | |
return Self.init(UIntMax(v)) | |
case let v as UInt16: | |
return Self.init(UIntMax(v)) | |
case let v as UInt32: | |
return Self.init(UIntMax(v)) | |
default: | |
fatalError("Unsupported Type please use a valid Number type") | |
break | |
} | |
return Self.init(0) | |
} | |
} | |
extension FloatingPointType { | |
static func make<V>(value: V) -> Self { | |
switch value { | |
case let v as CGFloat: | |
return Self.init(UIntMax(v)) | |
case let v as Double: | |
return Self.init(UIntMax(v)) | |
case let v as Float: | |
return Self.init(UIntMax(v)) | |
case let v as Int: | |
return Self.init(v) | |
case let v as Int8: | |
return Self.init(v) | |
case let v as Int16: | |
return Self.init(v) | |
case let v as Int32: | |
return Self.init(v) | |
case let v as UInt: | |
return Self.init(v) | |
case let v as UInt8: | |
return Self.init(v) | |
case let v as UInt16: | |
return Self.init(v) | |
case let v as UInt32: | |
return Self.init(v) | |
default: | |
fatalError("Unsupported Type please use a valid Integer type") | |
break | |
} | |
return Self.init(0) | |
} | |
} | |
//MARK:- Unit | |
protocol Unit: CustomStringConvertible, CustomDebugStringConvertible { | |
associatedtype UnitType = Any | |
var value: UnitType { get set } | |
init() | |
init(_ value: UnitType) | |
} | |
//MARK: Unit - String Conversion | |
extension Unit where UnitType: CustomStringConvertible { | |
var description: String { | |
return self.value.description | |
} | |
var debugDescription: String { | |
return "\(self.value.description)" | |
} | |
} | |
extension Unit { | |
init(_ value: Self.UnitType) { | |
self.init() | |
self.value = value | |
} | |
} | |
//MARK:- Unit - Initilzing With SignedIntegerType | |
extension Unit where Self.UnitType: SignedIntegerType { | |
init<T where T: UnsignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: SignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: FloatingPointType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
} | |
//MARK:- Unit - Initilzing With UnsignedIntegerType | |
extension Unit where Self.UnitType: UnsignedIntegerType { | |
init<T where T: UnsignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: SignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: FloatingPointType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
} | |
//MARK:- Unit - Initilzing With FloatingPointType | |
extension Unit where Self.UnitType: FloatingPointType { | |
init<T where T: UnsignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: SignedIntegerType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
init<T where T: FloatingPointType>(_ value: T) { | |
self.init() | |
self.value = Self.UnitType.make(value) | |
} | |
} | |
//MARK:- Unit - IntegerLiteralConvertible | |
extension Unit where Self.UnitType: SignedNumberType, Self.UnitType == Self.UnitType.IntegerLiteralType { | |
init(_ value: Self.UnitType) { | |
self.init() | |
self.value = value | |
} | |
} | |
//MARK:- Unit - FloatLiteralConvertible | |
extension Unit where Self.UnitType: FloatLiteralConvertible, Self.UnitType == Self.UnitType.FloatLiteralType { | |
init(_ value: Self.UnitType) { | |
self.init() | |
self.value = value | |
} | |
} | |
//MARK:- UnitConvertable | |
protocol UnitConvertable { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) | |
} | |
//MARK:- Unit - FloatingPointType Conversion | |
extension SignedIntegerType { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) { | |
self.init(IntMax.make(value.value)) | |
} | |
} | |
extension UnsignedIntegerType { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) { | |
self.init(UIntMax.make(value.value)) | |
} | |
} | |
extension Float: UnitConvertable { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) { | |
switch(value.value) { | |
case let v as CGFloat: | |
self.init(v) | |
break | |
case let v as Float: | |
self.init(v) | |
break | |
case let v as Double: | |
self.init(v) | |
break | |
default: | |
self.init(Float.make(value.value)) | |
break | |
} | |
} | |
} | |
extension Double: UnitConvertable { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) { | |
switch(value.value) { | |
case let v as CGFloat: | |
self.init(v) | |
break | |
case let v as Float: | |
self.init(v) | |
break | |
case let v as Double: | |
self.init(v) | |
break | |
default: | |
self.init(Double.make(value.value)) | |
break | |
} | |
} | |
} | |
extension CGFloat: UnitConvertable { | |
init<T: Unit where T.UnitType: SignedNumberType>(_ value: T) { | |
switch(value.value) { | |
case let v as CGFloat: | |
self.init(v) | |
break | |
case let v as Float: | |
self.init(v) | |
break | |
case let v as Double: | |
self.init(v) | |
break | |
default: | |
self.init(NativeType.make(value.value)) | |
break | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment