Skip to content

Commit 0982e5a

Browse files
committed
Fix PointerOffset.offset implementation
1 parent 47a81fd commit 0982e5a

File tree

2 files changed

+103
-56
lines changed

2 files changed

+103
-56
lines changed

Sources/OpenGraph/Attribute/Attribute/PointerOffset.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extension PointerOffset {
2626
}
2727

2828
public static func of(_ member: inout Member) -> PointerOffset {
29-
withUnsafePointer(to: member) { memberPointer in
29+
withUnsafePointer(to: &member) { memberPointer in
3030
let offset = UnsafeRawPointer(memberPointer) - UnsafeRawPointer(invalidScenePointer())
3131
return PointerOffset(byteOffset: offset)
3232
}
Lines changed: 102 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,125 @@
11
//
22
// PointerOffsetTests.swift
3-
//
4-
//
5-
//
3+
// OpenGraphCompatibilityTests
64

5+
import RealModule
76
import Testing
87

98
struct PointerOffsetTests {
109
@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)
1321
#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)
1723
}
18-
24+
1925
@Test
2026
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)
2331
let result = offset1 + offset2
2432
#expect(result.byteOffset == 16)
33+
#expect(type(of: result) == PointerOffset<Base2, Int>.self)
2534
}
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))
3143
}
32-
44+
3345
@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
4149
}
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)
5179
}
5280
}
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+
}
66100
}
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+
}
76123
}
77124
}
78125
}

0 commit comments

Comments
 (0)