//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // Interfaces with a questionable future that are needed in order to // be a drop-in replacement for String // extension String { @public init(count sz: Int, repeatedValue c: Character) { let s = String(c) self = String(_StringBuffer(capacity: s.core.count * sz, initialSize: 0, elementWidth: s.core.elementWidth)) for i in 0.. [String] { var scalarSlices = Swift.split(unicodeScalars, { $0 == separator }) return scalarSlices.map { $0 as String } } @public var isEmpty : Bool { return core.count == 0 } } extension String { @public var uppercaseString : String { let end = utf8.endIndex var resultArray = ContiguousArray( count: countElements(utf8), repeatedValue: 0) var i = utf8.startIndex var j = 0 while i != end { let u8 = utf8[i++] if u8 < 0x80 { if 97..<123 ~= u8 { resultArray[j++] = u8 - 32 } else { resultArray[j++] = u8 } } else if u8 < 0xE0 { resultArray[j++] = u8 let u8_1 = utf8[i++] if u8 == 0xC3 && 0xA0..<0xBF ~= Int(u8_1) && u8_1 != 0xB7 { resultArray[j++] = u8_1 - 0x20 } else { resultArray[j++] = u8_1 } } else { resultArray[j++] = u8 if u8 >= 0xF0 { resultArray[j++] = utf8[i++] } resultArray[j++] = utf8[i++] resultArray[j++] = utf8[i++] } } return String._fromWellFormedCodeUnitSequence(UTF8.self, input: resultArray) } @public var lowercaseString : String { let end = utf8.endIndex var resultArray = ContiguousArray( count: countElements(utf8), repeatedValue: 0) var i = utf8.startIndex var j = 0 while i != end { let u8 = utf8[i++] if u8 < 0x80 { if 65..<91 ~= u8 { resultArray[j++] = u8 + 32 } else { resultArray[j++] = u8 } } else if u8 < 0xE0 { resultArray[j++] = u8 let u8_1 = utf8[i++] if u8 == 0xC3 && 0x80..<0x9F ~= u8_1 && u8_1 != 0x97 { resultArray[j++] = u8_1 + 0x20 } else { resultArray[j++] = u8_1 } } else { resultArray[j++] = u8 if u8 >= 0xF0 { resultArray[j++] = utf8[i++] } resultArray[j++] = utf8[i++] resultArray[j++] = utf8[i++] } } return String._fromWellFormedCodeUnitSequence(UTF8.self, input: resultArray) } init(_ _c: UnicodeScalar) { self = String(count: 1, repeatedValue: _c) } func _isAll(predicate: (UnicodeScalar) -> Bool) -> Bool { for c in unicodeScalars { if !predicate(c) { return false } } return true } @public func hasPrefix(prefix: String) -> Bool { return Swift.startsWith(self, prefix) } @public func hasSuffix(suffix: String) -> Bool { return Swift.startsWith(reverse(self), reverse(suffix)) } func _isAlpha() -> Bool { return _isAll({ $0.isAlpha() }) } func _isDigit() -> Bool { return _isAll({ $0.isDigit() }) } func _isSpace() -> Bool { return _isAll({ $0.isSpace() }) } } /// Represent a positive integer value in the given radix, /// writing each ASCII character into stream. The value of `ten' /// should be either "A" or "a", depending on whether you want upper- /// or lower-case letters when radix > 10 func _formatPositiveInteger( value: UInt64, radix: UInt64, ten: UnicodeScalar = "a") ( stream: (UTF8.CodeUnit)->Void ) { if value == 0 { return } _formatPositiveInteger(value / radix, radix, ten: ten)(stream: stream) var digit = UInt32(value % radix) var baseCharOrd: UInt32 = digit <= 9 ? _asUnicodeCodePoint("0") : _asUnicodeCodePoint(ten) - 10 stream(UTF8.CodeUnit(baseCharOrd + digit)) } func _formatSignedInteger( value: Int64, radix: UInt64, ten: UnicodeScalar = "a") ( stream: (UTF8.CodeUnit)->Void ) { if value == 0 { stream(UTF8.CodeUnit(_asUnicodeCodePoint("0"))) } else { if (value < 0) { let minusCharacter: UnicodeScalar = "-" stream(UTF8.CodeUnit(_asUnicodeCodePoint("-"))) } // Compute the absolute value without causing overflow when value // == Int64.min let absValue = value < 0 ? UInt64(~value) + 1 : UInt64(value) _formatPositiveInteger(absValue, radix, ten: ten)(stream: stream) } } // Conversions to string from other types. extension String { @public init(_ v: Int64, radix: Int = 10, _uppercase: Bool = false) { var format = _formatSignedInteger(v, UInt64(radix), ten: _uppercase ? "A" : "a") var asciiCount = 0 format(stream: { _ in ++asciiCount;() }) var buffer = _StringBuffer( capacity: asciiCount, initialSize: asciiCount, elementWidth: 1) var p = UnsafePointer(buffer.start) format(stream: { p++.memory = $0 }) self = String(buffer) } // FIXME: This function assumes UTF16 @public init(_ v: UInt64, radix: Int = 10, _uppercase: Bool = false) { var format = _formatPositiveInteger(v, UInt64(radix), ten: _uppercase ? "A" : "a") var asciiCount = v == 0 ? 1 : 0 format(stream: { _ in ++asciiCount;() }) var buffer = _StringBuffer( capacity: asciiCount, initialSize: asciiCount, elementWidth: 1) var p = UnsafePointer(buffer.start) format(stream: { p++.memory = $0 }) if v == 0 { p++.memory = UTF8.CodeUnit("0") } self = String(buffer) } @public init(_ v : Int8, radix : Int = 10, _uppercase : Bool = false) { self = String(Int64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : Int16, radix : Int = 10, _uppercase : Bool = false) { self = String(Int64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : Int32, radix : Int = 10, _uppercase : Bool = false) { self = String(Int64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : Int, radix : Int = 10, _uppercase : Bool = false) { self = String(Int64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : UInt8, radix : Int = 10, _uppercase : Bool = false) { self = String(UInt64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : UInt16, radix : Int = 10, _uppercase : Bool = false) { self = String(UInt64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : UInt32, radix : Int = 10, _uppercase : Bool = false) { self = String(UInt64(v), radix: radix, _uppercase: _uppercase) } @public init(_ v : UInt, radix : Int = 10, _uppercase : Bool = false) { self = String(UInt64(v), radix: radix, _uppercase: _uppercase) } typealias _Double = Double typealias _Float = Float typealias _Bool = Bool init(_ v : _Double) { self = _doubleToString(v) } init(_ v : _Float) { self = String(Double(v)) } init(_ b : _Bool) { if b { self = "true" } else { self = "false" } } } // Conversions from string to other types. extension String { /// If the string represents an integer that fits into an Int, returns /// the corresponding integer. @public func toInt() -> Int? { var scalars = self.unicodeScalars var start = scalars.startIndex if start == scalars.endIndex { return .None } // Interpet '+' or '-' before the number. var negativeFactor = -1 var firstC = scalars[start] if (firstC == "+") { ++start } else if (firstC == "-") { ++start negativeFactor = 1 } // Interpret the string as an integer. // Since Int.min has a larger absolute value, perform addition with // negative numbers; detect underflows before they happen. var res : Int = 0 for c in scalars[start.. String { var rng = unicodeScalars var startIndex = rng.startIndex for i in 0.. (before: String, after: String, wasFound : Bool) { var rng = unicodeScalars for i in indices(rng) { if rng[i] == delim { return (rng[rng.startIndex.. Bool) -> (before: String, found: UnicodeScalar, after: String, wasFound: Bool) { var rng = unicodeScalars for i in indices(rng) { if predicate(rng[i]) { return (rng[rng.startIndex.. Bool) -> [String] { var scalarSlices = Swift.split(unicodeScalars, predicate) return scalarSlices.map { $0 as String } } }