| // Playground - noun: a place where people can play | |
| import Cocoa | |
| protocol UnitBase { | |
| class var unitLabel:String { get } | |
| } | |
| // T: the unit | |
| // U: its inverse | |
| struct Unit<T:UnitBase,U:UnitBase> : Printable, Comparable { | |
| var value:Double | |
| init(_ v:Double) { value = v } | |
| var description:String { return "\(value) \(T.unitLabel)" } | |
| var inverse:Unit<U,T> { return Unit<U,T>(1/value) } | |
| } | |
| func == <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Bool { return lhs.value == rhs.value } | |
| func <= <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Bool { return lhs.value <= rhs.value } | |
| func >= <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Bool { return lhs.value >= rhs.value } | |
| func < <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Bool { return lhs.value < rhs.value } | |
| func > <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Bool { return lhs.value > rhs.value } | |
| func + <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Unit<T,U> { return Unit<T,U>(lhs.value + rhs.value) } | |
| func - <T,U>(lhs:Unit<T,U>, rhs:Unit<T,U>) -> Unit<T,U> { return Unit<T,U>(lhs.value - rhs.value) } | |
| func * <T,U>(lhs:Double, rhs:Unit<T,U>) -> Unit<T,U> { return Unit<T,U>(lhs * rhs.value) } | |
| func * <T,U>(lhs:Unit<T,U>, rhs:Double) -> Unit<T,U> { return Unit<T,U>(lhs.value * rhs) } | |
| func / <T,U>(lhs:Double, rhs:Unit<T,U>) -> Unit<U,T> { return lhs * rhs.inverse } | |
| func / <T,U>(lhs:Unit<T,U>, rhs:Double) -> Unit<T,U> { return Unit<T,U>(lhs.value / rhs) } | |
| @assignment func += <T,U>(inout lhs:Unit<T,U>, rhs:Unit<T,U>) { lhs = lhs + rhs; } | |
| @assignment func -= <T,U>(inout lhs:Unit<T,U>, rhs:Unit<T,U>) { lhs = lhs - rhs; } | |
| @assignment func *= <T,U>(inout lhs:Unit<T,U>, rhs:Double) { lhs = lhs * rhs; } | |
| @assignment func /= <T,U>(inout lhs:Unit<T,U>, rhs:Double) { lhs = lhs / rhs; } | |
| struct RateBase: UnitBase { static var unitLabel = "Hz" } | |
| struct DurationBase: UnitBase { static var unitLabel = "sec" } | |
| typealias Rate = Unit<RateBase,DurationBase> | |
| typealias Duration = Unit<DurationBase,RateBase> | |
| extension Double { | |
| var Hz:Rate { return Rate(self) } | |
| var kHz:Rate { return Rate(self*1000) } | |
| var sec:Duration { return Duration(self) } | |
| var msec:Duration { return Duration(self*0.001) } | |
| var min:Duration { return Duration(self*60) } | |
| } | |
| // the explicit description calls are due to a struct-printing bug in Xcode | |
| (100.Hz).description | |
| (44.1.kHz).description | |
| (20.sec).description | |
| (5000.msec).description | |
| (3.min).description | |
| (10.Hz + 20.Hz).description | |
| (20.sec * 2).description | |
| (3 * 4.sec).description | |
| (2.min / 5).description | |
| (1/10.sec).description | |
| (1/20.Hz).description | |
| (10.sec + 1/(3.Hz)).description | |
| var t = 20.sec | |
| t += 50.msec | |
| t.description | |
| // Won't compile | |
| //3.sec + 2.Hz | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment