Skip to content

Instantly share code, notes, and snippets.

@jcampbell05
Created June 23, 2016 15:32
Show Gist options
  • Save jcampbell05/f6b5611bd7f61840edb10500fa69fd09 to your computer and use it in GitHub Desktop.
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.
//
// 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)
}
}
//
// 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