@@ -175,6 +175,73 @@ if resiliencyChecks.subscriptOnOutOfBoundsIndicesBehavior != .none {
175
175
}
176
176
}
177
177
}
178
+
179
+ let tests = _product(
180
+ subscriptRangeTests,
181
+ _SubSequenceSubscriptOnIndexMode.all)
182
+
183
+ self.test("\(testNamePrefix).SubSequence.subscript(_: Index)/Set/OutOfBounds")
184
+ .forEach(in: tests) {
185
+ (test, mode) in
186
+ let elements = test.collection
187
+ let sliceFromLeft = test.bounds.lowerBound
188
+ let sliceFromRight = elements.count - test.bounds.upperBound
189
+ print("\(elements)/sliceFromLeft=\(sliceFromLeft)/sliceFromRight=\(sliceFromRight)")
190
+ let base = makeWrappedCollection(elements)
191
+ let sliceStartIndex =
192
+ base.index(numericCast(sliceFromLeft), stepsFrom: base.startIndex)
193
+ let sliceEndIndex = base.index(
194
+ numericCast(elements.count - sliceFromRight),
195
+ stepsFrom: base.startIndex)
196
+ var slice = base[sliceStartIndex..<sliceEndIndex]
197
+ expectType(C.SubSequence.self, &slice)
198
+
199
+ var index: C.Index = base.startIndex
200
+ switch mode {
201
+ case .inRange:
202
+ let sliceNumericIndices =
203
+ sliceFromLeft..<(elements.count - sliceFromRight)
204
+ for (i, index) in base.indices.enumerated() {
205
+ if sliceNumericIndices.contains(i) {
206
+ slice[index] = wrapValue(OpaqueValue(elements[i].value + 90000))
207
+ }
208
+ }
209
+ for (i, index) in base.indices.enumerated() {
210
+ if sliceNumericIndices.contains(i) {
211
+ expectEqual(
212
+ elements[i].value + 90000,
213
+ extractValue(slice[index]).value)
214
+ expectEqual(
215
+ extractValue(base[index]).value + 90000,
216
+ extractValue(slice[index]).value)
217
+ }
218
+ }
219
+ return
220
+ case .outOfRangeToTheLeft:
221
+ if sliceFromLeft == 0 { return }
222
+ index = base.index(
223
+ numericCast(sliceFromLeft - 1),
224
+ stepsFrom: base.startIndex)
225
+ case .outOfRangeToTheRight:
226
+ if sliceFromRight == 0 { return }
227
+ index = base.index(
228
+ numericCast(elements.count - sliceFromRight),
229
+ stepsFrom: base.startIndex)
230
+ case .baseEndIndex:
231
+ index = base.endIndex
232
+ case .sliceEndIndex:
233
+ index = sliceEndIndex
234
+ }
235
+
236
+ if resiliencyChecks.subscriptOnOutOfBoundsIndicesBehavior == .trap {
237
+ expectCrashLater()
238
+ slice[index] = wrapValue(OpaqueValue(9999))
239
+ } else {
240
+ expectFailure {
241
+ slice[index] = wrapValue(OpaqueValue(9999))
242
+ }
243
+ }
244
+ }
178
245
}
179
246
180
247
//===----------------------------------------------------------------------===//
@@ -267,6 +334,123 @@ if isFixedLengthCollection {
267
334
}
268
335
}
269
336
337
+ if resiliencyChecks.subscriptRangeOnOutOfBoundsRangesBehavior != .none {
338
+ let tests = _product(
339
+ subscriptRangeTests,
340
+ _SubSequenceSubscriptOnRangeMode.all)
341
+
342
+ self.test("\(testNamePrefix).SubSequence.subscript(_: Range)/Set/OutOfBounds")
343
+ .forEach(in: tests) {
344
+ (test, mode) in
345
+ let elements = test.collection
346
+ let sliceFromLeft = test.bounds.lowerBound
347
+ let sliceFromRight = elements.count - test.bounds.upperBound
348
+ print("\(elements)/sliceFromLeft=\(sliceFromLeft)/sliceFromRight=\(sliceFromRight)")
349
+ let base = makeWrappedCollection(elements)
350
+ let sliceStartIndex =
351
+ base.index(numericCast(sliceFromLeft), stepsFrom: base.startIndex)
352
+ let sliceEndIndex = base.index(
353
+ numericCast(elements.count - sliceFromRight),
354
+ stepsFrom: base.startIndex)
355
+ var slice = base[sliceStartIndex..<sliceEndIndex]
356
+ expectType(C.SubSequence.self, &slice)
357
+
358
+ var bounds: Range<C.Index> = base.startIndex..<base.startIndex
359
+ switch mode {
360
+ case .inRange:
361
+ let sliceNumericIndices =
362
+ sliceFromLeft..<(elements.count - sliceFromRight + 1)
363
+ for (i, subSliceStartIndex) in base.indices.enumerated() {
364
+ for (j, subSliceEndIndex) in base.indices.enumerated() {
365
+ if i <= j &&
366
+ sliceNumericIndices.contains(i) &&
367
+ sliceNumericIndices.contains(j) {
368
+ let newValues = makeWrappedCollection(
369
+ elements[i..<j].map { OpaqueValue($0.value + 90000) }
370
+ )
371
+ slice[subSliceStartIndex..<subSliceEndIndex]
372
+ = newValues[newValues.startIndex..<newValues.endIndex]
373
+ let subSlice = slice[subSliceStartIndex..<subSliceEndIndex]
374
+ for (k, index) in subSlice.indices.enumerated() {
375
+ expectEqual(
376
+ elements[i + k].value + 90000,
377
+ extractValue(subSlice[index]).value)
378
+ expectEqual(
379
+ extractValue(base[index]).value + 90000,
380
+ extractValue(subSlice[index]).value)
381
+ expectEqual(
382
+ extractValue(slice[index]).value,
383
+ extractValue(subSlice[index]).value)
384
+ }
385
+ let oldValues = makeWrappedCollection(Array(elements[i..<j]))
386
+ slice[subSliceStartIndex..<subSliceEndIndex]
387
+ = oldValues[oldValues.startIndex..<oldValues.endIndex]
388
+ }
389
+ }
390
+ }
391
+ return
392
+ case .outOfRangeToTheLeftEmpty:
393
+ if sliceFromLeft == 0 { return }
394
+ let index = base.index(
395
+ numericCast(sliceFromLeft - 1),
396
+ stepsFrom: base.startIndex)
397
+ bounds = index..<index
398
+ break
399
+ case .outOfRangeToTheLeftNonEmpty:
400
+ if sliceFromLeft == 0 { return }
401
+ let index = base.index(
402
+ numericCast(sliceFromLeft - 1),
403
+ stepsFrom: base.startIndex)
404
+ bounds = index..<sliceStartIndex
405
+ break
406
+ case .outOfRangeToTheRightEmpty:
407
+ if sliceFromRight == 0 { return }
408
+ let index = base.index(
409
+ numericCast(elements.count - sliceFromRight + 1),
410
+ stepsFrom: base.startIndex)
411
+ bounds = index..<index
412
+ break
413
+ case .outOfRangeToTheRightNonEmpty:
414
+ if sliceFromRight == 0 { return }
415
+ let index = base.index(
416
+ numericCast(elements.count - sliceFromRight + 1),
417
+ stepsFrom: base.startIndex)
418
+ bounds = sliceEndIndex..<index
419
+ break
420
+ case .outOfRangeBothSides:
421
+ if sliceFromLeft == 0 { return }
422
+ if sliceFromRight == 0 { return }
423
+ bounds =
424
+ base.index(
425
+ numericCast(sliceFromLeft - 1),
426
+ stepsFrom: base.startIndex)
427
+ ..<
428
+ base.index(
429
+ numericCast(elements.count - sliceFromRight + 1),
430
+ stepsFrom: base.startIndex)
431
+ break
432
+ case .baseEndIndex:
433
+ if sliceFromRight == 0 { return }
434
+ bounds = sliceEndIndex..<base.endIndex
435
+ break
436
+ }
437
+
438
+ let count: Int = numericCast(
439
+ base.distance(from: bounds.lowerBound, to: bounds.upperBound))
440
+ let newValues = makeWrappedCollection(Array(elements[0..<count]))
441
+ let newSlice = newValues[newValues.startIndex..<newValues.endIndex]
442
+
443
+ if resiliencyChecks.subscriptOnOutOfBoundsIndicesBehavior == .trap {
444
+ expectCrashLater()
445
+ slice[bounds] = newSlice
446
+ } else {
447
+ expectFailure {
448
+ slice[bounds] = newSlice
449
+ }
450
+ }
451
+ }
452
+ }
453
+
270
454
//===----------------------------------------------------------------------===//
271
455
// _withUnsafeMutableBufferPointerIfSupported()
272
456
//===----------------------------------------------------------------------===//
0 commit comments