Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unsafe pointer access to MatrixType #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/SGLMath/Complex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ extension Float {
public struct Complex<T: FloatingPointArithmeticType>: MatrixType, ExpressibleByFloatLiteral, ExpressibleByIntegerLiteral, ExpressibleByArrayLiteral {
public typealias Element = T

public static var elementCount: Int { 2 }

public var real: T
public var imag: T

Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix2x2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import simd
public struct Matrix2x2<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 2 * 2 }

private var x: Vector2<T>, y: Vector2<T>

public subscript(column: Int) -> Vector2<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix2x3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Matrix2x3<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 2 * 3 }

private var x: Vector3<T>, y: Vector3<T>

public subscript(column: Int) -> Vector3<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix2x4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import simd
public struct Matrix2x4<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 2 * 4 }

private var x: Vector4<T>, y: Vector4<T>

public subscript(column: Int) -> Vector4<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix3x2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Matrix3x2<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 3 * 2 }

private var x: Vector2<T>, y: Vector2<T>, z: Vector2<T>

public subscript(column: Int) -> Vector2<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix3x3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Matrix3x3<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 3 * 3 }

private var x: Vector3<T>, y: Vector3<T>, z: Vector3<T>

public subscript(column: Int) -> Vector3<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix3x4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Matrix3x4<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 3 * 4 }

private var x: Vector4<T>, y: Vector4<T>, z: Vector4<T>

public subscript(column: Int) -> Vector4<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix4x2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import simd
public struct Matrix4x2<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 4 * 2 }

private var x: Vector2<T>, y: Vector2<T>, z: Vector2<T>, w: Vector2<T>

public subscript(column: Int) -> Vector2<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix4x3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Matrix4x3<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 4 * 3 }

private var x: Vector3<T>, y: Vector3<T>, z: Vector3<T>, w: Vector3<T>

public subscript(column: Int) -> Vector3<T> {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Matrix4x4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import simd
public struct Matrix4x4<T: ArithmeticType>: MatrixType {
public typealias Element = T

public static var elementCount: Int { 4 * 4 }

private var x: Vector4<T>, y: Vector4<T>, z: Vector4<T>, w: Vector4<T>

public subscript(column: Int) -> Vector4<T> {
Expand Down
35 changes: 35 additions & 0 deletions Sources/SGLMath/Protocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,41 @@ public protocol MatrixType: Hashable, CustomDebugStringConvertible, Sequence whe
static func %(_: Self, _: Element) -> Self
static func %=(_: inout Self, _: Element)
var elements: [Element] { get }

static var elementCount: Int { get }
}

// Unsafe pointer access
public extension MatrixType {
func withUnsafePointer<R>(_ body: (UnsafePointer<Element>) throws -> R) rethrows -> R {
try Swift.withUnsafePointer(to: self) { pointer in
try pointer.withMemoryRebound(to: Element.self, capacity: Self.elementCount) {
try body($0)
}
}
}

mutating func withUnsafeMutablePointer<R>(_ body: (UnsafeMutablePointer<Element>) throws -> R) rethrows -> R {
try Swift.withUnsafeMutablePointer(to: &self) { pointer in
try pointer.withMemoryRebound(to: Element.self, capacity: Self.elementCount) {
try body($0)
}
}
}

func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Element>) throws -> R) rethrows -> R {
try withUnsafeBytes(of: self) { rawBuffer in
let buffer = UnsafeBufferPointer(start: rawBuffer.baseAddress!.assumingMemoryBound(to: Element.self), count: Self.elementCount)
return try body(buffer)
}
}

mutating func withUnsafeMutableBufferPointer<R>(_ body: (UnsafeMutableBufferPointer<Element>) throws -> R) rethrows -> R {
try withUnsafeMutableBytes(of: &self) { rawBuffer in
let buffer = UnsafeMutableBufferPointer(start: rawBuffer.baseAddress!.assumingMemoryBound(to: Element.self), count: Self.elementCount)
return try body(buffer)
}
}
}

