File tree Expand file tree Collapse file tree 1 file changed +19
-17
lines changed Expand file tree Collapse file tree 1 file changed +19
-17
lines changed Original file line number Diff line number Diff line change @@ -445,7 +445,7 @@ extension UniquePermutations: Sequence {
445
445
}
446
446
447
447
@usableFromInline
448
- var state = State . start
448
+ var initial = true
449
449
450
450
@usableFromInline
451
451
var lengths : Range < Int >
@@ -458,27 +458,29 @@ extension UniquePermutations: Sequence {
458
458
459
459
@inlinable
460
460
public mutating func next( ) -> ArraySlice < Element > ? {
461
- switch state {
462
- case . start:
463
- state = . middle
461
+ // In the end case, `lengths` is an empty range.
462
+ if lengths. isEmpty {
463
+ return nil
464
+ }
465
+
466
+ // The first iteration must produce the original sorted array, before any
467
+ // permutations. We skip the permutation the first time so that we can
468
+ // always mutate the array _before_ returning a slice, which avoids
469
+ // copying when possible.
470
+ if initial {
471
+ initial = false
464
472
return elements [ ..< lengths. lowerBound]
465
- case . middle:
466
- if !elements. nextPermutation ( upperBound: lengths. lowerBound) {
467
- lengths = ( lengths. lowerBound + 1 ) ..< lengths. upperBound
473
+ }
468
474
469
- if lengths. isEmpty {
470
- state = . end
471
- return nil
472
- }
475
+ if !elements. nextPermutation ( upperBound: lengths. lowerBound) {
476
+ lengths = ( lengths. lowerBound + 1 ) ..< lengths. upperBound
473
477
474
- elements . sort ( )
475
- state = . start
478
+ if lengths . isEmpty {
479
+ return nil
476
480
}
477
- return elements [ ..< lengths. lowerBound]
478
-
479
- case . end:
480
- return nil
481
481
}
482
+
483
+ return elements [ ..< lengths. lowerBound]
482
484
}
483
485
}
484
486
You can’t perform that action at this time.
0 commit comments