mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
207 lines
7.6 KiB
Swift
207 lines
7.6 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2016 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.Index {
|
|
/// Creates an index in the given string that corresponds exactly to the
|
|
/// specified `UnicodeScalarView` position.
|
|
///
|
|
/// The following example converts the position of the Unicode scalar `"e"`
|
|
/// into its corresponding position in the string's character view. The
|
|
/// character at that position is the composed `"é"` character.
|
|
///
|
|
/// let cafe = "Cafe\u{0301}"
|
|
/// print(cafe)
|
|
/// // Prints "Café"
|
|
///
|
|
/// let scalarsIndex = cafe.unicodeScalars.index(of: "e")!
|
|
/// let charactersIndex = String.Index(scalarsIndex, within: cafe)!
|
|
///
|
|
/// print(String(cafe.characters.prefix(through: charactersIndex)))
|
|
/// // Prints "Café"
|
|
///
|
|
/// If the position passed in `unicodeScalarIndex` doesn't have an exact
|
|
/// corresponding position in `other.characters`, the result of the
|
|
/// initializer is `nil`. For example, an attempt to convert the position of
|
|
/// the combining acute accent (`"\u{0301}"`) fails. Combining Unicode
|
|
/// scalars do not have their own position in a character view.
|
|
///
|
|
/// let nextIndex = String.Index(cafe.unicodeScalars.index(after: scalarsIndex),
|
|
/// within: cafe)
|
|
/// print(nextIndex)
|
|
/// // Prints "nil"
|
|
///
|
|
/// - Parameters:
|
|
/// - unicodeScalarIndex: A position in the `unicodeScalars` view of the
|
|
/// `other` parameter.
|
|
/// - other: The string referenced by both `unicodeScalarIndex` and the
|
|
/// resulting index.
|
|
public init?(
|
|
_ unicodeScalarIndex: String.UnicodeScalarIndex,
|
|
within other: String
|
|
) {
|
|
if !other.unicodeScalars._isOnGraphemeClusterBoundary(unicodeScalarIndex) {
|
|
return nil
|
|
}
|
|
self.init(_base: unicodeScalarIndex, in: other.characters)
|
|
}
|
|
|
|
/// Creates an index in the given string that corresponds exactly to the
|
|
/// specified `UTF16View` position.
|
|
///
|
|
/// The following example finds the position of a space in a string's `utf16`
|
|
/// view and then converts that position to an index in the string's
|
|
/// `characters` view. The value `32` is the UTF-16 encoded value of a space
|
|
/// character.
|
|
///
|
|
/// let cafe = "Café 🍵"
|
|
///
|
|
/// let utf16Index = cafe.utf16.index(of: 32)!
|
|
/// let charactersIndex = String.Index(utf16Index, within: cafe)!
|
|
///
|
|
/// print(String(cafe.characters.prefix(upTo: charactersIndex)))
|
|
/// // Prints "Café"
|
|
///
|
|
/// If the position passed in `utf16Index` doesn't have an exact
|
|
/// corresponding position in `other.characters`, the result of the
|
|
/// initializer is `nil`. For example, an attempt to convert the position of
|
|
/// the trailing surrogate of a UTF-16 surrogate pair fails.
|
|
///
|
|
/// The next example attempts to convert the indices of the two UTF-16 code
|
|
/// points that represent the teacup emoji (`"🍵"`). The index of the lead
|
|
/// surrogate is successfully converted to a position in `other.characters`,
|
|
/// but the index of the trailing surrogate is not.
|
|
///
|
|
/// let emojiHigh = cafe.utf16.index(after: utf16Index)
|
|
/// print(String.Index(emojiHigh, within: cafe))
|
|
/// // Prints "Optional(String.Index(...))"
|
|
///
|
|
/// let emojiLow = cafe.utf16.index(after: emojiHigh)
|
|
/// print(String.Index(emojiLow, within: cafe))
|
|
/// // Prints "nil"
|
|
///
|
|
/// - Parameters:
|
|
/// - utf16Index: A position in the `utf16` view of the `other` parameter.
|
|
/// - other: The string referenced by both `utf16Index` and the resulting
|
|
/// index.
|
|
public init?(
|
|
_ utf16Index: String.UTF16Index,
|
|
within other: String
|
|
) {
|
|
if let me = utf16Index.samePosition(
|
|
in: other.unicodeScalars
|
|
)?.samePosition(in: other) {
|
|
self = me
|
|
}
|
|
else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
/// Creates an index in the given string that corresponds exactly to the
|
|
/// specified `UTF8View` position.
|
|
///
|
|
/// If the position passed in `utf8Index` doesn't have an exact corresponding
|
|
/// position in `other.characters`, the result of the initializer is `nil`.
|
|
/// For example, an attempt to convert the position of a UTF-8 continuation
|
|
/// byte returns `nil`.
|
|
///
|
|
/// - Parameters:
|
|
/// - utf8Index: A position in the `utf8` view of the `other` parameter.
|
|
/// - other: The string referenced by both `utf8Index` and the resulting
|
|
/// index.
|
|
public init?(
|
|
_ utf8Index: String.UTF8Index,
|
|
within other: String
|
|
) {
|
|
if let me = utf8Index.samePosition(
|
|
in: other.unicodeScalars
|
|
)?.samePosition(in: other) {
|
|
self = me
|
|
}
|
|
else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
/// Returns the position in the given UTF-8 view that corresponds exactly to
|
|
/// this index.
|
|
///
|
|
/// The index must be a valid index of `String(utf8).characters`.
|
|
///
|
|
/// This example first finds the position of the character `"é"` and then uses
|
|
/// this method find the same position in the string's `utf8` view.
|
|
///
|
|
/// let cafe = "Café"
|
|
/// if let i = cafe.characters.index(of: "é") {
|
|
/// let j = i.samePosition(in: cafe.utf8)
|
|
/// print(Array(cafe.utf8.suffix(from: j)))
|
|
/// }
|
|
/// // Prints "[195, 169]"
|
|
///
|
|
/// - Parameter utf8: The view to use for the index conversion.
|
|
/// - Returns: The position in `utf8` that corresponds exactly to this index.
|
|
public func samePosition(
|
|
in utf8: String.UTF8View
|
|
) -> String.UTF8View.Index {
|
|
return String.UTF8View.Index(self, within: utf8)
|
|
}
|
|
|
|
/// Returns the position in the given UTF-16 view that corresponds exactly to
|
|
/// this index.
|
|
///
|
|
/// The index must be a valid index of `String(utf16).characters`.
|
|
///
|
|
/// This example first finds the position of the character `"é"` and then uses
|
|
/// this method find the same position in the string's `utf16` view.
|
|
///
|
|
/// let cafe = "Café"
|
|
/// if let i = cafe.characters.index(of: "é") {
|
|
/// let j = i.samePosition(in: cafe.utf16)
|
|
/// print(cafe.utf16[j])
|
|
/// }
|
|
/// // Prints "233"
|
|
///
|
|
/// - Parameter utf16: The view to use for the index conversion.
|
|
/// - Returns: The position in `utf16` that corresponds exactly to this index.
|
|
public func samePosition(
|
|
in utf16: String.UTF16View
|
|
) -> String.UTF16View.Index {
|
|
return String.UTF16View.Index(self, within: utf16)
|
|
}
|
|
|
|
/// Returns the position in the given view of Unicode scalars that
|
|
/// corresponds exactly to this index.
|
|
///
|
|
/// The index must be a valid index of `String(unicodeScalars).characters`.
|
|
///
|
|
/// This example first finds the position of the character `"é"` and then uses
|
|
/// this method find the same position in the string's `unicodeScalars`
|
|
/// view.
|
|
///
|
|
/// let cafe = "Café"
|
|
/// if let i = cafe.characters.index(of: "é") {
|
|
/// let j = i.samePosition(in: cafe.unicodeScalars)
|
|
/// print(cafe.unicodeScalars[j])
|
|
/// }
|
|
/// // Prints "é"
|
|
///
|
|
/// - Parameter unicodeScalars: The view to use for the index conversion.
|
|
/// - Returns: The position in `unicodeScalars` that corresponds exactly to
|
|
/// this index.
|
|
public func samePosition(
|
|
in unicodeScalars: String.UnicodeScalarView
|
|
) -> String.UnicodeScalarView.Index {
|
|
return String.UnicodeScalarView.Index(self, within: unicodeScalars)
|
|
}
|
|
}
|
|
|