11
11
//===----------------------------------------------------------------------===//
12
12
13
13
extension String . Index {
14
+ private init ? < S: StringProtocol > (
15
+ _ sourcePosition: String . Index , _genericWithin target: S
16
+ ) {
17
+ guard target. _wholeGuts. isOnGraphemeClusterBoundary ( sourcePosition) else {
18
+ return nil
19
+ }
20
+ self = sourcePosition
21
+ }
22
+
14
23
/// Creates an index in the given string that corresponds exactly to the
15
24
/// specified position.
16
25
///
@@ -49,14 +58,53 @@ extension String.Index {
49
58
/// `sourcePosition` must be a valid index of at least one of the views
50
59
/// of `target`.
51
60
/// - target: The string referenced by the resulting index.
52
- public init ? (
53
- _ sourcePosition: String . Index ,
54
- within target: String
61
+ public init ? ( _ sourcePosition: String . Index , within target: String ) {
62
+ self . init ( sourcePosition, _genericWithin: target)
63
+ }
64
+
65
+ /// Creates an index in the given string that corresponds exactly to the
66
+ /// specified position.
67
+ ///
68
+ /// If the index passed as `sourcePosition` represents the start of an
69
+ /// extended grapheme cluster---the element type of a string---then the
70
+ /// initializer succeeds.
71
+ ///
72
+ /// The following example converts the position of the Unicode scalar `"e"`
73
+ /// into its corresponding position in the string. The character at that
74
+ /// position is the composed `"é"` character.
75
+ ///
76
+ /// let cafe = "Cafe\u{0301}"
77
+ /// print(cafe)
78
+ /// // Prints "Café"
79
+ ///
80
+ /// let scalarsIndex = cafe.unicodeScalars.firstIndex(of: "e")!
81
+ /// let stringIndex = String.Index(scalarsIndex, within: cafe)!
82
+ ///
83
+ /// print(cafe[...stringIndex])
84
+ /// // Prints "Café"
85
+ ///
86
+ /// If the index passed as `sourcePosition` doesn't have an exact
87
+ /// corresponding position in `target`, the result of the initializer is
88
+ /// `nil`. For example, an attempt to convert the position of the combining
89
+ /// acute accent (`"\u{0301}"`) fails. Combining Unicode scalars do not have
90
+ /// their own position in a string.
91
+ ///
92
+ /// let nextScalarsIndex = cafe.unicodeScalars.index(after: scalarsIndex)
93
+ /// let nextStringIndex = String.Index(nextScalarsIndex, within: cafe)
94
+ ///
95
+ /// print(nextStringIndex)
96
+ /// // Prints "nil"
97
+ ///
98
+ /// - Parameters:
99
+ /// - sourcePosition: A position in a view of the `target` parameter.
100
+ /// `sourcePosition` must be a valid index of at least one of the views
101
+ /// of `target`.
102
+ /// - target: The string referenced by the resulting index.
103
+ @available ( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , * )
104
+ public init ? < S: StringProtocol > (
105
+ _ sourcePosition: String . Index , within target: S
55
106
) {
56
- guard target. _guts. isOnGraphemeClusterBoundary ( sourcePosition) else {
57
- return nil
58
- }
59
- self = sourcePosition
107
+ self . init ( sourcePosition, _genericWithin: target)
60
108
}
61
109
62
110
/// Returns the position in the given UTF-8 view that corresponds exactly to
@@ -81,7 +129,7 @@ extension String.Index {
81
129
/// position of a UTF-16 trailing surrogate returns `nil`.
82
130
public func samePosition(
83
131
in utf8: String . UTF8View
84
- ) -> String . UTF8View . Index ? {
132
+ ) -> String . UTF8View . Index ? {
85
133
return String . UTF8View. Index ( self , within: utf8)
86
134
}
87
135
0 commit comments