Skip to content

Commit 99b21ef

Browse files
lorenteymilseman
authored andcommitted
FixedArray: Implement append & working count
1 parent bbb4fd5 commit 99b21ef

File tree

3 files changed

+78
-46
lines changed

3 files changed

+78
-46
lines changed

stdlib/public/core/FixedArray.swift.gyb

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,29 @@ internal struct _FixedArray${N}<T> {
3737
)
3838

3939
@_versioned // FIXME(sil-serialize-all)
40-
internal static var _arraySize : Int { return ${N} }
40+
var _count: Int8
41+
}
42+
43+
44+
extension _FixedArray${N} {
45+
@_inlineable // FIXME(sil-serialize-all)
46+
@_versioned // FIXME(sil-serialize-all)
47+
internal static var capacity: Int {
48+
@inline(__always) get { return ${N} }
49+
}
50+
51+
@_inlineable // FIXME(sil-serialize-all)
52+
@_versioned // FIXME(sil-serialize-all)
53+
internal var capacity: Int {
54+
@inline(__always) get { return ${N} }
55+
}
56+
57+
@_inlineable // FIXME(sil-serialize-all)
58+
@_versioned // FIXME(sil-serialize-all)
59+
internal var count : Int {
60+
@inline(__always) get { return Int(truncatingIfNeeded: _count) }
61+
@inline(__always) set { _count = Int8(newValue) }
62+
}
4163
}
4264

4365
extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
@@ -52,18 +74,17 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
5274
@_inlineable // FIXME(sil-serialize-all)
5375
@_versioned // FIXME(sil-serialize-all)
5476
internal var endIndex : Index {
55-
return _FixedArray${N}._arraySize
77+
return count
5678
}
5779

