Skip to content

Instantly share code, notes, and snippets.

@McNight
Created April 19, 2020 21:27
Show Gist options
  • Save McNight/c3a2b2bc3f047b09a1d1f3b27f8fb223 to your computer and use it in GitHub Desktop.
Save McNight/c3a2b2bc3f047b09a1d1f3b27f8fb223 to your computer and use it in GitHub Desktop.
Hashable's StaticString
import Foundation
extension StaticString: Equatable {
public static func == (lhs: StaticString, rhs: StaticString) -> Bool {
let lp = UnsafeRawPointer(lhs.utf8Start).assumingMemoryBound(to: Int8.self)
let rp = UnsafeRawPointer(rhs.utf8Start).assumingMemoryBound(to: Int8.self)
return strcmp(lp, rp) == 0
}
}
extension StaticString: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(bytes: UnsafeRawBufferPointer(start: utf8Start, count: utf8CodeUnitCount))
}
}
var dictionary: [StaticString: Int] = [:]
dictionary["Swift"] = 42
@hmlongco
Copy link

Just noting the above StaticString comparison will blow up if the StaticString is a unicode scalar. A safer method that also works with scalars is ...

    public static func == (lhs: Self, rhs: Self) -> Bool {
        if lhs.hasPointerRepresentation && rhs.hasPointerRepresentation {
            if lhs.utf8Start == rhs.utf8Start {
                return true
            }            
            return strcmp(lhs.utf8Start, rhs.utf8Start) == 0
        } else if lhs.asPointerRepresentation == false && rhs.hasPointerRepresentation == false {
            return lhs.unicodeScalar.value == rhs.unicodeScalar.value
        }
        // in this context if one's a scalar and one's a pointer unequal
        return false
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment