mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[stdlib] in-place initializer for InlineArray
This commit is contained in:
@@ -300,6 +300,25 @@ extension InlineArray where Element: ~Copyable {
|
||||
}
|
||||
#else
|
||||
fatalError()
|
||||
#endif
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.2, *)
|
||||
@_alwaysEmitIntoClient
|
||||
public init<E: Error>(
|
||||
initializingWith initializer: (inout OutputSpan<Element>) throws(E) -> Void
|
||||
) throws(E) {
|
||||
#if $BuiltinEmplaceTypedThrows
|
||||
_storage = try Builtin.emplace { (rawPtr) throws(E) -> () in
|
||||
let buffer = unsafe Self._initializationBuffer(start: rawPtr)
|
||||
_internalInvariant(Self.count == buffer.count)
|
||||
var output = unsafe OutputSpan(buffer: buffer, initializedCount: 0)
|
||||
try initializer(&output)
|
||||
let initialized = unsafe output.finalize(for: buffer)
|
||||
_precondition(count == initialized, "InlineArray initialization underflow")
|
||||
}
|
||||
#else
|
||||
fatalError()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,14 +168,14 @@ enum InlineArrayTests {
|
||||
let error = CancellationError()
|
||||
do {
|
||||
expectDoesNotThrow {
|
||||
let a = try InlineArray<0, String> { _ in throw error }
|
||||
let a = try InlineArray<0, String>({ _ in throw error })
|
||||
_checkInlineArray(a, oracle: [])
|
||||
}
|
||||
_expectThrows {
|
||||
let _ = try InlineArray<1, String> { _ in throw error }
|
||||
let _ = try InlineArray<1, String>({ _ in throw error })
|
||||
}
|
||||
_expectThrows {
|
||||
let _ = try InlineArray<1, any P> { _ in throw error }
|
||||
let _ = try InlineArray<1, any P>({ _ in throw error })
|
||||
}
|
||||
_expectThrows {
|
||||
let _ = try InlineArray<2, String> { index in
|
||||
|
||||
@@ -325,3 +325,98 @@ suite.test("mutate with MutableSpan prefix")
|
||||
expectTrue(b.elementsEqual((0..<10).map({2*(1+$0)})))
|
||||
b.deinitialize()
|
||||
}
|
||||
|
||||
suite.test("InlineArray initialization")
|
||||
.require(.stdlib_6_2).code {
|
||||
guard #available(SwiftStdlib 6.2, *) else { return }
|
||||
|
||||
var a: [Int] = []
|
||||
|
||||
let i = InlineArray<10, Int> {
|
||||
(o: inout OutputSpan<Int>) in
|
||||
for _ in 0..<o.capacity {
|
||||
let r = Int.random(in: 10...99)
|
||||
a.append(r)
|
||||
o.append(r)
|
||||
}
|
||||
}
|
||||
expectEqual(a.count, i.count)
|
||||
for j in i.indices {
|
||||
expectEqual(a[j], i[j])
|
||||
}
|
||||
}
|
||||
|
||||
suite.test("InlineArray initialization underflow")
|
||||
.skip(.wasiAny(reason: "Trap tests aren't supported on WASI."))
|
||||
.require(.stdlib_6_2).code {
|
||||
guard #available(SwiftStdlib 6.2, *) else { return }
|
||||
|
||||
expectCrashLater()
|
||||
_ = InlineArray<4, Int> {
|
||||
$0.append(1)
|
||||
}
|
||||
}
|
||||
|
||||
#if false
|
||||
suite.test("InlineArray initialization throws 0")
|
||||
.require(.stdlib_6_2).code {
|
||||
guard #available(SwiftStdlib 6.2, *) else { return }
|
||||
|
||||
enum LocalError: Error { case error }
|
||||
|
||||
class I {
|
||||
static public var count = 0
|
||||
init() { Self.count += 1 }
|
||||
deinit { Self.count -= 1 }
|
||||
}
|
||||
|
||||
let a: InlineArray<4, I>
|
||||
do throws(LocalError) {
|
||||
var c = 1
|
||||
a = try InlineArray(first: I()) {
|
||||
i throws(LocalError) in
|
||||
c += 1
|
||||
if c < 4 {
|
||||
return I()
|
||||
}
|
||||
print(I.count)
|
||||
throw LocalError.error
|
||||
}
|
||||
_ = a
|
||||
} catch {
|
||||
print(error, I.count)
|
||||
expectEqual(I.count, 0)
|
||||
}
|
||||
}
|
||||
|
||||
suite.test("InlineArray initialization throws")
|
||||
.require(.stdlib_6_2).code {
|
||||
guard #available(SwiftStdlib 6.2, *) else { return }
|
||||
|
||||
enum LocalError: Error { case error }
|
||||
|
||||
class I {
|
||||
static var count = 0
|
||||
init() { Self.count += 1 }
|
||||
deinit { Self.count -= 1 }
|
||||
}
|
||||
|
||||
let a: InlineArray<4, I>
|
||||
do throws(LocalError) {
|
||||
a = try InlineArray {
|
||||
o throws(LocalError) in
|
||||
o.append(I())
|
||||
o.append(I())
|
||||
o.append(I())
|
||||
o.append(I())
|
||||
expectEqual(I.count, 4)
|
||||
print(I.count)
|
||||
throw LocalError.error
|
||||
}
|
||||
_ = a
|
||||
} catch {
|
||||
print(error, I.count)
|
||||
expectEqual(I.count, 0)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user