Skip to content

Commit 5846e8f

Browse files
authored
Add Equatable and Hashable conformance to GUID. (#84792)
On Windows, `GUID` is a currency type and (along with its various typedefs) is used pervasively Windows offers `IsEqualGUID()` and `UuidHash()` for comparing and hashing them, respectively, but `IsEqualGUID()` is a macro in C mode and `UuidHash()` only provides a 16-bit hash. We should provide conformance to these protocols in the WinSDK overlay to provide equivalent functionality in Swift.
1 parent 1803d3e commit 5846e8f

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

stdlib/public/Windows/WinSDK.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,31 @@ func _convertWindowsBoolToBool(_ b: WindowsBool) -> Bool {
319319
return b.boolValue
320320
}
321321

322+
// GUID
323+
324+
extension GUID {
325+
@usableFromInline @_transparent
326+
internal var uint128Value: UInt128 {
327+
unsafe withUnsafeBytes(of: self) { buffer in
328+
// GUID is 32-bit-aligned only, so use loadUnaligned().
329+
unsafe buffer.baseAddress!.loadUnaligned(as: UInt128.self)
330+
}
331+
}
332+
}
333+
334+
// These conformances are marked @retroactive because the GUID type nominally
335+
// comes from the _GUIDDef clang module rather than the WinSDK clang module.
336+
337+
extension GUID: @retroactive Equatable {
338+
@_transparent
339+
public static func ==(lhs: Self, rhs: Self) -> Bool {
340+
lhs.uint128Value == rhs.uint128Value
341+
}
342+
}
343+
344+
extension GUID: @retroactive Hashable {
345+
@_transparent
346+
public func hash(into hasher: inout Hasher) {
347+
hasher.combine(uint128Value)
348+
}
349+
}

test/stdlib/WinSDK_GUID.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-build-swift %s
1+
// RUN: %target-build-swift %s -o %t.exe
2+
// RUN: %target-codesign %t.exe
3+
// RUN: %target-run %t.exe
4+
// REQUIRES: executable_test
25
// REQUIRES: OS=windows-msvc
36

47
// Make sure that importing WinSDK brings in the GUID type, which is declared in
@@ -7,3 +10,13 @@
710
import WinSDK
811

912
public func usesGUID(_ x: GUID) {}
13+
14+
// Make sure equating and hashing GUIDs works.
15+
16+
let guid: GUID = GUID_NULL
17+
assert(guid == guid)
18+
assert(guid.hashValue == guid.hashValue)
19+
20+
let guid2: GUID = IID_IUnknown
21+
assert(guid != guid2)
22+
assert(guid.hashValue != guid2.hashValue) // well, probably

0 commit comments

Comments
 (0)