@@ -766,6 +766,11 @@ extension Unsafe${Mutable}RawBufferPointer {
766
766
return ( it, UnsafeMutableBufferPointer ( start: nil , count: 0 ) )
767
767
}
768
768
769
+ _debugPrecondition (
770
+ Int ( bitPattern: base) % MemoryLayout< S . Element> . stride == 0 ,
771
+ " buffer base address must be properly aligned to access S.Element "
772
+ )
773
+
769
774
_internalInvariant ( _end != nil )
770
775
for p in stride ( from: base,
771
776
// only advance to as far as the last element that will fit
@@ -813,27 +818,57 @@ extension Unsafe${Mutable}RawBufferPointer {
813
818
as type: C . Element . Type ,
814
819
fromContentsOf source: C
815
820
) -> UnsafeMutableBufferPointer < C . Element > {
816
- var count = source. count
817
- guard let base = _position, let end = _end, end > base, count > 0 else {
818
- return UnsafeMutableBufferPointer ( start: nil , count: 0 )
821
+ let buffer : UnsafeMutableBufferPointer < C . Element > ?
822
+ buffer = source. withContiguousStorageIfAvailable {
823
+ guard let sourceAddress = $0. baseAddress, !$0. isEmpty else {
824
+ return . init( start: nil , count: 0 )
825
+ }
826
+ _debugPrecondition (
827
+ Int ( bitPattern: baseAddress) % MemoryLayout< C . Element> . stride == 0 ,
828
+ " buffer base address must be properly aligned to access C.Element "
829
+ )
830
+ _precondition (
831
+ $0. count * MemoryLayout < C . Element > . stride < self . count,
832
+ " buffer cannot contain every element from source collection. "
833
+ )
834
+ let start = baseAddress? . initializeMemory (
835
+ as: C . Element. self, from: sourceAddress, count: $0. count
836
+ )
837
+ return . init( start: start, count: $0. count)
838
+ }
839
+ if let buffer {
840
+ return buffer
819
841
}
820
- count = Swift . min ( ( end - base) / MemoryLayout< C . Element> . stride, count)
821
842
822
- if let start = source. withContiguousStorageIfAvailable ( {
823
- base. initializeMemory (
824
- as: C . Element. self,
825
- from: $0. baseAddress. _unsafelyUnwrappedUnchecked,
826
- count: count
843
+ guard let base = baseAddress else {
844
+ _precondition (
845
+ source. isEmpty,
846
+ " buffer cannot contain every element from source collection. "
827
847
)
828
- } ) {
829
- return UnsafeMutableBufferPointer ( start: start, count: count)
848
+ return . init( start: nil , count: 0 )
830
849
}
831
-
832
- let start = base. bindMemory ( to: C . Element. self, capacity: count)
833
- for (pointer, element) in zip ( start..< start. advanced ( by: count) , source) {
834
- pointer. initialize ( to: element)
850
+ _internalInvariant ( _end != nil )
851
+ _debugPrecondition (
852
+ Int ( bitPattern: baseAddress) % MemoryLayout< C . Element> . stride == 0 ,
853
+ " buffer base address must be properly aligned to access C.Element "
854
+ )
855
+ var iterator = source. makeIterator ( )
856
+ var element = base
857
+ var initialized = 0
858
+ let end = _end. _unsafelyUnwrappedUnchecked - MemoryLayout< C . Element> . stride
859
+ while element <= end {
860
+ guard let value = iterator. next ( ) else {
861
+ return . init( start: . init( base. _rawValue) , count: initialized)
862
+ }
863
+ element. initializeMemory ( as: C . Element. self, to: value)
864
+ element = element. advanced ( by: MemoryLayout< C . Element> . stride)
865
+ initialized += 1
835
866
}
836
- return UnsafeMutableBufferPointer ( start: start, count: count)
867
+ _precondition (
868
+ iterator. next ( ) == nil ,
869
+ " buffer cannot contain every element from source collection. "
870
+ )
871
+ return . init( start: . init( base. _rawValue) , count: initialized)
837
872
}
838
873
839
874
/// Moves every element of an initialized source buffer into the
@@ -870,17 +905,21 @@ extension Unsafe${Mutable}RawBufferPointer {
870
905
as type: T . Type ,
871
906
fromContentsOf source: UnsafeMutableBufferPointer < T >
872
907
) -> UnsafeMutableBufferPointer < T > {
873
- guard let sourceBase = source. baseAddress
874
- else { return UnsafeMutableBufferPointer ( start: nil , count: 0 ) }
875
-
876
- let neededBytes = source. count*MemoryLayout< T> . stride
877
- guard let base = _position, count >= neededBytes
878
- else { _debugPreconditionFailure ( " destination has too few bytes " ) }
879
-
880
- let initialized = base. moveInitializeMemory ( as: T . self,
881
- from: sourceBase,
882
- count: source. count)
883
- return UnsafeMutableBufferPointer ( start: initialized, count: source. count)
908
+ guard let sourceAddress = source. baseAddress, !source. isEmpty else {
909
+ return . init( start: nil , count: 0 )
910
+ }
911
+ _precondition (
912
+ source. count * MemoryLayout < T > . stride <= self . count,
913
+ " buffer cannot contain every element from source. "
914
+ )
915
+ _debugPrecondition (
916
+ Int ( bitPattern: baseAddress) % MemoryLayout< T> . stride == 0 ,
917
+ " buffer base address must be properly aligned to access T "
918
+ )
919
+ let initialized = baseAddress? . moveInitializeMemory (
920
+ as: T . self, from: sourceAddress, count: source. count
921
+ )
922
+ return . init( start: initialized, count: source. count)
884
923
}
885
924
886
925
/// Moves every element of an initialized source buffer slice into the
0 commit comments