Skip to content

Commit 7fa9d1f

Browse files
itingliuphausler
andauthored
Slices of no copy Data bridged to and back incorrectly account for the start index (#698)
* rdar://130028376 (slices of no copy Data bridged to and back incorrectly account for the start index) * Ensure the range can be stored as half int --------- Co-authored-by: Philippe Hausler <[email protected]>
1 parent ffd3118 commit 7fa9d1f

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

Sources/FoundationEssentials/Data/Data.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,11 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
817817
static func canStore(count: Int) -> Bool {
818818
return count < HalfInt.max
819819
}
820+
821+
@inlinable // This is @inlinable as trivially computable.
822+
static func canStore(range: Range<Int>) -> Bool {
823+
return range.lowerBound < HalfInt.max && range.upperBound < HalfInt.max
824+
}
820825

821826
@inlinable // This is @inlinable as a convenience initializer.
822827
init(_ buffer: UnsafeRawBufferPointer) {
@@ -1120,6 +1125,12 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
11201125
self.storage = storage
11211126
self.slice = RangeReference(0..<count)
11221127
}
1128+
1129+
@inlinable // This is @inlinable as a trivial initializer.
1130+
init(_ storage: __DataStorage, range: Range<Int>) {
1131+
self.storage = storage
1132+
self.slice = RangeReference(range)
1133+
}
11231134

11241135
@inlinable // This is @inlinable as trivially computable (and inlining may help avoid retain-release traffic).
11251136
mutating func ensureUniqueReference() {
@@ -1362,6 +1373,19 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
13621373
self = .large(LargeSlice(storage, count: count))
13631374
}
13641375
}
1376+
1377+
@inlinable
1378+
init(_ storage: __DataStorage, range: Range<Int>) {
1379+
if range.count == 0 {
1380+
self = .empty
1381+
} else if range.startIndex == 0 {
1382+
self.init(storage, count: range.count)
1383+
} else if InlineSlice.canStore(range: range) {
1384+
self = .slice(InlineSlice(storage, range: range))
1385+
} else {
1386+
self = .large(LargeSlice(storage, range: range))
1387+
}
1388+
}
13651389

13661390
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
13671391
mutating func reserveCapacity(_ minimumCapacity: Int) {

0 commit comments

Comments
 (0)