Skip to content

Commit 6160220

Browse files
committed
Use substring end to handle unaligned indices
1 parent 9024254 commit 6160220

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

Sources/_StringProcessing/Engine/MEBuiltins.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,7 @@ extension String {
125125
///
126126
/// This function handles loading a character from a string while respecting
127127
/// an end boundary, even if that end boundary is sub-character or sub-scalar.
128-
///
129-
/// - Parameters:
130-
/// - pos: The position to load a character from.
131-
/// - end: The limit for the character at `pos`.
132-
/// - Returns:
128+
133129
/// - If `pos` is at or past `end`, this function returns `nil`.
134130
/// - If `end` is between `pos` and the next grapheme cluster boundary (i.e.,
135131
/// `end` is before `self.index(after: pos)`, then the returned character
@@ -139,11 +135,20 @@ extension String {
139135
/// is not on a Unicode scalar boundary, the partial scalar is dropped. This
140136
/// can result in a `nil` return or a character that includes only part of
141137
/// the `self[pos]` character.
138+
///
139+
/// - Parameters:
140+
/// - pos: The position to load a character from.
141+
/// - end: The limit for the character at `pos`.
142+
/// - Returns: The character at `pos`, bounded by `end`, if it exists, along
143+
/// with the upper bound of that character. The upper bound is always
144+
/// scalar-aligned.
142145
func characterAndEnd(at pos: String.Index, limitedBy end: String.Index) -> (Character, String.Index)? {
143146
// FIXME: Sink into the stdlib to avoid multiple boundary calculations
144147
guard pos < end else { return nil }
145148
let next = index(pos, offsetBy: 1, limitedBy: end) ?? end
146-
return self[pos..<next].first.map { ($0, next) }
149+
// Substring will round down non-scalar aligned indices
150+
let substr = self[pos..<next]
151+
return substr.first.map { ($0, substr.endIndex) }
147152
}
148153

149154
func matchAnyNonNewline(

0 commit comments

Comments
 (0)