10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
- // A RawSpan represents a span of initialized memory
14
- // of unspecified type.
13
+ /// `RawSpan` represents a contiguous region of memory
14
+ /// which contains initialized bytes.
15
+ ///
16
+ /// A `RawSpan` instance is a non-owning, non-escaping view into memory.
17
+ /// When a `RawSpan` is created, it inherits the lifetime of the container
18
+ /// owning the contiguous memory, ensuring temporal safety and avoiding
19
+ /// use-after-free errors. Operations on `RawSpan` are bounds-checked,
20
+ /// ensuring spcial safety and avoiding buffer overflow errors.
15
21
@_disallowFeatureSuppression ( NonescapableTypes)
16
22
@available ( SwiftStdlib 6 . 1 , * )
17
23
@frozen
18
24
public struct RawSpan : ~ Escapable, Copyable, BitwiseCopyable {
19
- @usableFromInline internal let _pointer : UnsafeRawPointer ?
25
+
26
+ /// The starting address of this `RawSpan`.
27
+ ///
28
+ /// `_pointer` can be `nil` if and only if `_count` equals 0.
29
+ /// Otherwise, `_pointer` must point to memory that will remain
30
+ /// valid and not mutated as long as this `Span` exists.
31
+ /// The memory at `_pointer` must consist of `_count` initialized bytes.
32
+ @usableFromInline
33
+ internal let _pointer : UnsafeRawPointer ?
20
34
21
35
@_alwaysEmitIntoClient
22
36
internal func _start( ) -> UnsafeRawPointer {
23
37
_pointer. _unsafelyUnwrappedUnchecked
24
38
}
25
39
26
- @usableFromInline internal let _count : Int
40
+ /// The number of bytes in this `RawSpan`.
41
+ ///
42
+ /// If `_count` equals 0, then `_pointer` may be either `nil` or valid.
43
+ /// Any `_count` greater than 0 indicates a valid non-nil `_pointer`.
44
+ /// Any `_count` less than 0 is invalid and is undefined behaviour.
45
+ @usableFromInline
46
+ internal let _count : Int
27
47
48
+ /// Unsafely create a `RawSpan` over initialized memory.
49
+ ///
50
+ /// `pointer` must point to a region of `byteCount` initialized bytes,
51
+ /// or may be `nil` if `count` is 0.
52
+ ///
53
+ /// The region of `byteCount` bytes of memory starting at `pointer`
54
+ /// must remain valid, initialized and immutable
55
+ /// throughout the lifetime of the newly-created `Span`.
56
+ /// Failure to maintain this invariant results in undefined behaviour.
57
+ ///
58
+ /// - Parameters:
59
+ /// - pointer: a pointer to the first initialized byte.
60
+ /// - byteCount: the number of initialized bytes in the span.
28
61
@_disallowFeatureSuppression ( NonescapableTypes)
29
62
@_alwaysEmitIntoClient
63
+ @inline ( __always)
30
64
//FIXME: should be @lifetime(borrow pointer) rdar://138672380
31
65
@lifetime ( immortal)
32
66
internal init (
@@ -298,11 +332,12 @@ extension RawSpan {
298
332
/// - Complexity: O(1)
299
333
@_disallowFeatureSuppression ( NonescapableTypes)
300
334
@_alwaysEmitIntoClient
335
+ @lifetime ( self )
301
336
public func _extracting( _ bounds: Range < Int > ) -> Self {
302
337
_precondition (
303
338
UInt ( bitPattern: bounds. lowerBound) <= UInt ( bitPattern: _count) &&
304
339
UInt ( bitPattern: bounds. upperBound) <= UInt ( bitPattern: _count) ,
305
- " byte offset range out of bounds"
340
+ " Byte offset range out of bounds"
306
341
)
307
342
return _extracting ( unchecked: bounds)
308
343
}
@@ -325,6 +360,7 @@ extension RawSpan {
325
360
@_disallowFeatureSuppression ( NonescapableTypes)
326
361
@unsafe
327
362
@_alwaysEmitIntoClient
363
+ @lifetime ( self )
328
364
public func _extracting( unchecked bounds: Range < Int > ) -> Self {
329
365
RawSpan (
330
366
_unchecked: _pointer? . advanced ( by: bounds. lowerBound) ,
@@ -347,6 +383,7 @@ extension RawSpan {
347
383
/// - Complexity: O(1)
348
384
@_disallowFeatureSuppression ( NonescapableTypes)
349
385
@_alwaysEmitIntoClient
386
+ @lifetime ( self )
350
387
public func _extracting( _ bounds: some RangeExpression < Int > ) -> Self {
351
388
_extracting ( bounds. relative ( to: byteOffsets) )
352
389
}
@@ -369,6 +406,7 @@ extension RawSpan {
369
406
@_disallowFeatureSuppression ( NonescapableTypes)
370
407
@unsafe
371
408
@_alwaysEmitIntoClient
409
+ @lifetime ( self )
372
410
public func _extracting(
373
411
unchecked bounds: some RangeExpression < Int >
374
412
) -> Self {
@@ -386,6 +424,7 @@ extension RawSpan {
386
424
/// - Complexity: O(1)
387
425
@_disallowFeatureSuppression ( NonescapableTypes)
388
426
@_alwaysEmitIntoClient
427
+ @lifetime ( self )
389
428
public func _extracting( _: UnboundedRange ) -> Self {
390
429
self
391
430
}
@@ -479,7 +518,7 @@ extension RawSpan {
479
518
_precondition (
480
519
UInt ( bitPattern: offset) <= UInt ( bitPattern: _count) &&
481
520
MemoryLayout < T > . size <= ( _count &- offset) ,
482
- " byte offset range out of bounds"
521
+ " Byte offset range out of bounds"
483
522
)
484
523
return unsafeLoad ( fromUncheckedByteOffset: offset, as: T . self)
485
524
}
@@ -536,7 +575,7 @@ extension RawSpan {
536
575
_precondition (
537
576
UInt ( bitPattern: offset) <= UInt ( bitPattern: _count) &&
538
577
MemoryLayout < T > . size <= ( _count &- offset) ,
539
- " byte offset range out of bounds"
578
+ " Byte offset range out of bounds"
540
579
)
541
580
return unsafeLoadUnaligned ( fromUncheckedByteOffset: offset, as: T . self)
542
581
}
@@ -589,16 +628,16 @@ extension RawSpan {
589
628
/// Returns: A range of offsets within `self`
590
629
@_disallowFeatureSuppression ( NonescapableTypes)
591
630
@_alwaysEmitIntoClient
592
- public func byteOffsets( of span : borrowing Self ) -> Range < Int > ? {
593
- if span . _count > _count { return nil }
594
- guard let spanStart = span . _pointer, _count > 0 else {
595
- return _pointer == span . _pointer ? Range ( _uncheckedBounds: ( 0 , 0 ) ) : nil
631
+ public func byteOffsets( of other : borrowing Self ) -> Range < Int > ? {
632
+ if other . _count > _count { return nil }
633
+ guard let spanStart = other . _pointer, _count > 0 else {
634
+ return _pointer == other . _pointer ? Range ( _uncheckedBounds: ( 0 , 0 ) ) : nil
596
635
}
597
636
let start = _start ( )
598
- let spanEnd = spanStart + span . _count
637
+ let spanEnd = spanStart + other . _count
599
638
if spanStart < start || ( start + _count) < spanEnd { return nil }
600
639
let lower = start. distance ( to: spanStart)
601
- return Range ( _uncheckedBounds: ( lower, lower &+ span . _count) )
640
+ return Range ( _uncheckedBounds: ( lower, lower &+ other . _count) )
602
641
}
603
642
}
604
643
@@ -624,8 +663,9 @@ extension RawSpan {
624
663
/// - Complexity: O(1)
625
664
@_disallowFeatureSuppression ( NonescapableTypes)
626
665
@_alwaysEmitIntoClient
666
+ @lifetime ( self )
627
667
public func _extracting( first maxLength: Int ) -> Self {
628
- _precondition ( maxLength >= 0 , " Can't have a prefix of negative length. " )
668
+ _precondition ( maxLength >= 0 , " Can't have a prefix of negative length " )
629
669
let newCount = min ( maxLength, byteCount)
630
670
return Self ( _unchecked: _pointer, byteCount: newCount)
631
671
}
@@ -646,8 +686,9 @@ extension RawSpan {
646
686
/// - Complexity: O(1)
647
687
@_disallowFeatureSuppression ( NonescapableTypes)
648
688
@_alwaysEmitIntoClient
689
+ @lifetime ( self )
649
690
public func _extracting( droppingLast k: Int ) -> Self {
650
- _precondition ( k >= 0 , " Can't drop a negative number of elements. " )
691
+ _precondition ( k >= 0 , " Can't drop a negative number of elements " )
651
692
let droppedCount = min ( k, byteCount)
652
693
return Self ( _unchecked: _pointer, byteCount: byteCount &- droppedCount)
653
694
}
@@ -669,8 +710,9 @@ extension RawSpan {
669
710
/// - Complexity: O(1)
670
711
@_disallowFeatureSuppression ( NonescapableTypes)
671
712
@_alwaysEmitIntoClient
713
+ @lifetime ( self )
672
714
public func _extracting( last maxLength: Int ) -> Self {
673
- _precondition ( maxLength >= 0 , " Can't have a suffix of negative length. " )
715
+ _precondition ( maxLength >= 0 , " Can't have a suffix of negative length " )
674
716
let newCount = min ( maxLength, byteCount)
675
717
let newStart = _pointer? . advanced ( by: byteCount &- newCount)
676
718
return Self ( _unchecked: newStart, byteCount: newCount)
@@ -692,8 +734,9 @@ extension RawSpan {
692
734
/// - Complexity: O(1)
693
735
@_disallowFeatureSuppression ( NonescapableTypes)
694
736
@_alwaysEmitIntoClient
737
+ @lifetime ( self )
695
738
public func _extracting( droppingFirst k: Int ) -> Self {
696
- _precondition ( k >= 0 , " Can't drop a negative number of elements. " )
739
+ _precondition ( k >= 0 , " Can't drop a negative number of elements " )
697
740
let droppedCount = min ( k, byteCount)
698
741
let newStart = _pointer? . advanced ( by: droppedCount)
699
742
return Self ( _unchecked: newStart, byteCount: byteCount &- droppedCount)
0 commit comments