 }
 public func /= <T: CGFloatTupleConvertible>(inout lhs: T, rhs: CGFloat) {
     lhs = lhs / rhs
+}
+
+public func * <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(lhs: T, rhs: U) -> T {
+    return lhs.merge(rhs, *)
+}
+public func *= <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(inout lhs: T, rhs: U) {
+    lhs = lhs * rhs
+}
+
+public func / <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(lhs: T, rhs: U) -> T {
+    return lhs.merge(rhs, /)
+}
+public func /= <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(inout lhs: T, rhs: U) {
+    lhs = lhs / rhs
+}
+
+public func + <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(lhs: T, rhs: U) -> T {
+    return lhs.merge(rhs, +)
+}
+public func += <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(inout lhs: T, rhs: U) {
+    lhs = lhs + rhs
+}
+
+public func - <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(lhs: T, rhs: U) -> T {
+    return lhs.merge(rhs, -)
+}
+public func -= <T: CGFloatTupleConvertible, U: CGFloatTupleConvertible>(inout lhs: T, rhs: U) {
+    lhs = lhs - rhs
+}
+
+public prefix func + <T: CGFloatTupleConvertible>(rhs: T) -> T {
+    return rhs
+}
+public prefix func - <T: CGFloatTupleConvertible>(rhs: T) -> T {
+    return rhs.map { -$0 }
+}
+
+public func abs<T: CGFloatTupleConvertible>(x: T) -> T {
+    return x.map { abs($0) }
 }
 
 /// CGPoint, CGVector and CGSize can be converted to a pair of floats.

public protocol CGFloatTupleConvertible {    
    var tuple: CGFloatTuple { get }
    init(tuple: CGFloatTuple)
}

/// Functional methods used to apply transforms to a pair of floats

        let newOrigin = origin.pointByClamping(newRect)
        
        return CGRect(origin: newOrigin, size: size)
    }
    
    public init(origin: CGPoint, width: CGFloat, height: CGFloat) {
        self.init(x: origin.x, y: origin.y, width: width, height: height)
    }
    
    public init(x: CGFloat, y: CGFloat, size: CGSize) {
        self.init(x: x, y: y, width: size.width, height: size.height)
    }
    
    public var center: CGPoint {
        return CGPoint(x: midX, y: midY)
    }
}

