@@ -340,6 +340,102 @@ ${Suite}.test("${ArrayType}/withUnsafeMutableBytes")
340
340
expectEqual(10, b[0])
341
341
}
342
342
343
+ // FIXME: Implement these changes for ArraySlice and ContiguousArray
344
+
345
+ %if ArrayType == 'Array':
346
+
347
+ //===----------------------------------------------------------------------===//
348
+ // reserveCapacity semantics
349
+ //===----------------------------------------------------------------------===//
350
+
351
+ ${Suite}.test("${ArrayType}/reserveCapacity") {
352
+ var a = ${ArrayType}<Int>()
353
+ for capacity in stride(from: 0, to: 1000, by: 53) {
354
+ a.reserveCapacity(capacity)
355
+ expectLE(capacity, a.capacity)
356
+ }
357
+ }
358
+
359
+ //===----------------------------------------------------------------------===//
360
+ // init(_unsafeUninitializedCapacity:initializingWith:)
361
+ //===----------------------------------------------------------------------===//
362
+
363
+ extension Collection {
364
+ func stablyPartitioned(
365
+ by belongsInFirstPartition: (Element) -> Bool
366
+ ) -> ${ArrayType}<Element> {
367
+ let result = ${ArrayType}<Element>(_unsafeUninitializedCapacity: self.count) {
368
+ buffer, initializedCount in
369
+ var lowIndex = 0
370
+ var highIndex = buffer.count
371
+ for element in self {
372
+ if belongsInFirstPartition(element) {
373
+ buffer[lowIndex] = element
374
+ lowIndex += 1
375
+ } else {
376
+ highIndex -= 1
377
+ buffer[highIndex] = element
378
+ }
379
+ }
380
+
381
+ buffer[highIndex...].reverse()
382
+ initializedCount = buffer.count
383
+ }
384
+ return result
385
+ }
386
+ }
387
+
388
+ ${Suite}.test("${ArrayType}/init(_unsafeUninitializedCapacity:...:)") {
389
+ var a = ${ArrayType}(0..<300)
390
+ let p = a.stablyPartitioned(by: { $0 % 2 == 0 })
391
+ expectEqualSequence(
392
+ [stride(from: 0, to: 300, by: 2), stride(from: 1, to: 300, by: 2)].joined(),
393
+ p
394
+ )
395
+ }
396
+
397
+ ${Suite}.test("${ArrayType}/init(_unsafeUninitializedCapacity:...:)/throwing") {
398
+ final class InstanceCountedClass {
399
+ static var instanceCounter = 0
400
+
401
+ init() { InstanceCountedClass.instanceCounter += 1 }
402
+ deinit { InstanceCountedClass.instanceCounter -= 1 }
403
+ }
404
+ enum E: Error { case error }
405
+
406
+ do {
407
+ var a = Array<InstanceCountedClass>(_unsafeUninitializedCapacity: 10) { buffer, c in
408
+ let p = buffer.baseAddress!
409
+ for i in 0..<5 {
410
+ (p + i).initialize(to: InstanceCountedClass())
411
+ }
412
+ c = 5
413
+ }
414
+ expectEqual(5, a.count)
415
+ expectEqual(5, InstanceCountedClass.instanceCounter)
416
+
417
+ a = []
418
+ expectEqual(0, InstanceCountedClass.instanceCounter)
419
+
420
+ a = try Array(_unsafeUninitializedCapacity: 10) { buffer, c in
421
+ let p = buffer.baseAddress!
422
+ for i in 0..<5 {
423
+ (p + i).initialize(to: InstanceCountedClass())
424
+ }
425
+ c = 5
426
+ throw E.error
427
+ }
428
+
429
+ // The throw above should prevent reaching here, which should mean the
430
+ // instances created in the closure should get deallocated before the final
431
+ // expectation outside the do/catch block.
432
+ expectTrue(false)
433
+ } catch {}
434
+ expectEqual(0, InstanceCountedClass.instanceCounter)
435
+ }
436
+
437
+ %end
438
+
343
439
//===---
344
440
// Check that iterators traverse a snapshot of the collection.
345
441
//===---
0 commit comments