@@ -280,20 +280,6 @@ extension MutableSpan where Element: ~Copyable {
280280 }
281281}
282282
283- @available( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , visionOS 9999 , * )
284- extension MutableSpan where Element: BitwiseCopyable {
285-
286- /// Construct a RawSpan over the memory represented by this span
287- ///
288- /// - Returns: a RawSpan over the memory represented by this span
289- @unsafe //FIXME: remove when the lifetime inference is fixed
290- @_alwaysEmitIntoClient
291- public var _unsafeRawSpan: RawSpan {
292- @lifetime ( borrow self)
293- get { RawSpan ( _unsafeMutableSpan: self ) }
294- }
295- }
296-
297283@available( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , visionOS 9999 , * )
298284extension MutableSpan where Element: ~ Copyable {
299285
@@ -687,11 +673,91 @@ public struct OutputSpan<Element: ~Copyable>: ~Copyable, ~Escapable {
687673extension OutputSpan: Sendable { }
688674
689675@available( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , visionOS 9999 , * )
690- extension OutputSpan where Element: ~ Copyable {
676+ extension OutputSpan where Element: ~ Copyable {
677+ @unsafe
678+ @_alwaysEmitIntoClient
679+ @lifetime ( borrow buffer)
680+ public init(
681+ _uncheckedBuffer buffer: UnsafeMutableBufferPointer < Element > ,
682+ initializedCount: Int
683+ ) {
684+ unsafe _pointer = . init( buffer. baseAddress)
685+ capacity = buffer. count
686+ _initialized = initializedCount
687+ }
688+
689+ /// Unsafely create an OutputSpan over partly-initialized memory.
690+ ///
691+ /// The memory in `buffer` must remain valid throughout the lifetime
692+ /// of the newly-created `OutputSpan`. Its prefix must contain
693+ /// `initializedCount` initialized instances, followed by uninitialized
694+ /// memory. The default value of `initializedCount` is 0, representing
695+ /// the common case of a completely uninitialized `buffer`.
696+ ///
697+ /// - Parameters:
698+ /// - buffer: an `UnsafeMutableBufferPointer` to be initialized
699+ /// - initializedCount: the number of initialized elements
700+ /// at the beginning of `buffer`.
701+ @unsafe
702+ @_alwaysEmitIntoClient
703+ @lifetime ( borrow buffer)
704+ public init(
705+ buffer: UnsafeMutableBufferPointer < Element > ,
706+ initializedCount: Int
707+ ) {
708+ precondition ( buffer. _isWellAligned ( ) , " Misaligned OutputSpan " )
709+ if let baseAddress = buffer. baseAddress {
710+ precondition (
711+ unsafe baseAddress. advanced ( by: buffer. count) >= baseAddress,
712+ " Buffer must not wrap around the address space "
713+ )
714+ }
715+ precondition (
716+ 0 <= initializedCount && initializedCount <= buffer. count,
717+ " OutputSpan count is not within capacity "
718+ )
719+ unsafe self. init (
720+ _uncheckedBuffer: buffer, initializedCount: initializedCount
721+ )
722+ }
723+ }
724+
725+ extension UnsafePointer where Pointee: ~ Copyable {
726+ @safe
727+ @_alwaysEmitIntoClient
728+ public func _isWellAligned( ) -> Bool {
729+ ( Int ( bitPattern: self ) & ( MemoryLayout < Pointee > . alignment &- 1 ) ) == 0
730+ }
731+ }
732+
733+ extension UnsafeMutablePointer where Pointee: ~ Copyable {
734+ @safe
735+ @_alwaysEmitIntoClient
736+ public func _isWellAligned( ) -> Bool {
737+ ( Int ( bitPattern: self ) & ( MemoryLayout < Pointee > . alignment &- 1 ) ) == 0
738+ }
739+ }
740+
741+ extension UnsafeBufferPointer where Element: ~ Copyable {
742+ @safe
743+ @_alwaysEmitIntoClient
744+ public func _isWellAligned( ) -> Bool {
745+ guard let p = baseAddress else { return true }
746+ return p. _isWellAligned ( )
747+ }
748+ }
749+
750+ extension UnsafeMutableBufferPointer where Element: ~ Copyable {
751+ @inlinable
752+ public func _isWellAligned( ) -> Bool {
753+ guard let p = baseAddress else { return true }
754+ return p. _isWellAligned ( )
755+ }
756+ }
757+
758+ @available( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , visionOS 9999 , * )
759+ extension OutputSpan where Element: ~ Copyable {
691760
692- @available ( macOS 9999 , * )
693- @available ( macOS 9999 , * )
694- @available ( macOS 9999 , * )
695761 @_alwaysEmitIntoClient
696762 @lifetime ( self: copy self)
697763 public mutating func append( _ value: consuming Element ) {
@@ -767,11 +833,7 @@ extension OutputSpan {
767833 fromContentsOf source: some Collection < Element >
768834 ) {
769835 let void : Void ? = source. withContiguousStorageIfAvailable {
770- #if false
771836 append ( fromContentsOf: Span ( _unsafeElements: $0) )
772- #else //FIXME: remove once rdar://136838539 & rdar://136849171 are fixed
773- append ( fromContentsOf: $0)
774- #endif
775837 }
776838 if void != nil {
777839 return
@@ -792,24 +854,6 @@ extension OutputSpan {
792854 _initialized &+= copied
793855 }
794856
795- //FIXME: remove once rdar://136838539 & rdar://136849171 are fixed
796- @lifetime ( self : copy self )
797- public mutating func append(
798- fromContentsOf source: UnsafeBufferPointer < Element >
799- ) {
800- guard !source. isEmpty else { return }
801- precondition (
802- source. count <= available,
803- " destination span cannot contain every element from source. "
804- )
805- let tail = _start. advanced ( by: _initialized&* MemoryLayout< Element> . stride)
806- source. baseAddress!. withMemoryRebound ( to: Element . self, capacity: source. count) {
807- _ = tail. initializeMemory ( as: Element . self, from: $0, count: source. count)
808- }
809- _initialized += source. count
810- }
811-
812- //FIXME: rdar://136838539 & rdar://136849171
813857 @_alwaysEmitIntoClient
814858 @lifetime ( self : copy self )
815859 public mutating func append(
@@ -863,21 +907,8 @@ extension OutputSpan where Element: ~Copyable {
863907 public mutating func moveAppend(
864908 fromContentsOf source: UnsafeMutableBufferPointer < Element >
865909 ) {
866- #if false //FIXME: rdar://136838539 & rdar://136849171
867- let source = OutputSpan ( _initializing: source, initialized: source. count)
910+ let source = OutputSpan ( buffer: source, initializedCount: source. count)
868911 moveAppend ( fromContentsOf: source)
869- #else
870- guard !source. isEmpty else { return }
871- precondition (
872- source. count <= available,
873- " buffer cannot contain every element from source. "
874- )
875- let tail = _start. advanced ( by: _initialized&* MemoryLayout< Element> . stride)
876- tail. moveInitializeMemory (
877- as: Element . self, from: source. baseAddress!, count: source. count
878- )
879- _initialized &+= source. count
880- #endif
881912 }
882913}
883914
@@ -912,19 +943,16 @@ extension OutputSpan where Element: ~Copyable {
912943 }
913944 }
914945
915- /* FIXME: rdar://147194789 ([nonescapable] 'mutating get' causes a
916- type checking error for non-existent _read accessor)
917946 @_alwaysEmitIntoClient
918947 public var mutableSpan : MutableSpan < Element > {
919- @lifetime(borrow self)
948+ @lifetime ( & self )
920949 mutating get { // the accessor must provide a mutable projection
921950 let pointer = _pointer? . assumingMemoryBound ( to: Element . self)
922951 let buffer = UnsafeMutableBufferPointer ( start: pointer, count: _initialized)
923952 let span = MutableSpan ( _unsafeElements: buffer)
924953 return _overrideLifetime ( span, mutating: & self )
925954 }
926955 }
927- */
928956}
929957
930958@available( macOS 9999 , iOS 9999 , tvOS 9999 , watchOS 9999 , visionOS 9999 , * )
0 commit comments