Skip to content

Commit 79ea752

Browse files
committed
Make Gen.unitVector available on non-Apple platforms
1 parent 695120f commit 79ea752

2 files changed

Lines changed: 33 additions & 22 deletions

File tree

Sources/PropertyBased/Gen+SIMD.swift

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
// Created by Lennard Sprong on 19/05/2025.
66
//
77

8+
#if canImport(simd)
9+
import simd
10+
#endif
11+
812
extension Generator {
913
/// Produces a generator that creates a pair of values.
1014
///
@@ -51,56 +55,55 @@ extension Generator where ResultValue: SIMDScalar & Sendable {
5155
}
5256
}
5357

54-
#if canImport(simd)
55-
import simd
56-
extension Gen where Value == simd_float2 {
58+
extension Gen<SIMD2<Float>> {
5759
/// A generator of vectors with length 1.
58-
public static var unitVector: Generator<simd_float2, Shrink.None<(Float, Float)>> {
60+
public static var unitVector: Generator<SIMD2<Float>, Shrink.None<(Float, Float)>> {
5961
let gen = Gen<Float>.float(in: 0...1)
6062
return gen.simd2.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
6163
}
6264
}
6365

64-
extension Gen where Value == simd_float3 {
66+
extension Gen<SIMD3<Float>> {
6567
/// A generator of vectors with length 1.
66-
public static var unitVector: Generator<simd_float3, Shrink.None<(Float, Float, Float)>> {
68+
public static var unitVector: Generator<SIMD3<Float>, Shrink.None<(Float, Float, Float)>> {
6769
let gen = Gen<Float>.float(in: 0...1)
6870
return gen.simd3.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
6971
}
7072
}
7173

72-
extension Gen where Value == simd_float4 {
74+
extension Gen<SIMD4<Float>> {
7375
/// A generator of vectors with length 1.
74-
public static var unitVector: Generator<simd_float4, Shrink.None<(Float, Float, Float, Float)>> {
76+
public static var unitVector: Generator<SIMD4<Float>, Shrink.None<(Float, Float, Float, Float)>> {
7577
let gen = Gen<Float>.float(in: 0...1)
7678
return gen.simd4.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
7779
}
7880
}
7981

80-
extension Gen where Value == simd_double2 {
82+
extension Gen<SIMD2<Double>> {
8183
/// A generator of vectors with length 1.
82-
public static var unitVector: Generator<simd_double2, Shrink.None<(Double, Double)>> {
84+
public static var unitVector: Generator<SIMD2<Double>, Shrink.None<(Double, Double)>> {
8385
let gen = Gen<Double>.double(in: 0...1)
8486
return gen.simd2.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
8587
}
8688
}
8789

88-
extension Gen where Value == simd_double3 {
90+
extension Gen<SIMD3<Double>> {
8991
/// A generator of vectors with length 1.
90-
public static var unitVector: Generator<simd_double3, Shrink.None<(Double, Double, Double)>> {
92+
public static var unitVector: Generator<SIMD3<Double>, Shrink.None<(Double, Double, Double)>> {
9193
let gen = Gen<Double>.double(in: 0...1)
9294
return gen.simd3.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
9395
}
9496
}
9597

96-
extension Gen where Value == simd_double4 {
98+
extension Gen<SIMD4<Double>> {
9799
/// A generator of vectors with length 1.
98-
public static var unitVector: Generator<simd_double4, Shrink.None<(Double, Double, Double, Double)>> {
100+
public static var unitVector: Generator<SIMD4<Double>, Shrink.None<(Double, Double, Double, Double)>> {
99101
let gen = Gen<Double>.double(in: 0...1)
100102
return gen.simd4.map { normalize($0) }.filter { $0.x.isFinite }.withoutShrink()
101103
}
102104
}
103105

106+
#if canImport(simd)
104107
extension Gen where Value == simd_quatf {
105108
/// A generator of rotation quaternions with length 1 and a random angle.
106109
public static var simd_quatf: Generator<simd_quatf, Shrink.Tuple<(Float, (Float, Float, Float))>> {
@@ -118,4 +121,11 @@ extension Gen where Value == simd_quatd {
118121
return zip(angle, vector).map { t in simd.simd_quatd(angle: t.0, axis: t.1) }
119122
}
120123
}
124+
#else
125+
func length<F: FloatingPoint, T: SIMD<F>>(_ item: T) -> F {
126+
(item * item).sum().squareRoot()
127+
}
128+
func normalize<F: FloatingPoint, T: SIMD<F>>(_ item: T) -> T {
129+
return item / length(item)
130+
}
121131
#endif

Tests/PropertyBasedTests/GenTests+SIMD.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
// Created by Lennard Sprong on 21/05/2025.
66
//
77

8-
import PropertyBased
98
import Testing
109

10+
@testable import PropertyBased
11+
1112
#if canImport(simd)
1213
import simd
1314
#endif
@@ -46,38 +47,38 @@ import simd
4647
}
4748
}
4849

49-
#if canImport(simd)
5050
@Test func testUnitVectorFloat2() async {
51-
await propertyCheck(input: Gen<simd_float2>.unitVector) { vec in
51+
await propertyCheck(input: Gen<SIMD2<Float>>.unitVector) { vec in
5252
#expect(abs(length(vec) - 1) < 0.0001)
5353
}
5454
}
5555
@Test func testUnitVectorFloat3() async {
56-
await propertyCheck(input: Gen<simd_float3>.unitVector) { vec in
56+
await propertyCheck(input: Gen<SIMD3<Float>>.unitVector) { vec in
5757
#expect(abs(length(vec) - 1) < 0.0001)
5858
}
5959
}
6060
@Test func testUnitVectorFloat4() async {
61-
await propertyCheck(input: Gen<simd_float4>.unitVector) { vec in
61+
await propertyCheck(input: Gen<SIMD4<Float>>.unitVector) { vec in
6262
#expect(abs(length(vec) - 1) < 0.0001)
6363
}
6464
}
6565
@Test func testUnitVectorDouble2() async {
66-
await propertyCheck(input: Gen<simd_double2>.unitVector) { vec in
66+
await propertyCheck(input: Gen<SIMD2<Double>>.unitVector) { vec in
6767
#expect(abs(length(vec) - 1) < 0.0001)
6868
}
6969
}
7070
@Test func testUnitVectorDouble3() async {
71-
await propertyCheck(input: Gen<simd_double3>.unitVector) { vec in
71+
await propertyCheck(input: Gen<SIMD3<Double>>.unitVector) { vec in
7272
#expect(abs(length(vec) - 1) < 0.0001)
7373
}
7474
}
7575
@Test func testUnitVectorDouble4() async {
76-
await propertyCheck(input: Gen<simd_double4>.unitVector) { vec in
76+
await propertyCheck(input: Gen<SIMD4<Double>>.unitVector) { vec in
7777
#expect(abs(length(vec) - 1) < 0.0001)
7878
}
7979
}
8080

81+
#if canImport(simd)
8182
@Test func testQuatF() async {
8283
await propertyCheck(input: Gen.simd_quatf) { quat in
8384
#expect(abs(quat.length - 1) < 0.0001)

0 commit comments

Comments
 (0)