 
 // MARK: operators
 
+/// Returns a point by adding the coordinates of another point.
 public func +(p1: CGPoint, p2: CGPoint) -> CGPoint {
     return CGPoint(x: p1.x + p2.x, y: p1.y + p2.y)
 }
+/// Modifies the x and y values by adding the coordinates of another point.
 public func +=(inout p1: CGPoint, p2: CGPoint) {
     p1.x += p2.x
     p1.y += p2.y
 }
+/// Returns a point by subtracting the coordinates of another point.
 public func -(p1: CGPoint, p2: CGPoint) -> CGPoint {
     return CGPoint(x: p1.x - p2.x, y: p1.y - p2.y)
 }
+/// Modifies the x and y values by subtracting the coordinates of another points.
 public func -=(inout p1: CGPoint, p2: CGPoint) {
     p1.x -= p2.x
     p1.y -= p2.y
 }
 
+/// Returns a point by adding a size to the coordinates.
 public func +(point: CGPoint, size: CGSize) -> CGPoint {
     return CGPoint(x: point.x + size.width, y: point.y + size.height)
 }
+/// Modifies the x and y values by adding a size to the coordinates.
 public func +=(inout point: CGPoint, size: CGSize) {
     point.x += size.width
     point.y += size.height
 }
+/// Returns a point by subtracting a size from the coordinates.
 public func -(point: CGPoint, size: CGSize) -> CGPoint {
     return CGPoint(x: point.x - size.width, y: point.y - size.height)
 }
+/// Modifies the x and y values by subtracting a size from the coordinates.
 public func -=(inout point: CGPoint, size: CGSize) {
     point.x -= size.width
     point.y -= size.height
 }
 
+/// Returns a point by adding a tuple to the coordinates.
 public func +(point: CGPoint, tuple: (CGFloat, CGFloat)) -> CGPoint {
     return CGPoint(x: point.x + tuple.0, y: point.y + tuple.1)
 }
+/// Modifies the x and y values by adding a tuple to the coordinates.
 public func +=(inout point: CGPoint, tuple: (CGFloat, CGFloat)) {
     point.x += tuple.0
     point.y += tuple.1
 }
+/// Returns a point by subtracting a tuple from the coordinates.
 public func -(point: CGPoint, tuple: (CGFloat, CGFloat)) -> CGPoint {
     return CGPoint(x: point.x - tuple.0, y: point.y - tuple.1)
 }
+/// Modifies the x and y values by subtracting a tuple from the coordinates.
 public func -=(inout point: CGPoint, tuple: (CGFloat, CGFloat)) {
     point.x -= tuple.0
     point.y -= tuple.1
 }
+/// Returns a point by multiplying the coordinates with a value.
 public func *(point: CGPoint, factor: CGFloat) -> CGPoint {
     return CGPoint(x: point.x * factor, y: point.y * factor)
 }
+/// Modifies the x and y values by multiplying the coordinates with a value.
 public func *=(inout point: CGPoint, factor: CGFloat) {
     point.x *= factor
     point.y *= factor
 }
+/// Returns a point by multiplying the coordinates with a tuple.
 public func *(point: CGPoint, tuple: (CGFloat, CGFloat)) -> CGPoint {
     return CGPoint(x: point.x * tuple.0, y: point.y * tuple.1)
 }
+/// Modifies the x and y values by multiplying the coordinates with a tuple.
 public func *=(inout point: CGPoint, tuple: (CGFloat, CGFloat)) {
     point.x *= tuple.0
     point.y *= tuple.1
 }
+/// Returns a point by dividing the coordinates by a tuple.
 public func /(point: CGPoint, tuple: (CGFloat, CGFloat)) -> CGPoint {
     return CGPoint(x: point.x / tuple.0, y: point.y / tuple.1)
 }
+/// Modifies the x and y values by dividing the coordinates by a tuple.
 public func /=(inout point: CGPoint, tuple: (CGFloat, CGFloat)) {
     point.x /= tuple.0
     point.y /= tuple.1
 }
+/// Returns a point by dividing the coordinates by a factor.
 public func /(point: CGPoint, factor: CGFloat) -> CGPoint {
     return CGPoint(x: point.x / factor, y: point.y / factor)
 }
+/// Modifies the x and y values by dividing the coordinates by a factor.
 public func /=(inout point: CGPoint, factor: CGFloat) {
     point.x /= factor
     point.y /= factor
 }
 
+/// Returns a point by adding another size.
 public func +(s1: CGSize, s2: CGSize) -> CGSize {
     return CGSize(width: s1.width + s2.width, height: s1.height + s2.height)
 }
+/// Modifies the width and height values by adding another size.
 public func +=(inout s1: CGSize, s2: CGSize) {
     s1.width += s2.width
     s1.height += s2.height
 }
