mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
stdlib: move String.{lowercaseString,uppercaseString} to the core
library Swift SVN r23936
This commit is contained in:
@@ -10,84 +10,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: these properties should be implemented in the core library.
|
||||
// <rdar://problem/17550602> [unicode] Implement case folding
|
||||
extension String {
|
||||
/// A "table" for which ASCII characters need to be upper cased.
|
||||
/// To determine which bit corresponds to which ASCII character, subtract 1
|
||||
/// from the ASCII value of that character and divide by 2. The bit is set iff
|
||||
/// that character is a lower case character.
|
||||
internal var _asciiLowerCaseTable: UInt64 {
|
||||
@inline(__always)
|
||||
get {
|
||||
return 0b0001_1111_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
|
||||
}
|
||||
}
|
||||
|
||||
/// The same table for upper case characters.
|
||||
internal var _asciiUpperCaseTable: UInt64 {
|
||||
@inline(__always)
|
||||
get {
|
||||
return 0b0000_0000_0000_0000_0001_1111_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000
|
||||
}
|
||||
}
|
||||
|
||||
public var lowercaseString: String {
|
||||
if self._core.isASCII {
|
||||
let length = self._core.count
|
||||
let source = self._core.startASCII
|
||||
var buffer = _StringBuffer(
|
||||
capacity: length, initialSize: length, elementWidth: 1)
|
||||
var dest = UnsafeMutablePointer<UInt8>(buffer.start)
|
||||
for i in 0..<length {
|
||||
// For each character in the string, we lookup if it should be shifted
|
||||
// in our ascii table, then we return 0x20 if it should, 0x0 if not.
|
||||
// This code is equivalent to:
|
||||
// switch source[i] {
|
||||
// case let x where (x >= 0x41 && x <= 0x5a):
|
||||
// dest[i] = x &+ 0x20
|
||||
// case let x:
|
||||
// dest[i] = x
|
||||
// }
|
||||
let value = source[i]
|
||||
let isUpper =
|
||||
_asciiUpperCaseTable >>
|
||||
UInt64(((value &- 1) & 0b0111_1111) >> 1)
|
||||
let add = (isUpper & 0x1) << 5
|
||||
// Since we are left with either 0x0 or 0x20, we can safely truncate to
|
||||
// a UInt8 and add to our ASCII value (this will not overflow numbers in
|
||||
// the ASCII range).
|
||||
dest[i] = value &+ UInt8(truncatingBitPattern: add)
|
||||
}
|
||||
return String(_storage: buffer)
|
||||
}
|
||||
|
||||
return _ns.lowercaseString
|
||||
}
|
||||
|
||||
public var uppercaseString: String {
|
||||
if self._core.isASCII {
|
||||
let length = self._core.count
|
||||
let source = self._core.startASCII
|
||||
var buffer = _StringBuffer(
|
||||
capacity: length, initialSize: length, elementWidth: 1)
|
||||
var dest = UnsafeMutablePointer<UInt8>(buffer.start)
|
||||
for i in 0..<length {
|
||||
// See the comment above in lowercaseString.
|
||||
let value = source[i]
|
||||
let isLower =
|
||||
_asciiLowerCaseTable >>
|
||||
UInt64(((value &- 1) & 0b0111_1111) >> 1)
|
||||
let add = (isLower & 0x1) << 5
|
||||
dest[i] = value &- UInt8(truncatingBitPattern: add)
|
||||
}
|
||||
return String(_storage: buffer)
|
||||
}
|
||||
|
||||
return _ns.uppercaseString
|
||||
}
|
||||
}
|
||||
|
||||
extension String.UTF16View.Index : RandomAccessIndexType {
|
||||
public func distanceTo(x: String.UTF16View.Index) -> Int {
|
||||
return x._offset - _offset
|
||||
|
||||
Reference in New Issue
Block a user