From 0982e5ac2be3565e9dcf9253a9d6d6883c15434f Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 5 May 2024 15:46:13 +0800 Subject: [PATCH] Fix PointerOffset.offset implementation --- .../Attribute/Attribute/PointerOffset.swift | 2 +- .../Attribute/PointerOffsetTests.swift | 157 ++++++++++++------ 2 files changed, 103 insertions(+), 56 deletions(-) diff --git a/Sources/OpenGraph/Attribute/Attribute/PointerOffset.swift b/Sources/OpenGraph/Attribute/Attribute/PointerOffset.swift index df0348e..07f90c5 100644 --- a/Sources/OpenGraph/Attribute/Attribute/PointerOffset.swift +++ b/Sources/OpenGraph/Attribute/Attribute/PointerOffset.swift @@ -26,7 +26,7 @@ extension PointerOffset { } public static func of(_ member: inout Member) -> PointerOffset { - withUnsafePointer(to: member) { memberPointer in + withUnsafePointer(to: &member) { memberPointer in let offset = UnsafeRawPointer(memberPointer) - UnsafeRawPointer(invalidScenePointer()) return PointerOffset(byteOffset: offset) } diff --git a/Tests/OpenGraphCompatibilityTests/Attribute/Attribute/PointerOffsetTests.swift b/Tests/OpenGraphCompatibilityTests/Attribute/Attribute/PointerOffsetTests.swift index 9cc36e1..1180224 100644 --- a/Tests/OpenGraphCompatibilityTests/Attribute/Attribute/PointerOffsetTests.swift +++ b/Tests/OpenGraphCompatibilityTests/Attribute/Attribute/PointerOffsetTests.swift @@ -1,78 +1,125 @@ // // PointerOffsetTests.swift -// -// -// +// OpenGraphCompatibilityTests +import RealModule import Testing struct PointerOffsetTests { @Test - func basicInit() { - #expect(PointerOffset(byteOffset: 8).byteOffset == 8) + func plainInitAndProperty() { + typealias Base = Tuple + var offset = PointerOffset(byteOffset: 8) + #expect(offset.byteOffset == 8) + offset.byteOffset = 0 + #expect(offset.byteOffset == 0) + } + + @Test + func emptyInit() { + #expect(PointerOffset().byteOffset == 0) #expect(PointerOffset().byteOffset == 0) - let invalidPointer = PointerOffset, Int>.invalidScenePointer() - #expect(MemoryLayout>.stride == 16) - #expect(invalidPointer == UnsafeMutablePointer(bitPattern: MemoryLayout>.stride)) + #expect(PointerOffset().byteOffset == 0) } - + @Test func plusOperator() { - let offset1 = PointerOffset>, Tuple>(byteOffset: 8) - let offset2 = PointerOffset, Int>(byteOffset: 8) + typealias Base = Tuple + typealias Base2 = Tuple + let offset1 = PointerOffset(byteOffset: 8) + let offset2 = PointerOffset(byteOffset: 8) let result = offset1 + offset2 #expect(result.byteOffset == 16) + #expect(type(of: result) == PointerOffset.self) } - - @Test(.disabled("TODO: Add appropriate PointerOffset.of and PointerOffset.offset test case")) - func ofAndOffset() { - var tuple = Tuple(first: 1, second: 2) - _ = PointerOffset, Int>.of(&tuple.second) + + @Test + func invalidScenePointer() { + typealias Base = Tuple + let invalidPointer = PointerOffset.invalidScenePointer() + let stride = MemoryLayout.stride + #expect(stride == 16) + #expect(invalidPointer == UnsafeMutablePointer(bitPattern: stride)) } - + @Test - func unsafePointer() { - let tuple = Tuple(first: 1, second: 2.0) - withUnsafePointer(to: tuple) { pointer in - let first = pointer[offset: PointerOffset, Int>(byteOffset: 0)] - #expect(first == 1) - let second = pointer[offset: PointerOffset, Double>(byteOffset: 8)] - #expect(second == 2.0) + func ofAndOffset() { + struct Empty { + var value: Void } - - let triple = Triple(first: 0, second: 1, third: 2) - withUnsafePointer(to: triple) { pointer in - let first = pointer + PointerOffset, Int>(byteOffset: 0) - #expect(first.pointee == 0) - let second = pointer + PointerOffset, Int>(byteOffset: 8) - #expect(second.pointee == 1) - let third = pointer + PointerOffset, Int>(byteOffset: 16) - #expect(third.pointee == 2) + + func helper( + expectedByteOffset: Int, + _: Base.Type, + _: Member.Type, + _ body: (inout Base) -> PointerOffset + ) { + let pointerOffsetType = PointerOffset.self + let offset = pointerOffsetType.offset { invalid in + withUnsafeMutablePointer(to: &invalid) { pointer in + #expect(pointer == PointerOffset.invalidScenePointer()) + } + return body(&invalid) + } + #expect(offset.byteOffset == expectedByteOffset) + } + + helper(expectedByteOffset: 0, Tuple.self, Void.self) { _ in fatalError("Unreachable") } + helper(expectedByteOffset: 0, Tuple.self, Empty.self) { _ in fatalError("Unreachable") } + + typealias Base = Triple + helper(expectedByteOffset: 0, Base.self, Int.self) { invalid in + .of(&invalid.first) + } + helper(expectedByteOffset: 8, Base.self, Int.self) { invalid in + .of(&invalid.second) + } + helper(expectedByteOffset: 0, Base.self, Empty.self) { invalid in + .of(&invalid.third) } } - - @Test - func unsafeMutablePointer() { - var tuple = Tuple(first: 1, second: 2.0) - withUnsafeMutablePointer(to: &tuple) { pointer in - let first = pointer[offset: PointerOffset, Int>(byteOffset: 0)] - #expect(first == 1) - let second = pointer[offset: PointerOffset, Double>(byteOffset: 8)] - #expect(second == 2.0) - - pointer[offset: PointerOffset, Int>(byteOffset: 0)] = 3 - let newFirst = pointer[offset: PointerOffset, Int>(byteOffset: 0)] - #expect(newFirst == 3) + + @Test("Extension API between UnsafePointer/UnsafeMutablePointer and PointerOffset") + func unsafePointerAndUnsafeMutablePointerExtension() { + do { + var tuple = Tuple(first: 1, second: 2.0) + typealias Base = Tuple + let firstOffset = PointerOffset(byteOffset: 0) + let secondOffset = PointerOffset(byteOffset: 8) + withUnsafeMutablePointer(to: &tuple) { pointer in + #expect(pointer[offset: firstOffset] == 1) + #expect(pointer[offset: secondOffset] == 2.0) + + pointer[offset: firstOffset] = 3 + pointer[offset: secondOffset] = 4.0 + } + withUnsafePointer(to: tuple) { pointer in + #expect(pointer[offset: firstOffset] == 3) + #expect(pointer[offset: secondOffset].isApproximatelyEqual(to: 4.0)) + } } - - var triple = Triple(first: 0, second: 1, third: 2) - withUnsafeMutablePointer(to: &triple) { pointer in - let first = pointer + PointerOffset, Int>(byteOffset: 0) - #expect(first.pointee == 0) - let second = pointer + PointerOffset, Int>(byteOffset: 8) - #expect(second.pointee == 1) - let third = pointer + PointerOffset, Int>(byteOffset: 16) - #expect(third.pointee == 2) + + do { + var triple = Triple(first: 0, second: 1, third: 2) + typealias Base = Triple + + let firstOffset = PointerOffset.offset { .of(&$0.first) } + let secondOffset = PointerOffset.offset { .of(&$0.second) } + let thirdOffset = PointerOffset.offset { .of(&$0.third) } + withUnsafeMutablePointer(to: &triple) { pointer in + #expect((pointer + firstOffset).pointee == 0) + #expect((pointer + secondOffset).pointee == 1) + #expect((pointer + thirdOffset).pointee == 2) + + (pointer + firstOffset).pointee = 3 + (pointer + secondOffset).pointee = 4 + (pointer + thirdOffset).pointee = 5 + } + withUnsafePointer(to: triple) { pointer in + #expect((pointer + firstOffset).pointee == 3) + #expect((pointer + secondOffset).pointee == 4) + #expect((pointer + thirdOffset).pointee == 5) + } } } }