@@ -47,19 +47,6 @@ public struct OutputSpan<Element: ~Copyable>: ~Copyable, ~Escapable {
47
47
capacity = 0
48
48
_count = 0
49
49
}
50
-
51
- @unsafe
52
- @_alwaysEmitIntoClient
53
- @lifetime ( borrow start)
54
- public init (
55
- _uncheckedStart start: UnsafeMutableRawPointer ? ,
56
- capacity: Int ,
57
- initializedCount: Int
58
- ) {
59
- unsafe _pointer = start
60
- self . capacity = capacity
61
- _count = initializedCount
62
- }
63
50
}
64
51
65
52
@available ( SwiftStdlib 6 . 2 , * )
@@ -68,6 +55,8 @@ extension OutputSpan: @unchecked Sendable where Element: Sendable & ~Copyable {}
68
55
@available ( SwiftStdlib 6 . 2 , * )
69
56
extension OutputSpan where Element: ~ Copyable {
70
57
@_alwaysEmitIntoClient
58
+ @_transparent
59
+ @unsafe
71
60
internal func _start( ) -> UnsafeMutableRawPointer {
72
61
unsafe _pointer. _unsafelyUnwrappedUnchecked
73
62
}
@@ -79,16 +68,23 @@ extension OutputSpan where Element: ~Copyable {
79
68
// NOTE: `_pointer` must be known to be not-nil.
80
69
unsafe _start( ) . advanced ( by: _count &* MemoryLayout< Element> . stride)
81
70
}
71
+ }
82
72
73
+ @available ( SwiftStdlib 6 . 2 , * )
74
+ extension OutputSpan where Element: ~ Copyable {
75
+ /// The number of initialized elements in this span.
83
76
@_alwaysEmitIntoClient
84
- public var freeCapacity : Int { capacity &- _count }
77
+ public var count : Int { _count }
85
78
79
+ /// The number of additional elements that can be added to this span.
86
80
@_alwaysEmitIntoClient
87
- public var count : Int { _count }
81
+ public var freeCapacity : Int { capacity &- _count }
88
82
83
+ /// A Boolean value indicating whether the span is empty.
89
84
@_alwaysEmitIntoClient
90
85
public var isEmpty : Bool { _count == 0 }
91
86
87
+ /// A Boolean value indicating whether the span is full.
92
88
@_alwaysEmitIntoClient
93
89
public var isFull : Bool { _count == capacity }
94
90
}
@@ -99,7 +95,8 @@ extension OutputSpan where Element: ~Copyable {
99
95
@unsafe
100
96
@_alwaysEmitIntoClient
101
97
@lifetime ( borrow buffer)
102
- public init(
98
+ @usableFromInline
99
+ internal init(
103
100
_uncheckedBuffer buffer: UnsafeMutableBufferPointer < Element > ,
104
101
initializedCount: Int
105
102
) {
@@ -176,63 +173,66 @@ extension OutputSpan {
176
173
177
174
@available ( SwiftStdlib 6 . 2 , * )
178
175
extension OutputSpan where Element: ~ Copyable {
179
-
176
+ /// The type that represents an initialized position in an `OutputSpan`.
180
177
public typealias Index = Int
181
178
179
+ /// The range of initialized positions for this `OutputSpan`.
182
180
@_alwaysEmitIntoClient
183
181
public var indices : Range < Index > {
184
182
unsafe Range( _uncheckedBounds: ( 0 , _count) )
185
183
}
186
184
187
185
/// Accesses the element at the specified position.
188
186
///
189
- /// - Parameter position: The offset of the element to access. `position`
190
- /// must be greater or equal to zero, and less than `count`.
187
+ /// - Parameter index: A valid index into this span.
191
188
///
192
189
/// - Complexity: O(1)
193
190
@_alwaysEmitIntoClient
194
- public subscript( _ position : Index ) -> Element {
191
+ public subscript( _ index : Index ) -> Element {
195
192
unsafeAddress {
196
- _precondition ( indices. contains ( position ) , " index out of bounds " )
197
- return unsafe UnsafePointer( _unsafeAddressOfElement ( unchecked: position ) )
193
+ _precondition ( indices. contains ( index ) , " index out of bounds " )
194
+ return unsafe UnsafePointer( _unsafeAddressOfElement ( unchecked: index ) )
198
195
}
199
196
@lifetime ( self : copy self )
200
197
unsafeMutableAddress {
201
- _precondition ( indices. contains ( position ) , " index out of bounds " )
202
- return unsafe _unsafeAddressOfElement( unchecked: position )
198
+ _precondition ( indices. contains ( index ) , " index out of bounds " )
199
+ return unsafe _unsafeAddressOfElement( unchecked: index )
203
200
}
204
201
}
205
202
206
203
/// Accesses the element at the specified position.
207
204
///
208
205
/// This subscript does not validate `position`; this is an unsafe operation.
209
206
///
210
- /// - Parameter position: The offset of the element to access. `position`
211
- /// must be greater or equal to zero, and less than `count`.
207
+ /// - Parameter index: A valid index into this span.
212
208
///
213
209
/// - Complexity: O(1)
214
210
@unsafe
215
211
@_alwaysEmitIntoClient
216
- public subscript( unchecked position : Index ) -> Element {
212
+ public subscript( unchecked index : Index ) -> Element {
217
213
unsafeAddress {
218
- unsafe UnsafePointer( _unsafeAddressOfElement ( unchecked: position ) )
214
+ unsafe UnsafePointer( _unsafeAddressOfElement ( unchecked: index ) )
219
215
}
220
216
@lifetime ( self : copy self )
221
217
unsafeMutableAddress {
222
- unsafe _unsafeAddressOfElement( unchecked: position )
218
+ unsafe _unsafeAddressOfElement( unchecked: index )
223
219
}
224
220
}
225
221
226
222
@unsafe
227
223
@_alwaysEmitIntoClient
228
224
internal func _unsafeAddressOfElement(
229
- unchecked position : Index
225
+ unchecked index : Index
230
226
) -> UnsafeMutablePointer < Element > {
231
- let elementOffset = position &* MemoryLayout< Element> . stride
227
+ let elementOffset = index &* MemoryLayout< Element> . stride
232
228
let address = unsafe _start( ) . advanced ( by: elementOffset)
233
229
return unsafe address. assumingMemoryBound ( to: Element . self)
234
230
}
235
231
232
+ /// Exchange the elements at the two given offsets
233
+ ///
234
+ /// - Parameter i: A valid index into this span.
235
+ /// - Parameter j: A valid index into this span.
236
236
@_alwaysEmitIntoClient
237
237
@lifetime ( self : copy self )
238
238
public mutating func swapAt( _ i: Index , _ j: Index ) {
@@ -241,6 +241,12 @@ extension OutputSpan where Element: ~Copyable {
241
241
unsafe swapAt( unchecked: i, unchecked: j)
242
242
}
243
243
244
+ /// Exchange the elements at the two given offsets
245
+ ///
246
+ /// This subscript does not validate `i` or `j`; this is an unsafe operation.
247
+ ///
248
+ /// - Parameter i: A valid index into this span.
249
+ /// - Parameter j: A valid index into this span.
244
250
@unsafe
245
251
@_alwaysEmitIntoClient
246
252
@lifetime ( self : copy self )
@@ -255,7 +261,7 @@ extension OutputSpan where Element: ~Copyable {
255
261
256
262
@available ( SwiftStdlib 6 . 2 , * )
257
263
extension OutputSpan where Element: ~ Copyable {
258
-
264
+ /// Append a single element to this span.
259
265
@_alwaysEmitIntoClient
260
266
@lifetime ( self: copy self)
261
267
public mutating func append( _ value: consuming Element ) {
@@ -264,6 +270,9 @@ extension OutputSpan where Element: ~Copyable {
264
270
_count &+= 1
265
271
}
266
272
273
+ /// Remove the last initialized element from this span.
274
+ ///
275
+ /// Returns the last element. The `OutputSpan` must not be empty.
267
276
@_alwaysEmitIntoClient
268
277
@lifetime ( self : copy self )
269
278
public mutating func removeLast( ) -> Element {
@@ -274,6 +283,10 @@ extension OutputSpan where Element: ~Copyable {
274
283
}
275
284
}
276
285
286
+ /// Remove the last N elements of this span, returning the memory they occupy
287
+ /// to the uninitialized state.
288
+ ///
289
+ /// `n` must not be greater than `count`
277
290
@_alwaysEmitIntoClient
278
291
@lifetime ( self : copy self )
279
292
public mutating func removeLast( _ k: Int ) {
@@ -285,6 +298,8 @@ extension OutputSpan where Element: ~Copyable {
285
298
}
286
299
}
287
300
301
+ /// Remove all this span's elements and return its memory
302
+ /// to the uninitialized state.
288
303
@_alwaysEmitIntoClient
289
304
@lifetime ( self : copy self )
290
305
public mutating func removeAll( ) {
@@ -299,7 +314,7 @@ extension OutputSpan where Element: ~Copyable {
299
314
@available ( SwiftStdlib 6 . 2 , * )
300
315
extension OutputSpan {
301
316
302
- /// Initialize this span's suffix to the repetitions of the given value .
317
+ /// Repeatedly append an element to this span .
303
318
@_alwaysEmitIntoClient
304
319
@lifetime ( self : copy self )
305
320
public mutating func append( repeating repeatedValue: Element , count: Int ) {
@@ -309,137 +324,11 @@ extension OutputSpan {
309
324
)
310
325
_count &+= count
311
326
}
312
-
313
- /// Returns true if the iterator has filled all the free capacity in the span.
314
- @_alwaysEmitIntoClient
315
- @lifetime ( self : copy self )
316
- @discardableResult
317
- public mutating func append(
318
- from elements: inout some IteratorProtocol < Element >
319
- ) -> Bool {
320
- // FIXME: It may be best to delay this API until
321
- // we have designed a chunking IteratorProtocol
322
- var p = unsafe _tail( )
323
- while _count < capacity {
324
- guard let element = elements. next ( ) else { return false }
325
- unsafe p. initializeMemory ( as: Element . self, to: element)
326
- unsafe p = p. advanced ( by: MemoryLayout< Element> . stride)
327
- _count &+= 1
328
- }
329
- return true
330
- }
331
-
332
- @_alwaysEmitIntoClient
333
- @lifetime ( self : copy self )
334
- public mutating func append(
335
- contentsOf source: consuming some Sequence < Element >
336
- ) {
337
- let done : Void ? = source. withContiguousStorageIfAvailable {
338
- unsafe append( contentsOf: $0)
339
- }
340
- if done != nil {
341
- return
342
- }
343
-
344
- let freeCapacity = freeCapacity
345
- let tail = unsafe _tail( ) . _rawValue
346
- // rebind memory manually to get around closure issues
347
- // see https://github.com/swiftlang/swift/issues/81525
348
- let binding = Builtin . bindMemory (
349
- tail, freeCapacity. _builtinWordValue, Element . self
350
- )
351
- defer { Builtin . rebindMemory ( tail, binding) }
352
- let suffix = unsafe UnsafeMutableBufferPointer< Element > (
353
- start: . init( tail) , count: freeCapacity
354
- )
355
- var ( iterator, copied) = unsafe source. _copyContents ( initializing: suffix)
356
-
357
- _precondition ( iterator. next ( ) == nil , " OutputSpan capacity overflow " )
358
- _precondition ( _count + copied <= capacity, " Invalid Sequence._copyContents " )
359
- _count &+= copied
360
- }
361
-
362
- @_alwaysEmitIntoClient
363
- @lifetime ( self : copy self )
364
- public mutating func append(
365
- contentsOf source: UnsafeBufferPointer < Element >
366
- ) {
367
- guard !source. isEmpty else { return }
368
- _precondition ( source. count <= freeCapacity, " OutputSpan capacity overflow " )
369
- unsafe _tail( ) . initializeMemory (
370
- as: Element . self, from: source. baseAddress!, count: source. count)
371
- _count += source. count
372
- }
373
-
374
- @_alwaysEmitIntoClient
375
- @lifetime ( self : copy self )
376
- public mutating func append(
377
- copying source: borrowing Span < Element >
378
- ) {
379
- unsafe source. withUnsafeBufferPointer { unsafe append( contentsOf: $0) }
380
- }
381
- }
382
-
383
- @available ( SwiftStdlib 6 . 2 , * )
384
- extension OutputSpan where Element: ~ Copyable {
385
- /// Append to this output span by moving elements out of the given output
386
- /// span, leaving it empty. The elements are appended in the order they appear
387
- /// in the source.
388
- @_alwaysEmitIntoClient
389
- @lifetime ( self : copy self )
390
- public mutating func append(
391
- moving source: inout Self
392
- ) {
393
- guard !source. isEmpty else { return }
394
- unsafe source. withUnsafeMutableBufferPointer {
395
- unsafe self. append ( consuming: $0. extracting ( ..< $1) )
396
- $1 = 0
397
- }
398
- }
399
- }
400
-
401
- @available ( SwiftStdlib 6 . 2 , * )
402
- extension OutputSpan where Element: BitwiseCopyable {
403
- //FIXME: We need this for Element: ~Copyable
404
- @_alwaysEmitIntoClient
405
- @lifetime ( self : copy self )
406
- public mutating func append< let N: Int > (
407
- consuming source: consuming InlineArray < N , Element >
408
- ) {
409
- source. _consume { append ( moving: & $0) }
410
- }
411
- }
412
-
413
- @available ( SwiftStdlib 6 . 2 , * )
414
- extension OutputSpan where Element: ~ Copyable {
415
- @_alwaysEmitIntoClient
416
- @lifetime ( self: copy self)
417
- public mutating func append(
418
- consuming source: UnsafeMutableBufferPointer < Element >
419
- ) {
420
- guard !source. isEmpty else { return }
421
- _precondition ( source. count <= freeCapacity, " OutputSpan capacity overflow " )
422
- unsafe _tail( ) . moveInitializeMemory (
423
- as: Element . self, from: source. baseAddress!, count: source. count
424
- )
425
- _count += source. count
426
- }
427
- }
428
-
429
- @available ( SwiftStdlib 6 . 2 , * )
430
- extension OutputSpan {
431
- @_alwaysEmitIntoClient
432
- @lifetime ( self : copy self )
433
- public mutating func append(
434
- consuming source: Slice < UnsafeMutableBufferPointer < Element > >
435
- ) {
436
- unsafe append( consuming: UnsafeMutableBufferPointer ( rebasing: source) )
437
- }
438
327
}
439
328
440
329
@available ( SwiftStdlib 6 . 2 , * )
441
330
extension OutputSpan where Element: ~ Copyable {
442
-
331
+ /// Borrow the underlying initialized memory for read-only access.
443
332
@_alwaysEmitIntoClient
444
333
public var span : Span < Element > {
445
334
@lifetime ( borrow self)
@@ -451,6 +340,7 @@ extension OutputSpan where Element: ~Copyable {
451
340
}
452
341
}
453
342
343
+ /// Exclusively borrow the underlying initialized memory for mutation.
454
344
@_alwaysEmitIntoClient
455
345
public var mutableSpan : MutableSpan < Element > {
456
346
@lifetime ( & self )
@@ -526,8 +416,7 @@ extension OutputSpan where Element: ~Copyable {
526
416
527
417
@available ( SwiftStdlib 6 . 2 , * )
528
418
extension OutputSpan where Element: ~ Copyable {
529
- /// Consume the output span (relinquishing its control over the buffer it is
530
- /// addressing), and return the number of initialized elements in it.
419
+ /// Consume the output span and return the number of initialized elements.
531
420
///
532
421
/// This method should be invoked in the scope where the `OutputSpan` was
533
422
/// created, when it is time to commit the contents of the updated buffer
@@ -560,8 +449,7 @@ extension OutputSpan where Element: ~Copyable {
560
449
561
450
@available ( SwiftStdlib 6 . 2 , * )
562
451
extension OutputSpan {
563
- /// Consume the output span (relinquishing its control over the buffer it is
564
- /// addressing), and return the number of initialized elements in it.
452
+ /// Consume the output span and return the number of initialized elements.
565
453
///
566
454
/// This method should be invoked in the scope where the `OutputSpan` was
567
455
/// created, when it is time to commit the contents of the updated buffer
0 commit comments