|
| 1 | +// RUN: %target-run-simple-swift |
| 2 | +// REQUIRES: executable_test |
| 3 | +// REQUIRES: objc_interop |
| 4 | + |
| 5 | +import Foundation |
| 6 | +import StdlibUnittest |
| 7 | + |
| 8 | +let SIMDCodableTests = TestSuite("SIMDCodable") |
| 9 | + |
| 10 | +// Round an integer to the closest representable JS integer value |
| 11 | +func jsInteger<T>(_ value: T) -> T |
| 12 | +where T : SIMD, T.Scalar : FixedWidthInteger { |
| 13 | + // Attempt to round-trip though Double; if that fails it's because the |
| 14 | + // rounded value is too large to fit in T, so use the largest value that |
| 15 | + // does fit instead. |
| 16 | + let upperBound = T.Scalar(Double(T.Scalar.max).nextDown) |
| 17 | + var result = T() |
| 18 | + for i in result.indices { |
| 19 | + result[i] = T.Scalar(exactly: Double(value[i])) ?? upperBound |
| 20 | + } |
| 21 | + return result |
| 22 | +} |
| 23 | + |
| 24 | +func testRoundTrip<T>(_ for: T.Type) |
| 25 | +where T : SIMD, T.Scalar : FixedWidthInteger { |
| 26 | + let input = jsInteger(T.random(in: T.Scalar.min ... T.Scalar.max)) |
| 27 | + let encoder = JSONEncoder() |
| 28 | + let decoder = JSONDecoder() |
| 29 | + do { |
| 30 | + let data = try encoder.encode(input) |
| 31 | + let output = try decoder.decode(T.self, from: data) |
| 32 | + expectEqual(input, output) |
| 33 | + } |
| 34 | + catch { |
| 35 | + expectUnreachableCatch(error) |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +func testRoundTrip<T>(_ for: T.Type) |
| 40 | +where T : SIMD, T.Scalar : BinaryFloatingPoint, |
| 41 | + T.Scalar.RawSignificand : FixedWidthInteger { |
| 42 | + let input = T.random(in: -16 ..< 16) |
| 43 | + let encoder = JSONEncoder() |
| 44 | + let decoder = JSONDecoder() |
| 45 | + do { |
| 46 | + let data = try encoder.encode(input) |
| 47 | + let output = try decoder.decode(T.self, from: data) |
| 48 | + expectEqual(input, output) |
| 49 | + } |
| 50 | + catch { |
| 51 | + expectUnreachableCatch(error) |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +// Very basic round-trip test. We can be much more sophisticated in the future, |
| 56 | +// but we want to at least exercise the API. Also need to add some negative |
| 57 | +// tests for the error paths, and test a more substantial set of types. |
| 58 | +SIMDCodableTests.test("roundTrip") { |
| 59 | + testRoundTrip(SIMD2<Int8>.self) |
| 60 | + testRoundTrip(SIMD3<Int8>.self) |
| 61 | + testRoundTrip(SIMD4<Int8>.self) |
| 62 | + testRoundTrip(SIMD2<UInt8>.self) |
| 63 | + testRoundTrip(SIMD3<UInt8>.self) |
| 64 | + testRoundTrip(SIMD4<UInt8>.self) |
| 65 | + testRoundTrip(SIMD2<Int32>.self) |
| 66 | + testRoundTrip(SIMD3<Int32>.self) |
| 67 | + testRoundTrip(SIMD4<Int32>.self) |
| 68 | + testRoundTrip(SIMD2<UInt32>.self) |
| 69 | + testRoundTrip(SIMD3<UInt32>.self) |
| 70 | + testRoundTrip(SIMD4<UInt32>.self) |
| 71 | + testRoundTrip(SIMD2<Int>.self) |
| 72 | + testRoundTrip(SIMD3<Int>.self) |
| 73 | + testRoundTrip(SIMD4<Int>.self) |
| 74 | + testRoundTrip(SIMD2<UInt>.self) |
| 75 | + testRoundTrip(SIMD3<UInt>.self) |
| 76 | + testRoundTrip(SIMD4<UInt>.self) |
| 77 | +/* Apparently these fail to round trip not only for i386 but also on older |
| 78 | + macOS versions, so we'll disable them entirely for now. |
| 79 | +#if !arch(i386) |
| 80 | + // https://bugs.swift.org/browse/SR-9759 |
| 81 | + testRoundTrip(SIMD2<Float>.self) |
| 82 | + testRoundTrip(SIMD3<Float>.self) |
| 83 | + testRoundTrip(SIMD4<Float>.self) |
| 84 | + testRoundTrip(SIMD2<Double>.self) |
| 85 | + testRoundTrip(SIMD3<Double>.self) |
| 86 | + testRoundTrip(SIMD4<Double>.self) |
| 87 | +#endif |
| 88 | + */ |
| 89 | +} |
| 90 | + |
| 91 | +runAllTests() |
0 commit comments