Skip to content

Commit ece9c49

Browse files
committed
Merge pull request #2550 from moiseev/utf8-index-after
2 parents b4c7c1f + f582faa commit ece9c49

File tree

1 file changed

+31
-39
lines changed

1 file changed

+31
-39
lines changed

stdlib/public/core/StringUTF8.swift

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -130,43 +130,6 @@ extension String {
130130
_sanityCheck(_coreIndex <= _core.count)
131131
}
132132

133-
/// Returns the next consecutive value after `self`.
134-
///
135-
/// - Precondition: The next value is representable.
136-
@warn_unused_result
137-
internal func _successor() -> Index {
138-
// FIXME: swift-3-indexing-model: pull the following logic into UTF8View.index(after: Index)
139-
// FIXME: swift-3-indexing-model: remove the _successor() function.
140-
let currentUnit = UTF8.CodeUnit(truncatingBitPattern: _buffer)
141-
let hiNibble = currentUnit >> 4
142-
// Map the high nibble of the current code unit into the
143-
// amount by which to increment the UTF-16 index. Only when
144-
// the high nibble is 1111 do we have a surrogate pair.
145-
let u16Increments = Int(bitPattern:
146-
// 1111 1110 1101 1100 1011 1010 1001 1000 0111 0110 0101 0100 0011 0010 0001 0000
147-
0b10___01___01___01___00___00___00___00___01___01___01___01___01___01___01___01)
148-
let increment = (u16Increments >> numericCast(hiNibble << 1)) & 0x3
149-
let nextCoreIndex = _coreIndex &+ increment
150-
let nextBuffer = Index._nextBuffer(after: _buffer)
151-
152-
// if the nextBuffer is non-empty, we have all we need
153-
if _fastPath(nextBuffer != Index._emptyBuffer) {
154-
return Index(_core, nextCoreIndex, nextBuffer)
155-
}
156-
// If the underlying UTF16 isn't exhausted, fill a new buffer
157-
else if _fastPath(nextCoreIndex < _core.endIndex) {
158-
let (_, freshBuffer) = _core._encodeSomeUTF8(from: nextCoreIndex)
159-
return Index(_core, nextCoreIndex, freshBuffer)
160-
}
161-
else {
162-
// Produce the endIndex
163-
_precondition(
164-
nextCoreIndex == _core.endIndex,
165-
"Can't increment past endIndex of String.UTF8View")
166-
return Index(_core, nextCoreIndex, nextBuffer)
167-
}
168-
}
169-
170133
/// True iff the index is at the end of its view or if the next
171134
/// byte begins a new UnicodeScalar.
172135
internal var _isOnUnicodeScalarBoundary : Bool {
@@ -224,11 +187,40 @@ extension String {
224187
return self._endIndex
225188
}
226189

227-
// TODO: swift-3-indexing-model - add docs
190+
/// Returns the next consecutive position after `i`.
191+
///
192+
/// - Precondition: The next position is representable.
228193
@warn_unused_result
229194
public func index(after i: Index) -> Index {
230195
// FIXME: swift-3-indexing-model: range check i?
231-
return i._successor()
196+
let currentUnit = UTF8.CodeUnit(truncatingBitPattern: i._buffer)
197+
let hiNibble = currentUnit >> 4
198+
// Map the high nibble of the current code unit into the
199+
// amount by which to increment the UTF-16 index. Only when
200+
// the high nibble is 1111 do we have a surrogate pair.
201+
let u16Increments = Int(bitPattern:
202+
// 1111 1110 1101 1100 1011 1010 1001 1000 0111 0110 0101 0100 0011 0010 0001 0000
203+
0b10___01___01___01___00___00___00___00___01___01___01___01___01___01___01___01)
204+
let increment = (u16Increments >> numericCast(hiNibble << 1)) & 0x3
205+
let nextCoreIndex = i._coreIndex &+ increment
206+
let nextBuffer = Index._nextBuffer(after: i._buffer)
207+
208+
// if the nextBuffer is non-empty, we have all we need
209+
if _fastPath(nextBuffer != Index._emptyBuffer) {
210+
return Index(i._core, nextCoreIndex, nextBuffer)
211+
}
212+
// If the underlying UTF16 isn't exhausted, fill a new buffer
213+
else if _fastPath(nextCoreIndex < i._core.endIndex) {
214+
let (_, freshBuffer) = i._core._encodeSomeUTF8(from: nextCoreIndex)
215+
return Index(_core, nextCoreIndex, freshBuffer)
216+
}
217+
else {
218+
// Produce the endIndex
219+
_precondition(
220+
nextCoreIndex == i._core.endIndex,
221+
"Can't increment past endIndex of String.UTF8View")
222+
return Index(_core, nextCoreIndex, nextBuffer)
223+
}
232224
}
233225

234226
/// Access the element at `position`.

0 commit comments

Comments
 (0)