58-
@_versioned // FIXME(sil-serialize-all)
59-
internal var count : Int { return _FixedArray${N}._arraySize }
60-
6180
@_inlineable // FIXME(sil-serialize-all)
6281
@_versioned // FIXME(sil-serialize-all)
6382
internal subscript(i: Index) -> T {
6483
@_versioned
6584
@inline(__always)
6685
get {
86+
let count = self.count // for exclusive access
87+
_sanityCheck(i >= 0 && i < count)
6788
var copy = storage
6889
let res: T = withUnsafeBytes(of: &copy) {
6990
(rawPtr : UnsafeRawBufferPointer) -> T in
@@ -79,16 +100,9 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
79100
@_versioned
80101
@inline(__always)
81102
set {
82-
let count = self.count
83-
withUnsafeBytes(of: &storage) {
84-
(rawPtr : UnsafeRawBufferPointer) -> () in
85-
let rawPtr = UnsafeMutableRawBufferPointer(mutating: rawPtr)
86-
let stride = MemoryLayout<T>.stride
87-
_sanityCheck(rawPtr.count == ${N}*stride, "layout mismatch?")
88-
let bufPtr = UnsafeMutableBufferPointer(
89-
start: rawPtr.baseAddress!.assumingMemoryBound(to: T.self),
90-
count: count)
91-
bufPtr[i] = newValue
103+
_sanityCheck(i >= 0 && i < count)
104+
self.withUnsafeMutableBufferPointer { buffer in
105+
buffer[i] = newValue
92106
}
93107
}
94108
}
@@ -106,22 +120,45 @@ extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
106120
internal func index(before i: Index) -> Index {
107121
return i-1
108122
}
123+
}
109124

110-
// TODO: Any customization hooks it's profitable to override, e.g. append?
111-
125+
extension _FixedArray${N} {
126+
@_inlineable // FIXME(sil-serialize-all)
127+
@_versioned
128+
internal mutating func append(_ newElement: T) {
129+
_sanityCheck(count < capacity)
130+
self[count] = newElement
131+
_count += 1
132+
}
112133
}
113134

114135
extension _FixedArray${N} where T : ExpressibleByIntegerLiteral {
115136
@_inlineable // FIXME(sil-serialize-all)
116137
@_versioned // FIXME(sil-serialize-all)
117138
@inline(__always)
118-
internal init(allZeros: ()) {
139+
internal init(count: Int) {
140+
_sanityCheck(count >= 0 && count <= _FixedArray${N}.capacity)
119141
self.storage = (
120142
% for i in range(0, N-1):
121143
0,
122144
% end
123145
0
124146
)
147+
self._count = Int8(truncatingIfNeeded: count)
148+
}
149+
150+
@_inlineable // FIXME(sil-serialize-all)
151+
@_versioned // FIXME(sil-serialize-all)
152+
@inline(__always)
153+
internal init() {
154+
self.init(count: 0)
155+
}
156+
157+
@_inlineable // FIXME(sil-serialize-all)
158+
@_versioned // FIXME(sil-serialize-all)
159+
@inline(__always)
160+
internal init(allZeros: ()) {
161+
self.init(count: ${N})
125162
}
126163
}
127164

@@ -131,8 +168,10 @@ extension _FixedArray${N} {
131168
internal mutating func withUnsafeMutableBufferPointer<R>(
132169
_ body: (UnsafeMutableBufferPointer<Element>) throws -> R
133170
) rethrows -> R {
134-
let count = self.count
171+
let count = self.count // for exclusive access
135172
return try withUnsafeMutableBytes(of: &storage) { rawBuffer in
173+
_sanityCheck(rawBuffer.count == ${N}*MemoryLayout<T>.stride,
174+
"layout mismatch?")
136175
let buffer = UnsafeMutableBufferPointer<Element>(
137176
start: rawBuffer.baseAddress._unsafelyUnwrappedUnchecked
138177
.assumingMemoryBound(to: Element.self),
@@ -146,8 +185,10 @@ extension _FixedArray${N} {
146185
internal mutating func withUnsafeBufferPointer<R>(
147186
_ body: (UnsafeBufferPointer<Element>) throws -> R
148187
) rethrows -> R {
149-
let count = self.count
188+
let count = self.count // for exclusive access
150189
return try withUnsafeBytes(of: &storage) { rawBuffer in
190+
_sanityCheck(rawBuffer.count == ${N}*MemoryLayout<T>.stride,
191+
"layout mismatch?")
151192
let buffer = UnsafeBufferPointer<Element>(
152193
start: rawBuffer.baseAddress._unsafelyUnwrappedUnchecked
153194
.assumingMemoryBound(to: Element.self),

stdlib/public/core/StringGraphemeBreaking.swift

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,15 @@ extension _UnmanagedOpaqueString {
273273

274274
// Pull out some code units into a fixed array and try to perform grapheme
275275
// breaking on that.
276-
var shortBuffer = _FixedArray16<UInt16>(allZeros:())
277-
let maxShortCount = shortBuffer.count
278-
let shortCount = Swift.min(maxShortCount, count)
276+
typealias ShortBuffer = _FixedArray16<UInt16>
277+
var shortBuffer = ShortBuffer(count: Swift.min(ShortBuffer.capacity, count))
279278
shortBuffer.withUnsafeMutableBufferPointer { buffer in
280-
self.prefix(shortCount)._copy(into: buffer)
279+
self.prefix(buffer.count)._copy(into: buffer)
281280
}
282281
let shortLength = shortBuffer.withUnsafeBufferPointer { buffer in
283-
UTF16._measureFirstExtendedGraphemeCluster(
284-
in: UnsafeBufferPointer(rebasing: buffer.prefix(shortCount)))
282+
UTF16._measureFirstExtendedGraphemeCluster(in: buffer)
285283
}
286-
if _fastPath(shortLength < maxShortCount) {
284+
if _fastPath(shortLength < shortBuffer.capacity) {
287285
return shortLength
288286
}
289287

@@ -302,17 +300,15 @@ extension _UnmanagedOpaqueString {
302300

303301
// Pull out some code units into a fixed array and try to perform grapheme
304302
// breaking on that.
305-
var shortBuffer = _FixedArray16<UInt16>(allZeros:())
306-
let maxShortCount = shortBuffer.count
307-
let shortCount = Swift.min(maxShortCount, count)
303+
typealias ShortBuffer = _FixedArray16<UInt16>
304+
var shortBuffer = ShortBuffer(count: Swift.min(ShortBuffer.capacity, count))
308305
shortBuffer.withUnsafeMutableBufferPointer { buffer in
309-
self.suffix(shortCount)._copy(into: buffer)
306+
self.suffix(buffer.count)._copy(into: buffer)
310307
}
311308
let shortLength = shortBuffer.withUnsafeBufferPointer { buffer in
312-
UTF16._measureLastExtendedGraphemeCluster(
313-
in: UnsafeBufferPointer(rebasing: buffer.prefix(shortCount)))
309+
UTF16._measureLastExtendedGraphemeCluster(in: buffer)
314310
}
315-
if _fastPath(shortLength < maxShortCount) {
311+
if _fastPath(shortLength < shortBuffer.capacity) {
316312
return shortLength
317313
}
318314

stdlib/public/core/UnmanagedOpaqueString.swift

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,11 @@ extension _UnmanagedOpaqueString : Sequence {
7373
internal var _nextIndex: Int
7474

7575
@_versioned
76-
internal var _buffer = _FixedArray16<Element>(allZeros: ())
76+
internal var _buffer = _FixedArray16<Element>()
7777

7878
@_versioned
7979
internal var _bufferIndex: Int8 = 0
8080

81-
@_versioned
82-
internal var _bufferCount: Int8 = 0
83-
8481
@_inlineable
8582
@_versioned
8683
init(_ string: _UnmanagedOpaqueString, startingAt start: Int) {
@@ -93,7 +90,7 @@ extension _UnmanagedOpaqueString : Sequence {
9390
@_versioned
9491
@inline(__always)
9592
mutating func next() -> Element? {
96-
if _fastPath(_bufferIndex < _bufferCount) {
93+
if _fastPath(_bufferIndex < _buffer.count) {
9794
let result = _buffer[Int(_bufferIndex)]
9895
_bufferIndex += 1
9996
return result
@@ -106,20 +103,18 @@ extension _UnmanagedOpaqueString : Sequence {
106103
@_versioned
107104
mutating func _nextOnSlowPath() -> Element {
108105
// Fill buffer
109-
_sanityCheck(Element.self == UTF16.CodeUnit.self)
110106
_sanityCheck(_nextIndex < _endIndex)
111-
let capacity = _buffer.count
112-
let end = Swift.min(_nextIndex + capacity, _endIndex)
107+
let end = Swift.min(_nextIndex + _buffer.capacity, _endIndex)
113108
unowned(unsafe) let object = _object
114-
withUnsafeMutableBytes(of: &_buffer.storage) { b in
115-
_sanityCheck(b.count == MemoryLayout<Element>.stride * capacity)
109+
_buffer.count = end - _nextIndex
110+
_buffer.withUnsafeMutableBufferPointer { b in
111+
_sanityCheck(b.count == end - _nextIndex)
116112
_cocoaStringCopyCharacters(
117113
from: object,
118114
range: _nextIndex..<end,
119-
into: b.baseAddress!.assumingMemoryBound(to: UTF16.CodeUnit.self))
115+
into: b.baseAddress!)
120116
}
121117
_bufferIndex = 1
122-
_bufferCount = Int8(end - _nextIndex)
123118
_nextIndex = end
124119
_fixLifetime(_object)
125120
return _buffer[0]

0 commit comments

Comments
 (0)