|
1 | 1 | //
|
2 | 2 | // PointerOffsetTests.swift
|
3 |
| -// |
4 |
| -// |
5 |
| -// |
| 3 | +// OpenGraphCompatibilityTests |
6 | 4 |
|
| 5 | +import RealModule |
7 | 6 | import Testing
|
8 | 7 |
|
9 | 8 | struct PointerOffsetTests {
|
10 | 9 | @Test
|
11 |
| - func basicInit() { |
12 |
| - #expect(PointerOffset<Any, Any>(byteOffset: 8).byteOffset == 8) |
| 10 | + func plainInitAndProperty() { |
| 11 | + typealias Base = Tuple<Int, Int> |
| 12 | + var offset = PointerOffset<Base, Int>(byteOffset: 8) |
| 13 | + #expect(offset.byteOffset == 8) |
| 14 | + offset.byteOffset = 0 |
| 15 | + #expect(offset.byteOffset == 0) |
| 16 | + } |
| 17 | + |
| 18 | + @Test |
| 19 | + func emptyInit() { |
| 20 | + #expect(PointerOffset<Void, Void>().byteOffset == 0) |
13 | 21 | #expect(PointerOffset<Int, Int>().byteOffset == 0)
|
14 |
| - let invalidPointer = PointerOffset<Tuple<Int, Int>, Int>.invalidScenePointer() |
15 |
| - #expect(MemoryLayout<Tuple<Int, Int>>.stride == 16) |
16 |
| - #expect(invalidPointer == UnsafeMutablePointer(bitPattern: MemoryLayout<Tuple<Int, Int>>.stride)) |
| 22 | + #expect(PointerOffset<Any, Any>().byteOffset == 0) |
17 | 23 | }
|
18 |
| - |
| 24 | + |
19 | 25 | @Test
|
20 | 26 | func plusOperator() {
|
21 |
| - let offset1 = PointerOffset<Tuple<Int, Tuple<Int, Int>>, Tuple<Int, Int>>(byteOffset: 8) |
22 |
| - let offset2 = PointerOffset<Tuple<Int, Int>, Int>(byteOffset: 8) |
| 27 | + typealias Base = Tuple<Int, Int> |
| 28 | + typealias Base2 = Tuple<Int, Base> |
| 29 | + let offset1 = PointerOffset<Base2, Base>(byteOffset: 8) |
| 30 | + let offset2 = PointerOffset<Base, Int>(byteOffset: 8) |
23 | 31 | let result = offset1 + offset2
|
24 | 32 | #expect(result.byteOffset == 16)
|
| 33 | + #expect(type(of: result) == PointerOffset<Base2, Int>.self) |
25 | 34 | }
|
26 |
| - |
27 |
| - @Test(.disabled("TODO: Add appropriate PointerOffset.of and PointerOffset.offset test case")) |
28 |
| - func ofAndOffset() { |
29 |
| - var tuple = Tuple(first: 1, second: 2) |
30 |
| - _ = PointerOffset<Tuple<Int, Int>, Int>.of(&tuple.second) |
| 35 | + |
| 36 | + @Test |
| 37 | + func invalidScenePointer() { |
| 38 | + typealias Base = Tuple<Int, Int> |
| 39 | + let invalidPointer = PointerOffset<Base, Int>.invalidScenePointer() |
| 40 | + let stride = MemoryLayout<Base>.stride |
| 41 | + #expect(stride == 16) |
| 42 | + #expect(invalidPointer == UnsafeMutablePointer(bitPattern: stride)) |
31 | 43 | }
|
32 |
| - |
| 44 | + |
33 | 45 | @Test
|
34 |
| - func unsafePointer() { |
35 |
| - let tuple = Tuple(first: 1, second: 2.0) |
36 |
| - withUnsafePointer(to: tuple) { pointer in |
37 |
| - let first = pointer[offset: PointerOffset<Tuple<Int, Double>, Int>(byteOffset: 0)] |
38 |
| - #expect(first == 1) |
39 |
| - let second = pointer[offset: PointerOffset<Tuple<Int, Double>, Double>(byteOffset: 8)] |
40 |
| - #expect(second == 2.0) |
| 46 | + func ofAndOffset() { |
| 47 | + struct Empty { |
| 48 | + var value: Void |
41 | 49 | }
|
42 |
| - |
43 |
| - let triple = Triple(first: 0, second: 1, third: 2) |
44 |
| - withUnsafePointer(to: triple) { pointer in |
45 |
| - let first = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 0) |
46 |
| - #expect(first.pointee == 0) |
47 |
| - let second = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 8) |
48 |
| - #expect(second.pointee == 1) |
49 |
| - let third = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 16) |
50 |
| - #expect(third.pointee == 2) |
| 50 | + |
| 51 | + func helper<Base, Member>( |
| 52 | + expectedByteOffset: Int, |
| 53 | + _: Base.Type, |
| 54 | + _: Member.Type, |
| 55 | + _ body: (inout Base) -> PointerOffset<Base, Member> |
| 56 | + ) { |
| 57 | + let pointerOffsetType = PointerOffset<Base, Member>.self |
| 58 | + let offset = pointerOffsetType.offset { invalid in |
| 59 | + withUnsafeMutablePointer(to: &invalid) { pointer in |
| 60 | + #expect(pointer == PointerOffset<Base, Member>.invalidScenePointer()) |
| 61 | + } |
| 62 | + return body(&invalid) |
| 63 | + } |
| 64 | + #expect(offset.byteOffset == expectedByteOffset) |
| 65 | + } |
| 66 | + |
| 67 | + helper(expectedByteOffset: 0, Tuple<Int, Int>.self, Void.self) { _ in fatalError("Unreachable") } |
| 68 | + helper(expectedByteOffset: 0, Tuple<Int, Int>.self, Empty.self) { _ in fatalError("Unreachable") } |
| 69 | + |
| 70 | + typealias Base = Triple<Int, Int, Empty> |
| 71 | + helper(expectedByteOffset: 0, Base.self, Int.self) { invalid in |
| 72 | + .of(&invalid.first) |
| 73 | + } |
| 74 | + helper(expectedByteOffset: 8, Base.self, Int.self) { invalid in |
| 75 | + .of(&invalid.second) |
| 76 | + } |
| 77 | + helper(expectedByteOffset: 0, Base.self, Empty.self) { invalid in |
| 78 | + .of(&invalid.third) |
51 | 79 | }
|
52 | 80 | }
|
53 |
| - |
54 |
| - @Test |
55 |
| - func unsafeMutablePointer() { |
56 |
| - var tuple = Tuple(first: 1, second: 2.0) |
57 |
| - withUnsafeMutablePointer(to: &tuple) { pointer in |
58 |
| - let first = pointer[offset: PointerOffset<Tuple<Int, Double>, Int>(byteOffset: 0)] |
59 |
| - #expect(first == 1) |
60 |
| - let second = pointer[offset: PointerOffset<Tuple<Int, Double>, Double>(byteOffset: 8)] |
61 |
| - #expect(second == 2.0) |
62 |
| - |
63 |
| - pointer[offset: PointerOffset<Tuple<Int, Double>, Int>(byteOffset: 0)] = 3 |
64 |
| - let newFirst = pointer[offset: PointerOffset<Tuple<Int, Double>, Int>(byteOffset: 0)] |
65 |
| - #expect(newFirst == 3) |
| 81 | + |
| 82 | + @Test("Extension API between UnsafePointer/UnsafeMutablePointer and PointerOffset") |
| 83 | + func unsafePointerAndUnsafeMutablePointerExtension() { |
| 84 | + do { |
| 85 | + var tuple = Tuple(first: 1, second: 2.0) |
| 86 | + typealias Base = Tuple<Int, Double> |
| 87 | + let firstOffset = PointerOffset<Base, Int>(byteOffset: 0) |
| 88 | + let secondOffset = PointerOffset<Base, Double>(byteOffset: 8) |
| 89 | + withUnsafeMutablePointer(to: &tuple) { pointer in |
| 90 | + #expect(pointer[offset: firstOffset] == 1) |
| 91 | + #expect(pointer[offset: secondOffset] == 2.0) |
| 92 | + |
| 93 | + pointer[offset: firstOffset] = 3 |
| 94 | + pointer[offset: secondOffset] = 4.0 |
| 95 | + } |
| 96 | + withUnsafePointer(to: tuple) { pointer in |
| 97 | + #expect(pointer[offset: firstOffset] == 3) |
| 98 | + #expect(pointer[offset: secondOffset].isApproximatelyEqual(to: 4.0)) |
| 99 | + } |
66 | 100 | }
|
67 |
| - |
68 |
| - var triple = Triple(first: 0, second: 1, third: 2) |
69 |
| - withUnsafeMutablePointer(to: &triple) { pointer in |
70 |
| - let first = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 0) |
71 |
| - #expect(first.pointee == 0) |
72 |
| - let second = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 8) |
73 |
| - #expect(second.pointee == 1) |
74 |
| - let third = pointer + PointerOffset<Triple<Int, Int, Int>, Int>(byteOffset: 16) |
75 |
| - #expect(third.pointee == 2) |
| 101 | + |
| 102 | + do { |
| 103 | + var triple = Triple(first: 0, second: 1, third: 2) |
| 104 | + typealias Base = Triple<Int, Int, Int> |
| 105 | + |
| 106 | + let firstOffset = PointerOffset<Base, Int>.offset { .of(&$0.first) } |
| 107 | + let secondOffset = PointerOffset<Base, Int>.offset { .of(&$0.second) } |
| 108 | + let thirdOffset = PointerOffset<Base, Int>.offset { .of(&$0.third) } |
| 109 | + withUnsafeMutablePointer(to: &triple) { pointer in |
| 110 | + #expect((pointer + firstOffset).pointee == 0) |
| 111 | + #expect((pointer + secondOffset).pointee == 1) |
| 112 | + #expect((pointer + thirdOffset).pointee == 2) |
| 113 | + |
| 114 | + (pointer + firstOffset).pointee = 3 |
| 115 | + (pointer + secondOffset).pointee = 4 |
| 116 | + (pointer + thirdOffset).pointee = 5 |
| 117 | + } |
| 118 | + withUnsafePointer(to: triple) { pointer in |
| 119 | + #expect((pointer + firstOffset).pointee == 3) |
| 120 | + #expect((pointer + secondOffset).pointee == 4) |
| 121 | + #expect((pointer + thirdOffset).pointee == 5) |
| 122 | + } |
76 | 123 | }
|
77 | 124 | }
|
78 | 125 | }
|
0 commit comments