//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// extension String { // FIXME(strings): at least temporarily remove it to see where it was applied /// Creates a new string from the given substring. /// /// - Parameter substring: A substring to convert to a standalone `String` /// instance. /// /// - Complexity: O(*n*), where *n* is the length of `substring`. @_inlineable // FIXME(sil-serialize-all) public init(_ substring: Substring) { let x = substring._wholeString let start = substring.startIndex let end = substring.endIndex let u16 = x._core[start.encodedOffset.. /// Creates an empty substring. @_inlineable // FIXME(sil-serialize-all) public init() { _slice = Slice() } @_inlineable // FIXME(sil-serialize-all) @_versioned // FIXME(sil-serialize-all) internal init(_slice: Slice) { self._slice = _slice } /// Creates a substring with the specified bounds within the given string. /// /// - Parameters: /// - base: The string to create a substring of. /// - bounds: The range of `base` to use for the substring. The lower and /// upper bounds of `bounds` must be valid indices of `base`. @_inlineable // FIXME(sil-serialize-all) public init(_base base: String, _ bounds: Range) { _slice = Slice(base: base, bounds: bounds) } @_inlineable // FIXME(sil-serialize-all) @_versioned // FIXME(sil-serialize-all) internal init( _base base: String, _ bounds: R ) where R.Bound == Index { self.init(_base: base, bounds.relative(to: base)) } @_inlineable // FIXME(sil-serialize-all) public var startIndex: Index { return _slice.startIndex } @_inlineable // FIXME(sil-serialize-all) public var endIndex: Index { return _slice.endIndex } @_inlineable // FIXME(sil-serialize-all) public func index(after i: Index) -> Index { _precondition(i < endIndex, "Cannot increment beyond endIndex") _precondition(i >= startIndex, "Cannot increment an invalid index") // FIXME(strings): slice types currently lack necessary bound checks return _slice.index(after: i) } @_inlineable // FIXME(sil-serialize-all) public func index(before i: Index) -> Index { _precondition(i <= endIndex, "Cannot decrement an invalid index") _precondition(i > startIndex, "Cannot decrement beyond startIndex") // FIXME(strings): slice types currently lack necessary bound checks return _slice.index(before: i) } @_inlineable // FIXME(sil-serialize-all) public func index(_ i: Index, offsetBy n: Int) -> Index { let result = _slice.index(i, offsetBy: n) // FIXME(strings): slice types currently lack necessary bound checks _precondition( (_slice._startIndex ... _slice.endIndex).contains(result), "Operation results in an invalid index") return result } @_inlineable // FIXME(sil-serialize-all) public func index( _ i: Index, offsetBy n: Int, limitedBy limit: Index ) -> Index? { let result = _slice.index(i, offsetBy: n, limitedBy: limit) // FIXME(strings): slice types currently lack necessary bound checks _precondition(result.map { (_slice._startIndex ... _slice.endIndex).contains($0) } ?? true, "Operation results in an invalid index") return result } @_inlineable // FIXME(sil-serialize-all) public func distance(from start: Index, to end: Index) -> Int { return _slice.distance(from: start, to: end) } @_inlineable // FIXME(sil-serialize-all) public subscript(i: Index) -> Character { return _slice[i] } @_inlineable // FIXME(sil-serialize-all) public mutating func replaceSubrange( _ bounds: Range, with newElements: C ) where C : Collection, C.Iterator.Element == Iterator.Element { // FIXME(strings): slice types currently lack necessary bound checks _slice.replaceSubrange(bounds, with: newElements) } % for Range in ['Range', 'ClosedRange']: @_inlineable // FIXME(sil-serialize-all) public mutating func replaceSubrange( _ bounds: ${Range}, with newElements: Substring ) { replaceSubrange(bounds, with: newElements._slice) } % end /// Creates a string from the given Unicode code units in the specified /// encoding. /// /// - Parameters: /// - codeUnits: A collection of code units encoded in the encoding /// specified in `sourceEncoding`. /// - sourceEncoding: The encoding in which `codeUnits` should be /// interpreted. @_inlineable // FIXME(sil-serialize-all) public init( decoding codeUnits: C, as sourceEncoding: Encoding.Type ) where C.Iterator.Element == Encoding.CodeUnit { self.init(String(decoding: codeUnits, as: sourceEncoding)) } /// Creates a string from the null-terminated, UTF-8 encoded sequence of /// bytes at the given pointer. /// /// - Parameter nullTerminatedUTF8: A pointer to a sequence of contiguous, /// UTF-8 encoded bytes ending just before the first zero byte. @_inlineable // FIXME(sil-serialize-all) public init(cString nullTerminatedUTF8: UnsafePointer) { self.init(String(cString: nullTerminatedUTF8)) } /// Creates a string from the null-terminated sequence of bytes at the given /// pointer. /// /// - Parameters: /// - nullTerminatedCodeUnits: A pointer to a sequence of contiguous code /// units in the encoding specified in `sourceEncoding`, ending just /// before the first zero code unit. /// - sourceEncoding: The encoding in which the code units should be /// interpreted. @_inlineable // FIXME(sil-serialize-all) public init( decodingCString nullTerminatedCodeUnits: UnsafePointer, as sourceEncoding: Encoding.Type ) { self.init( String(decodingCString: nullTerminatedCodeUnits, as: sourceEncoding)) } /// Calls the given closure with a pointer to the contents of the string, /// represented as a null-terminated sequence of UTF-8 code units. /// /// The pointer passed as an argument to `body` is valid only during the /// execution of `withCString(_:)`. Do not store or return the pointer for /// later use. /// /// - Parameter body: A closure with a pointer parameter that points to a /// null-terminated sequence of UTF-8 code units. If `body` has a return /// value, that value is also used as the return value for the /// `withCString(_:)` method. The pointer argument is valid only for the /// duration of the method's execution. /// - Returns: The return value, if any, of the `body` closure parameter. @_inlineable // FIXME(sil-serialize-all) public func withCString( _ body: (UnsafePointer) throws -> Result) rethrows -> Result { return try _wholeString._core._withCSubstringAndLength( in: startIndex.encodedOffset..( encodedAs targetEncoding: TargetEncoding.Type, _ body: (UnsafePointer) throws -> Result ) rethrows -> Result { return try _wholeString._core._withCSubstring( in: startIndex.encodedOffset..(lhs: Self, rhs: R) -> Bool { return lhs._ephemeralString == rhs._ephemeralString } @_inlineable // FIXME(sil-serialize-all) public static func !=(lhs: Self, rhs: R) -> Bool { return lhs._ephemeralString != rhs._ephemeralString } } extension StringProtocol { @_inlineable // FIXME(sil-serialize-all) public static func < (lhs: Self, rhs: R) -> Bool { return lhs._ephemeralString < rhs._ephemeralString } @_inlineable // FIXME(sil-serialize-all) public static func > (lhs: Self, rhs: R) -> Bool { return rhs < lhs } @_inlineable // FIXME(sil-serialize-all) public static func <= (lhs: Self, rhs: R) -> Bool { return !(rhs < lhs) } @_inlineable // FIXME(sil-serialize-all) public static func >= (lhs: Self, rhs: R) -> Bool { return !(lhs < rhs) } } extension StringProtocol { @_inlineable // FIXME(sil-serialize-all) public var hashValue : Int { return self._ephemeralString.hashValue } } % for (property, ViewPrefix) in [ % ('utf8', 'UTF8'), % ('utf16', 'UTF16'), % ('unicodeScalars', 'UnicodeScalar'), % ('characters', 'Character') % ]: % View = ViewPrefix + 'View' % RangeReplaceable = 'RangeReplaceable' if property == 'unicodeScalars' else '' extension Substring { % if View == 'CharacterView': @available(swift, deprecated: 3.2, message: "Please use String or Substring directly") % end @_fixed_layout // FIXME(sil-serialize-all) public struct ${View} { @_versioned // FIXME(sil-serialize-all) internal var _slice: Slice } } extension Substring.${View} : BidirectionalCollection { public typealias Index = String.Index public typealias SubSequence = Substring.${View} /// Creates an instance that slices `base` at `_bounds`. @_inlineable // FIXME(sil-serialize-all) @_versioned // FIXME(sil-serialize-all) internal init(_ base: String.${View}, _bounds: Range) { _slice = Slice( base: String(base._core).${property}, bounds: _bounds) } /// The entire String onto whose slice this view is a projection. @_inlineable // FIXME(sil-serialize-all) @_versioned // FIXME(sil-serialize-all) internal var _wholeString: String { return String(_slice._base._core) } @_inlineable // FIXME(sil-serialize-all) public var startIndex: Index { return _slice.startIndex } @_inlineable // FIXME(sil-serialize-all) public var endIndex: Index { return _slice.endIndex } @_inlineable // FIXME(sil-serialize-all) public func index(after i: Index) -> Index { return _slice.index(after: i) } @_inlineable // FIXME(sil-serialize-all) public func index(before i: Index) -> Index { return _slice.index(before: i) } @_inlineable // FIXME(sil-serialize-all) public subscript(i: Index) -> String.${View}.Element { return _slice[i] } @_inlineable // FIXME(sil-serialize-all) public subscript(r: Range) -> SubSequence { return Substring.${View}(_wholeString.${property}, _bounds: r) } } extension Substring { % if View == 'CharacterView': @available(swift, deprecated: 3.2, message: "Please use String or Substring directly") % end @_inlineable // FIXME(sil-serialize-all) public var ${property}: ${View} { get { return ${View}(_wholeString.${property}, _bounds: startIndex..( _ target: Range, with replacement: C ) where C.Element == Element { _slice.replaceSubrange(target, with: replacement) } } #if _runtime(_ObjC) extension Substring { @_inlineable // FIXME(sil-serialize-all) public func hasPrefix(_ prefix: String) -> Bool { return String(self).hasPrefix(prefix) } @_inlineable // FIXME(sil-serialize-all) public func hasSuffix(_ suffix: String) -> Bool { return String(self).hasSuffix(suffix) } } #endif extension Substring : RangeReplaceableCollection { @_inlineable // FIXME(sil-serialize-all) public init(_ elements: S) where S.Element == Character { let e0 = elements as? _SwiftStringView if _fastPath(e0 != nil), let e = e0 { self = e._ephemeralContent[...] } else { self = String(elements)[...] } } @_inlineable // FIXME(sil-serialize-all) public mutating func append(contentsOf elements: S) where S.Element == Character { var c = self._ephemeralContent._core self = Substring() let e0 = elements as? _SwiftStringView if _fastPath(e0 != nil), let e1 = e0 { c.append(contentsOf: e1._ephemeralContent.utf16) self = String(c)[...] } else { var s = String(c) s.append(contentsOf: elements) self = s[...] } } } extension Substring { @_inlineable // FIXME(sil-serialize-all) public func lowercased() -> String { return String(self).lowercased() } @_inlineable // FIXME(sil-serialize-all) public func uppercased() -> String { return String(self).uppercased() } @_inlineable // FIXME(sil-serialize-all) public func filter( _ isIncluded: (Element) throws -> Bool ) rethrows -> String { return try String(self.lazy.filter(isIncluded)) } } extension Substring : TextOutputStream { @_inlineable // FIXME(sil-serialize-all) public mutating func write(_ other: String) { append(contentsOf: other) } } extension Substring : TextOutputStreamable { @_inlineable // FIXME(sil-serialize-all) public func write(to target: inout Target) { target.write(String(self)) } } extension Substring : ExpressibleByUnicodeScalarLiteral { @_inlineable // FIXME(sil-serialize-all) public init(unicodeScalarLiteral value: String) { self.init(_base: value, value.startIndex ..< value.endIndex) } } extension Substring : ExpressibleByExtendedGraphemeClusterLiteral { @_inlineable // FIXME(sil-serialize-all) public init(extendedGraphemeClusterLiteral value: String) { self.init(_base: value, value.startIndex ..< value.endIndex) } } extension Substring : ExpressibleByStringLiteral { @_inlineable // FIXME(sil-serialize-all) public init(stringLiteral value: String) { self.init(_base: value, value.startIndex ..< value.endIndex) } } //===--- String/Substring Slicing Support ---------------------------------===// /// In Swift 3.2, in the absence of type context, /// /// someString[someString.startIndex..) -> Substring { return Substring( _slice: Slice(base: self, bounds: r)) } @_inlineable // FIXME(sil-serialize-all) @available(swift, obsoleted: 4) public subscript(bounds: Range) -> String { return String(characters[bounds]) } @_inlineable // FIXME(sil-serialize-all) @available(swift, obsoleted: 4) public subscript(bounds: ClosedRange) -> String { return String(characters[bounds]) } } extension Substring { @_inlineable // FIXME(sil-serialize-all) @available(swift, introduced: 4) public subscript(r: Range) -> Substring { return Substring(_slice: _slice[r]) } @_inlineable // FIXME(sil-serialize-all) @available(swift, obsoleted: 4) public subscript(bounds: Range) -> String { return String(characters[bounds]) } @_inlineable // FIXME(sil-serialize-all) @available(swift, obsoleted: 4) public subscript(bounds: ClosedRange) -> String { return String(characters[bounds]) } } //===----------------------------------------------------------------------===// // popFirst() is only present when a collection is its own subsequence. This was // dropped in Swift 4. extension String { @_inlineable // FIXME(sil-serialize-all) @available(swift, deprecated: 3.2, obsoleted: 4, message: "Please use 'first', 'dropFirst()', or 'Substring.popFirst()'.") public mutating func popFirst() -> String.Element? { guard !isEmpty else { return nil } let element = first! let nextIdx = self.index(after: self.startIndex) self = String(self[nextIdx...]) return element } } extension String._CharacterView { @_inlineable // FIXME(sil-serialize-all) @available(swift, deprecated: 3.2, obsoleted: 4, message: "Please use 'first', 'dropFirst()', or 'Substring.CharacterView.popFirst()'.") public mutating func popFirst() -> String._CharacterView.Element? { guard !isEmpty else { return nil } let element = first! let nextIdx = self.index(after: self.startIndex) self = String(self[nextIdx...])._characters return element } } extension String.UnicodeScalarView { @_inlineable // FIXME(sil-serialize-all) @available(swift, deprecated: 3.2, obsoleted: 4, message: "Please use 'first', 'dropFirst()', or 'Substring.UnicodeScalarView.popFirst()'.") public mutating func popFirst() -> String.UnicodeScalarView.Element? { guard !isEmpty else { return nil } let element = first! let nextIdx = self.index(after: self.startIndex) self = String(self[nextIdx...]).unicodeScalars return element } }