Skip to content

Commit 8b9cc18

Browse files
authored
Merge pull request #20621 from milseman/unsafe_unchecked_buffer_pointer
[stdlib] Unchecked subscript on UnsafeBufferPointer
2 parents 9031865 + 3a0ac02 commit 8b9cc18

8 files changed

+38
-15
lines changed

stdlib/public/core/FixedArray.swift.gyb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
7474
let bufPtr = UnsafeBufferPointer(
7575
start: rawPtr.baseAddress!.assumingMemoryBound(to: T.self),
7676
count: count)
77-
return bufPtr[i]
77+
return bufPtr[_unchecked: i]
7878
}
7979
return res
8080
}
8181
@inline(__always)
8282
set {
8383
_internalInvariant(i >= 0 && i < count)
8484
self.withUnsafeMutableBufferPointer { buffer in
85-
buffer[i] = newValue
85+
buffer[_unchecked: i] = newValue
8686
}
8787
}
8888
}

stdlib/public/core/NormalizedCodeUnitIterator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ extension UnsafeBufferPointer where Element == UInt8 {
132132
return true
133133
}
134134

135-
assert(!_isContinuation(self[index]))
135+
assert(!_isContinuation(self[_unchecked: index]))
136136

137137
let cu = _decodeScalar(self, startingAt: index).0
138138
return cu._hasNormalizationBoundaryBefore

stdlib/public/core/SmallBuffer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extension _SmallBuffer {
5151
let rawPtr = $0.baseAddress._unsafelyUnwrappedUnchecked
5252
let bufPtr = UnsafeBufferPointer(
5353
start: rawPtr.assumingMemoryBound(to: T.self), count: capacity)
54-
return bufPtr[i]
54+
return bufPtr[_unchecked: i]
5555
}
5656
}
5757
set {
@@ -61,7 +61,7 @@ extension _SmallBuffer {
6161
let rawPtr = $0.baseAddress._unsafelyUnwrappedUnchecked
6262
let bufPtr = UnsafeMutableBufferPointer(
6363
start: rawPtr.assumingMemoryBound(to: T.self), count: capacity)
64-
bufPtr[i] = newValue
64+
bufPtr[_unchecked: i] = newValue
6565
}
6666
}
6767
}

stdlib/public/core/StringComparison.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ internal func _stringCompare(
124124

125125
// Back up to nearest scalar boundary and check if normal and end of segment.
126126
// If so, we have our answer.
127-
while _isContinuation(left[idx]) && idx > 0 { idx &-= 1 }
127+
while _isContinuation(left[_unchecked: idx]) && idx > 0 { idx &-= 1 }
128128

129129
// TODO: Refactor this into a function, handle these boundary condition as
130130
// early returns...
131-
if !_isContinuation(right[idx]) {
131+
if !_isContinuation(right[_unchecked: idx]) {
132132
let (leftScalar, leftLen) = _decodeScalar(left, startingAt: idx)
133133
let (rightScalar, rightLen) = _decodeScalar(right, startingAt: idx)
134134
_internalInvariant(leftScalar != rightScalar)

stdlib/public/core/StringUTF16View.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ extension String.UTF16View {
510510
}
511511

512512
while true {
513-
let len = _utf8ScalarLength(utf8[readIdx])
513+
let len = _utf8ScalarLength(utf8[_unchecked: readIdx])
514514
let utf16Len = len == 4 ? 2 : 1
515515
utf16I &+= utf16Len
516516

stdlib/public/core/StringUTF8View.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ extension String.UTF8View: BidirectionalCollection {
214214
@inline(__always) get {
215215
String(_guts)._boundsCheck(i)
216216
if _fastPath(_guts.isFastUTF8) {
217-
return _guts.withFastUTF8 { utf8 in utf8[i.encodedOffset] }
217+
return _guts.withFastUTF8 { utf8 in utf8[_unchecked: i.encodedOffset] }
218218
}
219219

220220
return _foreignSubscript(position: i)

stdlib/public/core/UnicodeHelpers.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,20 @@ internal func _decodeUTF8(
8888
internal func _decodeScalar(
8989
_ utf8: UnsafeBufferPointer<UInt8>, startingAt i: Int
9090
) -> (Unicode.Scalar, scalarLength: Int) {
91-
let cu0 = utf8[i]
91+
let cu0 = utf8[_unchecked: i]
9292
let len = _utf8ScalarLength(cu0)
9393
switch len {
9494
case 1: return (_decodeUTF8(cu0), len)
95-
case 2: return (_decodeUTF8(cu0, utf8[i &+ 1]), len)
96-
case 3: return (_decodeUTF8(cu0, utf8[i &+ 1], utf8[i &+ 2]), len)
95+
case 2: return (_decodeUTF8(cu0, utf8[_unchecked: i &+ 1]), len)
96+
case 3: return (_decodeUTF8(
97+
cu0, utf8[_unchecked: i &+ 1], utf8[_unchecked: i &+ 2]), len)
9798
case 4:
98-
return (_decodeUTF8(cu0, utf8[i &+ 1], utf8[i &+ 2], utf8[i &+ 3]), len)
99+
return (_decodeUTF8(
100+
cu0,
101+
utf8[_unchecked: i &+ 1],
102+
utf8[_unchecked: i &+ 2],
103+
utf8[_unchecked: i &+ 3]),
104+
len)
99105
default: Builtin.unreachable()
100106
}
101107
}
@@ -123,7 +129,7 @@ internal func _utf8ScalarLength(
123129
_ utf8: UnsafeBufferPointer<UInt8>, endingAt i: Int
124130
) -> Int {
125131
var len = 1
126-
while _isContinuation(utf8[i &- len]) {
132+
while _isContinuation(utf8[_unchecked: i &- len]) {
127133
len += 1
128134
}
129135
_internalInvariant(len == _utf8ScalarLength(utf8[i &- len]))
@@ -187,7 +193,7 @@ extension _StringGuts {
187193

188194
return self.withFastUTF8 { utf8 in
189195
var i = idx.encodedOffset
190-
while _slowPath(_isContinuation(utf8[i])) {
196+
while _slowPath(_isContinuation(utf8[_unchecked: i])) {
191197
i -= 1
192198
_internalInvariant(
193199
i >= 0, "Malformed contents: starts with continuation byte")

stdlib/public/core/UnsafeBufferPointer.swift.gyb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,23 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
281281
%end
282282
}
283283

284+
// Skip all debug and runtime checks
285+
@inlinable // unsafe-performance
286+
internal subscript(_unchecked i: Int) -> Element {
287+
get {
288+
_internalInvariant(i >= 0)
289+
_internalInvariant(i < endIndex)
290+
return _position._unsafelyUnwrappedUnchecked[i]
291+
}
292+
%if Mutable:
293+
nonmutating _modify {
294+
_internalInvariant(i >= 0)
295+
_internalInvariant(i < endIndex)
296+
yield &_position._unsafelyUnwrappedUnchecked[i]
297+
}
298+
%end
299+
}
300+
284301
/// Accesses a contiguous subrange of the buffer's elements.
285302
///
286303
/// The accessed slice uses the same indices for the same elements as the

0 commit comments

Comments
 (0)