+/// Returns a point by subtracting another size.
 public func -(s1: CGSize, s2: CGSize) -> CGSize {
     return CGSize(width: s1.width - s2.width, height: s1.height - s2.height)
 }
+/// Modifies the width and height values by subtracting another size.
 public func -=(inout s1: CGSize, s2: CGSize) {
     s1.width -= s2.width
     s1.height -= s2.height
 }
 
+/// Returns a point by adding a tuple.
 public func +(size: CGSize, tuple: (CGFloat, CGFloat)) -> CGSize {
     return CGSize(width: size.width + tuple.0, height: size.height + tuple.1)
 }
+/// Modifies the width and height values by adding a tuple.
 public func +=(inout size: CGSize, tuple: (CGFloat, CGFloat)) {
     size.width += tuple.0
     size.height += tuple.1
 }
+/// Returns a point by subtracting a tuple.
 public func -(size: CGSize, tuple: (CGFloat, CGFloat)) -> CGSize {
     return CGSize(width: size.width - tuple.0, height: size.height - tuple.1)
 }
+/// Modifies the width and height values by subtracting a tuple.
 public func -=(inout size: CGSize, tuple: (CGFloat, CGFloat)) {
     size.width -= tuple.0
     size.height -= tuple.1
 }
+/// Returns a point by multiplying the size with a factor.
 public func *(size: CGSize, factor: CGFloat) -> CGSize {
     return CGSize(width: size.width * factor, height: size.height * factor)
 }
+/// Modifies the width and height values by multiplying them with a factor.
 public func *=(inout size: CGSize, factor: CGFloat) {
     size.width *= factor
     size.height *= factor
 }
+/// Returns a point by multiplying the size with a tuple.
 public func *(size: CGSize, tuple: (CGFloat, CGFloat)) -> CGSize {
     return CGSize(width: size.width * tuple.0, height: size.height * tuple.1)
 }
+/// Modifies the width and height values by multiplying them with a tuple.
 public func *=(inout size: CGSize, tuple: (CGFloat, CGFloat)) {
     size.width *= tuple.0
     size.height *= tuple.1
 }
+/// Returns a point by dividing the size by a factor.
 public func /(size: CGSize, factor: CGFloat) -> CGSize {
     return CGSize(width: size.width / factor, height: size.height / factor)
 }
+/// Modifies the width and height values by dividing them by a factor.
 public func /=(inout size: CGSize, factor: CGFloat) {
     size.width /= factor
     size.height /= factor
 }
+/// Returns a point by dividing the size by a tuple.
 public func /(size: CGSize, tuple: (CGFloat, CGFloat)) -> CGSize {
     return CGSize(width: size.width / tuple.0, height: size.height / tuple.1)
 }
+/// Modifies the width and height values by dividing them by a tuple.
 public func /=(inout size: CGSize, tuple: (CGFloat, CGFloat)) {
     size.width /= tuple.0
     size.height /= tuple.1
 }
 
+/// Returns a rect by adding the coordinates of a point to the origin.
 public func +(rect: CGRect, point: CGPoint) -> CGRect {
     return CGRect(origin: rect.origin + point, size: rect.size)
 }
+/// Modifies the x and y values by adding the coordinates of a point.
 public func +=(inout rect: CGRect, point: CGPoint) {
     rect.origin += point
 }
+/// Returns a rect by subtracting the coordinates of a point from the origin.
 public func -(rect: CGRect, point: CGPoint) -> CGRect {
     return CGRect(origin: rect.origin - point, size: rect.size)
 }
+/// Modifies the x and y values by subtracting the coordinates from a point.
 public func -=(inout rect: CGRect, point: CGPoint) {
     rect.origin -= point
 }
 
+/// Returns a rect by adding a size to the size.
 public func +(rect: CGRect, size: CGSize) -> CGRect {
     return CGRect(origin: rect.origin, size: rect.size + size)
 }
+/// Modifies the width and height values by adding a size.
 public func +=(inout rect: CGRect, size: CGSize) {
     rect.size += size
 }
+/// Returns a rect by subtracting a size from the size.
 public func -(rect: CGRect, size: CGSize) -> CGRect {
     return CGRect(origin: rect.origin, size: rect.size - size)
 }
+/// Modifies the width and height values by subtracting a size.
 public func -=(inout rect: CGRect, size: CGSize) {
     rect.size -= size
 }
 
+/// Returns a point by applying a transform.
 public func *(point: CGPoint, transform: CGAffineTransform) -> CGPoint {
     return CGPointApplyAffineTransform(point, transform)
 }
+/// Modifies all values by applying a transform.
 public func *=(inout point: CGPoint, transform: CGAffineTransform) {
     point = CGPointApplyAffineTransform(point, transform)
 }