// This protocol is only Vector2, Vector3, and Vector4
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Quaternion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Quaternion<T: FloatingPointArithmeticType>: MatrixType, ExpressibleByArrayLiteral {
public typealias Element = T

public static var elementCount: Int { 4 }

public var x: T, y: T, z: T, w: T

public var elements: [Element] {
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public struct Vector2<T: ArithmeticType>: VectorType {
public typealias UInt32Vector = Vector2<UInt32>
public typealias BooleanVector = Vector2b

public static var elementCount: Int { 2 }

public var x: T, y: T

public var r: T { get { return x } set { x = newValue } }
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector2b.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Vector2b: BooleanVectorType {
public typealias BooleanVector = Vector2b

public static var elementCount: Int { 2 }

public var x: Bool, y: Bool

public var r: Bool { get { return x } set { x = newValue } }
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public struct Vector3<T: ArithmeticType>: VectorType {
public typealias UInt32Vector = Vector3<UInt32>
public typealias BooleanVector = Vector3b

public static var elementCount: Int { 3 }

public var x: T, y: T, z: T

public var r: T { get { return x } set { x = newValue } }
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector3b.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Vector3b: BooleanVectorType {
public typealias BooleanVector = Vector3b

public static var elementCount: Int { 3 }

public var x: Bool, y: Bool, z: Bool

public var r: Bool { get { return x } set { x = newValue } }
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public struct Vector4<T: ArithmeticType>: VectorType {
public typealias UInt32Vector = Vector4<UInt32>
public typealias BooleanVector = Vector4b

public static var elementCount: Int { 4 }

public var x: T, y: T, z: T, w: T

public var r: T { get { return x } set { x = newValue } }
Expand Down
2 changes: 2 additions & 0 deletions Sources/SGLMath/Vector4b.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public struct Vector4b: BooleanVectorType {
public typealias BooleanVector = Vector4b

public static var elementCount: Int { 4 }

public var x: Bool, y: Bool, z: Bool, w: Bool

public var r: Bool { get { return x } set { x = newValue } }
Expand Down
39 changes: 38 additions & 1 deletion Tests/SGLMathTests/Matrix4x4Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,49 @@ class Matrix4x4Tests: XCTestCase {
XCTAssertEqual(m0, m1)
}

func testPointers() {
var m0 = mat4(
vec4(0, 1, 2, 3),
vec4(4, 5, 6, 7),
vec4(8, 9, 10, 11),
vec4(12, 13, 14, 15)
)

let m1 = mat4(
vec4(20, 21, 22, 23),
vec4(24, 25, 26, 27),
vec4(28, 29, 30, 31),
vec4(32, 33, 34, 35)
)

m0.withUnsafePointer { pointer in
for i in 0..<16 {
XCTAssertEqual(pointer[i], Float(i))
}
}

m0.withUnsafeMutablePointer { pointer in
for i in 0..<16 {
pointer[i] += 20
}
}

m0.withUnsafeBufferPointer { buffer in
for (i, element) in buffer.enumerated() {
XCTAssertEqual(element, Float(i + 20))
}
}

XCTAssertEqual(m0, m1)
}

static var allTests = [
("testIdentityInits", testIdentityInits),
("testCommmonInits", testCommmonInits),
("testDivide", testDivide),
("testMultiplyWith2x4", testMultiplyWith2x4),
("testMultiplyVector", testMultiplyVector),
("testMultiArray", testMultiArray)
("testMultiArray", testMultiArray),
("testPointers", testPointers)
]
}
28 changes: 27 additions & 1 deletion Tests/SGLMathTests/Vector4Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,31 @@ class Vector4Tests: XCTestCase {
XCTAssertEqual(v1/v2, v3)
}

func testPointers() {
var v0 = vec4(0, 1, 2, 3)
let v1 = vec4(20, 21, 22, 23)

v0.withUnsafePointer { pointer in
for i in 0..<4 {
XCTAssertEqual(pointer[i], Float(i))
}
}

v0.withUnsafeMutablePointer { pointer in
for i in 0..<4 {
pointer[i] += 20
}
}

v0.withUnsafeBufferPointer { buffer in
for (i, element) in buffer.enumerated() {
XCTAssertEqual(element, Float(i + 20))
}
}

XCTAssertEqual(v0, v1)
}

static var allTests = [
("testInit", testInit),
("testAddFloat", testAddFloat),
Expand All @@ -120,6 +145,7 @@ class Vector4Tests: XCTestCase {
("testMulInt", testMulInt),
("testMulUInt", testMulUInt),
("testDivFloat", testDivFloat),
("testDivInt", testDivInt)
("testDivInt", testDivInt),
("testPointers", testPointers)
]
}