@@ -456,6 +456,98 @@ extension Unsafe${Mutable}BufferPointer where Element: ~Copyable {
456456
457457}
458458
459+ extension Unsafe${ Mutable} BufferPointer where Element: ~ Copyable {
460+ /// Constructs a standalone buffer pointer over the items within the supplied
461+ /// range of positions in the memory region addressed by this buffer pointer.
462+ ///
463+ /// The returned buffer's first item is always at index 0; unlike buffer
464+ /// slices, extracted buffers do not generally share their indices with the
465+ /// original buffer pointer.
466+ ///
467+ /// withUnsafeTemporaryAllocation(of: Int.self, capacity: 5) { buffer in
468+ /// buffer.initialize(repeating: 0)
469+ /// // buffer contains [0, 0, 0, 0, 0]
470+ /// let part = buffer.extracting(2 ..< 4)
471+ /// part[0] = 1
472+ /// part[1] = 2
473+ /// // buffer now contains [0, 0, 1, 2, 0]
474+ /// }
475+ ///
476+ /// When `Element` is copyable, the `extracting` operation is equivalent to
477+ /// slicing the buffer then rebasing the resulting buffer slice:
478+ ///
479+ /// let a = buffer.extracting(i ..< j)
480+ /// let b = UnsafeBufferPointer(rebasing: buffer[i ..< j])
481+ /// // `a` and `b` are now holding the same buffer
482+ ///
483+ /// However, unlike slicing, the `extracting` operation remains available even
484+ /// if `Element` happens to be noncopyable.
485+ ///
486+ /// - Parameter bounds: A valid range of indices within this buffer.
487+ /// - Returns: A new buffer pointer over the items at `bounds`.
488+ @_alwaysEmitIntoClient
489+ public func extracting( _ bounds: Range < Int > ) -> Self {
490+ _precondition ( bounds. lowerBound >= 0 && bounds. upperBound <= count,
491+ " Index out of range " )
492+ guard let start = self . baseAddress else {
493+ return Self ( start: nil , count: 0 )
494+ }
495+ return Self ( start: start + bounds. lowerBound, count: bounds. count)
496+ }
497+
498+ /// Constructs a standalone buffer pointer over the items within the supplied
499+ /// range of positions in the memory region addressed by this buffer pointer.
500+ ///
501+ /// The returned buffer's first item is always at index 0; unlike buffer
502+ /// slices, extracted buffers do not generally share their indices with the
503+ /// original buffer pointer.
504+ ///
505+ /// withUnsafeTemporaryAllocation(of: Int.self, capacity: 5) { buffer in
506+ /// buffer.initialize(repeating: 0)
507+ /// // buffer contains [0, 0, 0, 0, 0]
508+ /// let part = buffer.extracting(2...)
509+ /// part[0] = 1
510+ /// part[1] = 2
511+ /// // buffer now contains [0, 0, 1, 2, 0]
512+ /// }
513+ ///
514+ /// When `Element` is copyable, the `extracting` operation is equivalent to
515+ /// slicing the buffer then rebasing the resulting buffer slice:
516+ ///
517+ /// let a = buffer.extracting(i ..< j)
518+ /// let b = UnsafeBufferPointer(rebasing: buffer[i ..< j])
519+ /// // `a` and `b` are now holding the same buffer
520+ ///
521+ /// However, unlike slicing, the `extracting` operation remains available even
522+ /// if `Element` happens to be noncopyable.
523+ ///
524+ /// - Parameter bounds: A valid range of indices within this buffer.
525+ /// - Returns: A new buffer pointer over the items at `bounds`.
526+ @_alwaysEmitIntoClient
527+ public func extracting( _ bounds: some RangeExpression < Int > ) -> Self {
528+ extracting ( bounds. relative ( to: Range ( uncheckedBounds: ( 0 , count) ) ) )
529+ }
530+
531+ /// Extracts and returns a copy of the entire buffer.
532+ ///
533+ /// When `Element` is copyable, the `extracting` operation is equivalent to
534+ /// slicing the buffer then rebasing the resulting buffer slice:
535+ ///
536+ /// let a = buffer
537+ /// let b = buffer.extracting(...)
538+ /// let c = UnsafeBufferPointer(rebasing: buffer[...])
539+ /// // `a`, `b` and `c` are now all referring to the same buffer
540+ ///
541+ /// Note that unlike slicing, the `extracting` operation remains available
542+ /// even if `Element` happens to be noncopyable.
543+ //
544+ /// - Returns: The same buffer as `self`.
545+ @_alwaysEmitIntoClient
546+ public func extracting( _ bounds: UnboundedRange ) -> Self {
547+ self
548+ }
549+ }
550+
459551@_disallowFeatureSuppression ( NoncopyableGenerics)
460552extension Unsafe ${ Mutable} BufferPointer {
461553 /// Accesses the element at the specified position.
0 commit comments