Skip to content

Commit 396eca7

Browse files
committed
Implement String Comparable and Hashable conformances for non-objc
This is just a basic implementation of each, with some questions lingering about whether to do unicode normalization (and if so how), but it gets things going. Swift SVN r23572
1 parent 72c226e commit 396eca7

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

stdlib/core/String.swift

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,24 @@ extension String {
287287
public func _stdlib_compareNSStringDeterministicUnicodeCollation(
288288
lhs: AnyObject, rhs: AnyObject
289289
)-> Int32
290+
#else
291+
/// Compare two strings using the current locale and as defined by the
292+
/// platform's clib. Unlike the above, this may or may not do normalization,
293+
/// depending on the platform.
294+
/// FIXME: Make this do unicode normalization?
295+
@asmname("strcoll")
296+
public func _stdlib_strcoll(
297+
lhs: UnsafePointer<Int8>, rhs: UnsafePointer<Int8>
298+
) -> CInt
299+
300+
public func _stdlib_strcoll_wrap(lhs: String, rhs: String) -> CInt {
301+
var res : CInt
302+
return lhs.withCString { lhs -> CInt in
303+
return rhs.withCString { rhs -> CInt in
304+
return _stdlib_strcoll(lhs, rhs)
305+
}
306+
}
307+
}
290308
#endif
291309

292310
extension String: Equatable {
@@ -308,9 +326,7 @@ public func ==(lhs: String, rhs: String) -> Bool {
308326
return _stdlib_compareNSStringDeterministicUnicodeCollation(
309327
lhs._bridgeToObjectiveCImpl(), rhs._bridgeToObjectiveCImpl()) == 0
310328
#else
311-
// FIXME: Actually implement. For now, all strings are unequal.
312-
// rdar://problem/18878343
313-
return false
329+
return _stdlib_strcoll_wrap(lhs, rhs) == 0
314330
#endif
315331
}
316332

@@ -324,9 +340,7 @@ extension String {
324340
return _stdlib_compareNSStringDeterministicUnicodeCollation(
325341
self._bridgeToObjectiveCImpl(), rhs._bridgeToObjectiveCImpl()) < 0
326342
#else
327-
// FIXME: Actually implement. For now, all strings are unequal
328-
// rdar://problem/18878343
329-
return false
343+
return _stdlib_strcoll_wrap(self, rhs) < 0
330344
#endif
331345
}
332346

@@ -391,23 +405,29 @@ extension String : Hashable {
391405
/// different invocations of the same program. Do not persist the
392406
/// hash value across program runs.
393407
public var hashValue: Int {
408+
#if _runtime(_ObjC)
394409
// Mix random bits into NSString's hash so that clients don't rely on
395410
// Swift.String.hashValue and NSString.hash being the same.
396411
#if arch(i386) || arch(arm)
397412
let hashOffset = 0x88ddcc21
398413
#else
399414
let hashOffset = 0x429b126688ddcc21
400415
#endif
401-
#if _runtime(_ObjC)
402416
// FIXME(performance): constructing a temporary NSString is extremely
403417
// wasteful and inefficient.
404418
let cocoaString =
405419
unsafeBitCast(self._bridgeToObjectiveCImpl(), _NSStringCoreType.self)
406420
return hashOffset ^ _stdlib_NSStringNFDHashValue(cocoaString)
407421
#else
408-
// FIXME: Actually implement. For now, all strings have the same hash.
409-
// rdar://problem/18878343
410-
return hashOffset
422+
// FIXME: A better algorithm? Maybe murmur? This is djb2, which is fairly
423+
// common and simple.
424+
// FIXME: Like string comparison above, this does not normalize the unicode
425+
// string like the NSString callout does.
426+
var hash = 5381
427+
for char in UTF8View(_core) {
428+
hash = ((hash << 5) &+ hash) &+ Int(char)
429+
}
430+
return hash
411431
#endif
412432
}
413433
}

0 commit comments

Comments
 (0)