@@ -58,7 +58,7 @@ extension _StringGuts {
58
58
internal init ( _initialCapacity capacity: Int ) {
59
59
self . init ( )
60
60
if _slowPath ( capacity > _SmallString. capacity) {
61
- self . grow ( capacity)
61
+ self . grow ( capacity) // TODO: no factor should be applied
62
62
}
63
63
}
64
64
@@ -68,7 +68,7 @@ extension _StringGuts {
68
68
if let currentCap = self . uniqueNativeCapacity, currentCap >= n { return }
69
69
70
70
// Grow
71
- self . grow ( n)
71
+ self . grow ( n) // TODO: no factor should be applied
72
72
}
73
73
74
74
// Grow to accomodate at least `n` code units
@@ -128,11 +128,11 @@ extension _StringGuts {
128
128
} else {
129
129
sufficientCapacity = false
130
130
}
131
-
131
+
132
132
if self . isUniqueNative && sufficientCapacity {
133
133
return
134
134
}
135
-
135
+
136
136
// If we have to resize anyway, and we fit in smol, we should have made one
137
137
_internalInvariant ( totalCount > _SmallString. capacity)
138
138
@@ -145,7 +145,7 @@ extension _StringGuts {
145
145
growthTarget = Swift . max (
146
146
totalCount, _growArrayCapacity ( nativeCapacity ?? 0 ) )
147
147
}
148
- self . grow ( growthTarget)
148
+ self . grow ( growthTarget) // NOTE: this already has exponential growth...
149
149
}
150
150
151
151
internal mutating func append( _ other: _StringGuts ) {
@@ -157,7 +157,7 @@ extension _StringGuts {
157
157
}
158
158
append ( _StringGutsSlice ( other) )
159
159
}
160
-
160
+
161
161
@inline ( never)
162
162
@_effects ( readonly)
163
163
private func _foreignConvertedToSmall( ) -> _SmallString {
@@ -170,7 +170,7 @@ extension _StringGuts {
170
170
_internalInvariant ( smol. _guts. isSmall)
171
171
return smol. _guts. asSmall
172
172
}
173
-
173
+
174
174
private func _convertedToSmall( ) -> _SmallString {
175
175
_internalInvariant ( utf8Count <= _SmallString. capacity)
176
176
if _fastPath ( isSmall) {
@@ -186,25 +186,25 @@ extension _StringGuts {
186
186
defer { self . _invariantCheck ( ) }
187
187
188
188
let otherCount = slicedOther. utf8Count
189
-
189
+
190
190
let totalCount = utf8Count + otherCount
191
-
191
+
192
192
/*
193
193
Goal: determine if we need to allocate new native capacity
194
194
Possible scenarios in which we need to allocate:
195
195
• Not uniquely owned and native: we can't use the capacity to grow into,
196
196
have to become unique + native by allocating
197
197
• Not enough capacity: have to allocate to grow
198
-
198
+
199
199
Special case: a non-smol String that can fit in a smol String but doesn't
200
200
meet the above criteria shouldn't throw away its buffer just to be smol.
201
201
The reasoning here is that it may be bridged or have reserveCapacity'd
202
202
in preparation for appending more later, in which case we would end up
203
203
have to allocate anyway to convert back from smol.
204
-
204
+
205
205
If we would have to re-allocate anyway then that's not a problem and we
206
206
should just be smol.
207
-
207
+
208
208
e.g. consider
209
209
var str = "" // smol
210
210
str.reserveCapacity(100) // large native unique
@@ -215,15 +215,15 @@ extension _StringGuts {
215
215
nativeUnusedCapacity! >= otherCount
216
216
let shouldBeSmol = totalCount <= _SmallString. capacity &&
217
217
( isSmall || !hasEnoughUsableSpace)
218
-
218
+
219
219
if shouldBeSmol {
220
220
let smolSelf = _convertedToSmall ( )
221
221
let smolOther = String ( Substring ( slicedOther) ) . _guts. _convertedToSmall ( )
222
222
// TODO: In-register slicing
223
223
self = _StringGuts ( _SmallString ( smolSelf, appending: smolOther) !)
224
224
return
225
225
}
226
-
226
+
227
227
prepareForAppendInPlace ( totalCount: totalCount, otherUTF8Count: otherCount)
228
228
229
229
if slicedOther. isFastUTF8 {
0 commit comments