//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// import SwiftShims extension String { /// Creates a new string representing the given string repeated the specified /// number of times. /// /// For example, you can use this initializer to create a string with ten /// `"ab"` strings in a row. /// /// let s = String(repeating: "ab", count: 10) /// print(s) /// // Prints "abababababababababab" /// /// - Parameters: /// - repeatedValue: The string to repeat. /// - count: The number of times to repeat `repeatedValue` in the resulting /// string. public init(repeating repeatedValue: String, count: Int) { _precondition(count >= 0, "Negative count not allowed") guard count > 1 else { self = count == 0 ? "" : repeatedValue return } // TODO(String performance): We can directly call appendInPlace var result = String() result.reserveCapacity(repeatedValue._guts.count &* count) for _ in 0..(_ prefix: Prefix) -> Bool { return self.starts(with: prefix) } /// Returns a Boolean value indicating whether the string ends with the /// specified suffix. /// /// The comparison is both case sensitive and Unicode safe. The /// case-sensitive comparison will only match strings whose corresponding /// characters have the same case. /// /// let plans = "Let's meet at the café" /// /// // Case sensitive /// print(plans.hasSuffix("Café")) /// // Prints "false" /// /// The Unicode-safe comparison matches Unicode extended grapheme clusters /// rather than the code points used to compose them. The example below uses /// two strings with different forms of the `"é"` character---the first uses /// the composed form and the second uses the decomposed form. /// /// // Unicode safe /// let composedCafe = "café" /// let decomposedCafe = "cafe\u{0301}" /// /// print(plans.hasSuffix(composedCafe)) /// // Prints "true" /// print(plans.hasSuffix(decomposedCafe)) /// // Prints "true" /// /// - Parameter suffix: A possible suffix to test against this string. /// - Returns: `true` if the string ends with `suffix`; otherwise, `false`. @inlinable public func hasSuffix(_ suffix: Suffix) -> Bool { return self.reversed().starts(with: suffix.reversed()) } } extension String { public func hasPrefix(_ prefix: String) -> Bool { if _fastPath(self._guts.isNFCFastUTF8 && prefix._guts.isNFCFastUTF8) { guard prefix._guts.count <= self._guts.count else { return false } return prefix._guts.withFastUTF8 { nfcPrefix in let prefixEnd = nfcPrefix.count return self._guts.withFastUTF8(range: 0.. Bool { if _fastPath(self._guts.isNFCFastUTF8 && suffix._guts.isNFCFastUTF8) { guard suffix._guts.count <= self._guts.count else { return false } return suffix._guts.withFastUTF8 { nfcSuffix in let suffixStart = self._guts.count - nfcSuffix.count return self._guts.withFastUTF8(range: suffixStart..( _ value: T, radix: Int = 10, uppercase: Bool = false ) { self = value._description(radix: radix, uppercase: uppercase) } }