+/// Returns a size by applying a transform.
 public func *(size: CGSize, transform: CGAffineTransform) -> CGSize {
     return CGSizeApplyAffineTransform(size, transform)
 }
+/// Modifies all values by applying a transform.
 public func *=(inout size: CGSize, transform: CGAffineTransform) {
     size = CGSizeApplyAffineTransform(size, transform)
 }
+/// Returns a rect by applying a transform.
 public func *(rect: CGRect, transform: CGAffineTransform) -> CGRect {
     return CGRectApplyAffineTransform(rect, transform)
 }
+/// Modifies all values by applying a transform.
 public func *=(inout rect: CGRect, transform: CGAffineTransform) {
     rect = CGRectApplyAffineTransform(rect, transform)
 }
 
+/// Returns a transform by concatenating two transforms.
 public func *(t1: CGAffineTransform, t2: CGAffineTransform) -> CGAffineTransform {
     return CGAffineTransformConcat(t1, t2)
 }
+/// Modifies all values by concatenating another transform.
 public func *=(inout t1: CGAffineTransform, t2: CGAffineTransform) {
     t1 = CGAffineTransformConcat(t1, t2)
 }


    // MARK: with

    public func with(# origin: CGPoint) -> CGRect {
        return CGRect(origin: origin, size: size)
    }
    public func with(# x: CGFloat, y: CGFloat) -> CGRect {
        return with(origin: CGPoint(x: x, y: y))
    }
    public func with(# x: CGFloat) -> CGRect {
        return with(x: x, y: y)
    }
    public func with(# y: CGFloat) -> CGRect {
        return with(x: x, y: y)
    }

    public func with(# size: CGSize) -> CGRect {
        return CGRect(origin: origin, size: size)
    }
    public func with(# width: CGFloat, height: CGFloat) -> CGRect {
        return with(size: CGSize(width: width, height: height))
    }
    public func with(# width: CGFloat) -> CGRect {
        return with(width: width, height: height)
    }
    public func with(# height: CGFloat) -> CGRect {
        return with(width: width, height: height)
    }

    public func with(# x: CGFloat, width: CGFloat) -> CGRect {
        return CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: width, height: height))
    }
    public func with(# y: CGFloat, height: CGFloat) -> CGRect {
        return CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: width, height: height))
    }

    // MARK: offset

    public func rectByOffsetting(dx: CGFloat, _ dy: CGFloat) -> CGRect {
        return with(x: x + dx, y: y + dy)
    }
    public func rectByOffsetting(# dx: CGFloat) -> CGRect {
        return with(x: x + dx)
    }
    public func rectByOffsetting(# dy: CGFloat) -> CGRect {
        return with(y: y + dy)
    }
    public func rectByOffsetting(by: CGSize) -> CGRect {
        return with(x: x + by.width, y: y + by.height)
    }

    public mutating func offset(dx: CGFloat, _ dy: CGFloat) {
        offset(dx: dx, dy: dy)
    }
    public mutating func offset(dx: CGFloat = 0) {
        x += dx
    }
    public mutating func offset(dy: CGFloat = 0) {
        y += dy
    }
    public mutating func offset(by: CGSize) {
        offset(dx: by.width, dy: by.height)
    }

    // MARK: inset

    public func rectByInsetting(by: CGFloat) -> CGRect {
        return rectByInsetting(dx: by, dy: by)
    }

    public func rectByInsetting(# dx: CGFloat) -> CGRect {
        return with(x: x + dx, width: width - dx * 2)
    }
    public func rectByInsetting(# dy: CGFloat) -> CGRect {
        return with(y: y + dy, height: height - dy * 2)
    }

    public func rectByInsetting(minX: CGFloat = 0, minY: CGFloat = 0, maxX: CGFloat = 0, maxY: CGFloat = 0) -> CGRect {
        return CGRect(x: x + minX, y: y + minY, width: width - minX - maxX, height: height - minY - maxY)
    }

    public func rectByInsetting(top: CGFloat = 0, left: CGFloat = 0, bottom: CGFloat = 0, right: CGFloat = 0) -> CGRect {
        #if os(iOS)
            return CGRect(x: x + left, y: y + top, width: width - right - left, height: height - top - bottom)

        }
    }

    /// Modifies all values by setting the size while centering the rect.
    public mutating func setSizeCentered(size: CGSize) {
        self = rectByCentering(size)
    }

    /// Modifies all values by setting the size while centering the rect touching the specified edge.
    public mutating func setSizeCentered(size: CGSize, alignTo edge: CGRectEdge) {
        self = rectByCentering(size, alignTo: edge)
    }

    /// Modifies all values by setting the size while centering the rect touching the specified corner.
    public mutating func setSizeAligned(size: CGSize, corner e1: CGRectEdge, _ e2: CGRectEdge) {
        self = rectByAligning(size, corner: e1, e2)
    }
