📐 Generic Geometry
Did you ever need to make a CGSize that didn't contain CGFloats? What about a Point of enum values? Edges where some values are optional?
All this, and more, is possible with Generic Geometry.
Includes the following types:
Point<Value>Size<Value>Rect<Value>Edges<Value>Corners<Value>
This allows you to do things like:
let maybeSize: Size<Int?> = Size(width: nil, height: 15)
// w: nil, h: Optional(15)
let concreteSize: Size<Int> = maybeSize.unwrapped(or: Size(999))
// w: 999, h: 15
let stringSize: Size<String> = concreteSize.map(String.init)
// w: "999", h: "15"
let scaledSize = concreteSize.multipling(by: Size<Int>(width: 10, height: 100))
// w: 9990, h: 1500
let boolPoint: Point<Bool> = Point(x: true, y: false)
// x: true, y: false
let tuplePoint: Point<(Bool, Int)> = boolPoint.zip(Point<Int>(5))
// x:(true, 5), y:(false, 5)
let mappedPoint: Point<Double> = tuplePoint.map { $0 ? Double($1) * 2 : Double($1) / 2 }
// x:10.0, y:2.5Types
Point<Value>
An x/y point in a 2d coordinate system.
init(x: Value, y: Value)/init(Value)zeromap/zip/zipWith==(whenValue: Equatable)init(cgPoint: CGPoint)/cgPoint/withCGFloats
Size<Value>
A width and height pair, representing a size in a 2d coordinate system.
init(width: Value, height: Value)/init(Value)zeromap/zip/zipWith==(whenValue: Equatable)multipling(by: Value)/multipling(by: Size<Value>)adding(Value)/adding(Size<Value>)dividing(by: Value)/dividing(by: Size<Value>)inset(Edges<Value>)/outset(Edges<Value>)clamped(min: Size<Value>, max: Size<Value>)unwrapped(or: Size<A>)(whenValue == Optional<A>)init(cgSize: CGSize)/cgSize/withCGFloats
Rect<Value>
A combination of a Point and a Size, representing a rectangle in a 2d coordinate system. origin & size use the same underlying Value type.
init(origin: Point<Value>, size: Size<Value>)/init(x: Value, y: Value, width: Value, height: Value)zeromap/zip/zipWith==(whenValue: Equatable)cornerPoints: Corners<Point<Value>>inset(by: Edges<Value>)/inset(by: Value)outset(by: Edges<Value>)/outset(by: Value)init(cgRect: CGRect)/cgRect/withCGFloats
Edges<Value>
Contains values for the 4 edges of a rectange.
init(top: Value, left: Value, bottom: Value, right: Value)/init(Value)zeromap/zip/zipWith==/isUniform(whenValue: Equatable)negatedadding(Value)/adding(Edges)cgRectEdges: [CGRectEdge: Value]/value(forEdge: CGRectEdge)/withCGFloatsuiEdgeInsets
Corners<Value>
Contains values for the 4 corners of a rectange.
init(topLeft: Value, topRight: Value, bottomLeft: Value, bottomRight: Value)/init(Value)zeromap/zip/zipWith==/isUniform(whenValue: Equatable)withCGFloats