Skip to content

Commit 659cf1d

Browse files
committed
[stdlib] Make unsafe array initializer public
The original underscored version of this initializer remains, with a deprecation notice. Also add the initializer to ContiguousArray.
1 parent f157cdc commit 659cf1d

File tree

2 files changed

+71
-7
lines changed

2 files changed

+71
-7
lines changed

stdlib/public/core/Array.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,21 +1366,35 @@ extension Array {
13661366
}
13671367

13681368
extension Array {
1369+
@available(swift, deprecated: 5.1, renamed: "init(unsafeUninitializedCapacity:initializingWith:)")
1370+
@inlinable
1371+
public init(
1372+
_unsafeUninitializedCapacity: Int,
1373+
initializingWith initializer: (
1374+
_ buffer: inout UnsafeMutableBufferPointer<Element>,
1375+
_ initializedCount: inout Int) throws -> Void
1376+
) rethrows {
1377+
try self.init(
1378+
unsafeUninitializedCapacity: _unsafeUninitializedCapacity,
1379+
initializingWith: initializer)
1380+
}
1381+
13691382
/// Creates an array with the specified capacity, then calls the given
13701383
/// closure with a buffer covering the array's uninitialized memory.
13711384
///
13721385
/// Inside the closure, set the `initializedCount` parameter to the number of
13731386
/// elements that are initialized by the closure. The memory in the range
13741387
/// `buffer[0..<initializedCount]` must be initialized at the end of the
13751388
/// closure's execution, and the memory in the range
1376-
/// `buffer[initializedCount...]` must be uninitialized.
1389+
/// `buffer[initializedCount...]` must be uninitialized. This postcondition
1390+
/// must hold even if the `initializer` closure throws an error.
13771391
///
13781392
/// - Note: While the resulting array may have a capacity larger than the
13791393
/// requested amount, the buffer passed to the closure will cover exactly
13801394
/// the requested number of elements.
13811395
///
13821396
/// - Parameters:
1383-
/// - _unsafeUninitializedCapacity: The number of elements to allocate
1397+
/// - unsafeUninitializedCapacity: The number of elements to allocate
13841398
/// space for in the new array.
13851399
/// - initializer: A closure that initializes elements and sets the count
13861400
/// of the new array.
@@ -1392,29 +1406,29 @@ extension Array {
13921406
/// elements you initialize.
13931407
@inlinable
13941408
public init(
1395-
_unsafeUninitializedCapacity: Int,
1409+
unsafeUninitializedCapacity: Int,
13961410
initializingWith initializer: (
13971411
_ buffer: inout UnsafeMutableBufferPointer<Element>,
13981412
_ initializedCount: inout Int) throws -> Void
13991413
) rethrows {
14001414
var firstElementAddress: UnsafeMutablePointer<Element>
14011415
(self, firstElementAddress) =
1402-
Array._allocateUninitialized(_unsafeUninitializedCapacity)
1416+
Array._allocateUninitialized(unsafeUninitializedCapacity)
14031417

14041418
var initializedCount = 0
14051419
defer {
14061420
// Update self.count even if initializer throws an error.
14071421
_precondition(
1408-
initializedCount <= _unsafeUninitializedCapacity,
1422+
initializedCount <= unsafeUninitializedCapacity,
14091423
"Initialized count set to greater than specified capacity."
14101424
)
14111425
self._buffer.count = initializedCount
14121426
}
14131427
var buffer = UnsafeMutableBufferPointer<Element>(
1414-
start: firstElementAddress, count: _unsafeUninitializedCapacity)
1428+
start: firstElementAddress, count: unsafeUninitializedCapacity)
14151429
try initializer(&buffer, &initializedCount)
14161430
}
1417-
1431+
14181432
/// Calls a closure with a pointer to the array's contiguous storage.
14191433
///
14201434
/// Often, the optimizer can eliminate bounds checks within an array

stdlib/public/core/ContiguousArray.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,56 @@ extension ContiguousArray {
985985
}
986986

987987
extension ContiguousArray {
988+
/// Creates an array with the specified capacity, then calls the given
989+
/// closure with a buffer covering the array's uninitialized memory.
990+
///
991+
/// Inside the closure, set the `initializedCount` parameter to the number of
992+
/// elements that are initialized by the closure. The memory in the range
993+
/// `buffer[0..<initializedCount]` must be initialized at the end of the
994+
/// closure's execution, and the memory in the range
995+
/// `buffer[initializedCount...]` must be uninitialized. This postcondition
996+
/// must hold even if the `initializer` closure throws an error.
997+
///
998+
/// - Note: While the resulting array may have a capacity larger than the
999+
/// requested amount, the buffer passed to the closure will cover exactly
1000+
/// the requested number of elements.
1001+
///
1002+
/// - Parameters:
1003+
/// - unsafeUninitializedCapacity: The number of elements to allocate
1004+
/// space for in the new array.
1005+
/// - initializer: A closure that initializes elements and sets the count
1006+
/// of the new array.
1007+
/// - Parameters:
1008+
/// - buffer: A buffer covering uninitialized memory with room for the
1009+
/// specified number of of elements.
1010+
/// - initializedCount: The count of initialized elements in the array,
1011+
/// which begins as zero. Set `initializedCount` to the number of
1012+
/// elements you initialize.
1013+
@inlinable
1014+
public init(
1015+
unsafeUninitializedCapacity: Int,
1016+
initializingWith initializer: (
1017+
_ buffer: inout UnsafeMutableBufferPointer<Element>,
1018+
_ initializedCount: inout Int) throws -> Void
1019+
) rethrows {
1020+
var firstElementAddress: UnsafeMutablePointer<Element>
1021+
(self, firstElementAddress) =
1022+
ContiguousArray._allocateUninitialized(unsafeUninitializedCapacity)
1023+
1024+
var initializedCount = 0
1025+
defer {
1026+
// Update self.count even if initializer throws an error.
1027+
_precondition(
1028+
initializedCount <= unsafeUninitializedCapacity,
1029+
"Initialized count set to greater than specified capacity."
1030+
)
1031+
self._buffer.count = initializedCount
1032+
}
1033+
var buffer = UnsafeMutableBufferPointer<Element>(
1034+
start: firstElementAddress, count: unsafeUninitializedCapacity)
1035+
try initializer(&buffer, &initializedCount)
1036+
}
1037+
9881038
/// Calls a closure with a pointer to the array's contiguous storage.
9891039
///
9901040
/// Often, the optimizer can eliminate bounds checks within an array

0 commit comments

Comments
 (0)