@@ -6,32 +6,36 @@ use std::iter::FusedIterator;
6
6
7
7
use super :: lazy_buffer:: LazyBuffer ;
8
8
use crate :: size_hint:: { self , SizeHint } ;
9
+ use crate :: combinations:: { MaybeConstUsize , PoolIndex } ;
10
+
11
+ #[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
12
+ pub struct PermutationsGeneric < I : Iterator , Idx : PoolIndex > {
13
+ vals : LazyBuffer < I > ,
14
+ state : PermutationState < Idx > ,
15
+ }
9
16
10
17
/// An iterator adaptor that iterates through all the `k`-permutations of the
11
18
/// elements from an iterator.
12
19
///
13
20
/// See [`.permutations()`](crate::Itertools::permutations) for
14
21
/// more information.
15
- #[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
16
- pub struct Permutations < I : Iterator > {
17
- vals : LazyBuffer < I > ,
18
- state : PermutationState ,
19
- }
22
+ pub type Permutations < I > = PermutationsGeneric < I , Vec < usize > > ;
20
23
21
- impl < I > Clone for Permutations < I >
24
+ impl < I , Idx > Clone for PermutationsGeneric < I , Idx >
22
25
where
23
26
I : Clone + Iterator ,
24
27
I :: Item : Clone ,
28
+ Idx : Clone + PoolIndex ,
25
29
{
26
30
clone_fields ! ( vals, state) ;
27
31
}
28
32
29
33
#[ derive( Clone , Debug ) ]
30
- enum PermutationState {
34
+ enum PermutationState < Idx : PoolIndex > {
31
35
/// No permutation generated yet.
32
- Start { k : usize } ,
36
+ Start { k : Idx :: Length } ,
33
37
/// Values from the iterator are not fully loaded yet so `n` is still unknown.
34
- Buffered { k : usize , min_n : usize } ,
38
+ Buffered { k : Idx :: Length , min_n : usize } ,
35
39
/// All values from the iterator are known so `n` is known.
36
40
Loaded {
37
41
indices : Box < [ usize ] > ,
@@ -41,12 +45,13 @@ enum PermutationState {
41
45
End ,
42
46
}
43
47
44
- impl < I > fmt:: Debug for Permutations < I >
48
+ impl < I , Idx : PoolIndex > fmt:: Debug for PermutationsGeneric < I , Idx >
45
49
where
46
50
I : Iterator + fmt:: Debug ,
47
51
I :: Item : fmt:: Debug ,
52
+ Idx : fmt:: Debug ,
48
53
{
49
- debug_fmt_fields ! ( Permutations , vals, state) ;
54
+ debug_fmt_fields ! ( PermutationsGeneric , vals, state) ;
50
55
}
51
56
52
57
pub fn permutations < I : Iterator > ( iter : I , k : usize ) -> Permutations < I > {
@@ -56,7 +61,7 @@ pub fn permutations<I: Iterator>(iter: I, k: usize) -> Permutations<I> {
56
61
}
57
62
}
58
63
59
- impl < I > Iterator for Permutations < I >
64
+ impl < I , Idx : PoolIndex > Iterator for PermutationsGeneric < I , Idx >
60
65
where
61
66
I : Iterator ,
62
67
I :: Item : Clone ,
@@ -67,39 +72,39 @@ where
67
72
let Self { vals, state } = self ;
68
73
match state {
69
74
& mut PermutationState :: Start { k } => {
70
- if k == 0 {
75
+ if k. value ( ) == 0 {
71
76
* state = PermutationState :: End ;
72
77
} else {
73
- vals. prefill ( k) ;
74
- if vals. len ( ) != k {
78
+ vals. prefill ( k. value ( ) ) ;
79
+ if vals. len ( ) != k. value ( ) {
75
80
* state = PermutationState :: End ;
76
81
return None ;
77
82
}
78
- * state = PermutationState :: Buffered { k, min_n : k } ;
83
+ * state = PermutationState :: Buffered { k, min_n : k. value ( ) } ;
79
84
}
80
- Some ( vals[ 0 ..k] . to_vec ( ) )
85
+ Some ( vals[ 0 ..k. value ( ) ] . to_vec ( ) )
81
86
}
82
87
PermutationState :: Buffered { ref k, min_n } => {
83
88
if vals. get_next ( ) {
84
- let item = ( 0 ..* k - 1 )
89
+ let item = ( 0 ..k . value ( ) - 1 )
85
90
. chain ( once ( * min_n) )
86
91
. map ( |i| vals[ i] . clone ( ) )
87
92
. collect ( ) ;
88
93
* min_n += 1 ;
89
94
Some ( item)
90
95
} else {
91
96
let n = * min_n;
92
- let prev_iteration_count = n - * k + 1 ;
97
+ let prev_iteration_count = n - k . value ( ) + 1 ;
93
98
let mut indices: Box < [ _ ] > = ( 0 ..n) . collect ( ) ;
94
- let mut cycles: Box < [ _ ] > = ( n - k..n) . rev ( ) . collect ( ) ;
99
+ let mut cycles: Box < [ _ ] > = ( n - k. value ( ) . .n) . rev ( ) . collect ( ) ;
95
100
// Advance the state to the correct point.
96
101
for _ in 0 ..prev_iteration_count {
97
102
if advance ( & mut indices, & mut cycles) {
98
103
* state = PermutationState :: End ;
99
104
return None ;
100
105
}
101
106
}
102
- let item = vals. get_at ( & indices[ 0 ..* k ] ) ;
107
+ let item = vals. get_at ( & indices[ 0 ..k . value ( ) ] ) ;
103
108
* state = PermutationState :: Loaded { indices, cycles } ;
104
109
Some ( item)
105
110
}
@@ -130,7 +135,7 @@ where
130
135
}
131
136
}
132
137
133
- impl < I > FusedIterator for Permutations < I >
138
+ impl < I , Idx : PoolIndex > FusedIterator for PermutationsGeneric < I , Idx >
134
139
where
135
140
I : Iterator ,
136
141
I :: Item : Clone ,
@@ -155,20 +160,20 @@ fn advance(indices: &mut [usize], cycles: &mut [usize]) -> bool {
155
160
true
156
161
}
157
162
158
- impl PermutationState {
163
+ impl < Idx : PoolIndex > PermutationState < Idx > {
159
164
fn size_hint_for ( & self , n : usize ) -> SizeHint {
160
165
// At the beginning, there are `n!/(n-k)!` items to come.
161
- let at_start = |n, k| {
162
- debug_assert ! ( n >= k) ;
163
- let total = ( n - k + 1 ..=n) . try_fold ( 1usize , |acc, i| acc. checked_mul ( i) ) ;
166
+ let at_start = |n, k : Idx :: Length | {
167
+ debug_assert ! ( n >= k. value ( ) ) ;
168
+ let total = ( n - k. value ( ) + 1 ..=n) . try_fold ( 1usize , |acc, i| acc. checked_mul ( i) ) ;
164
169
( total. unwrap_or ( usize:: MAX ) , total)
165
170
} ;
166
171
match * self {
167
- Self :: Start { k } if n < k => ( 0 , Some ( 0 ) ) ,
172
+ Self :: Start { k } if n < k. value ( ) => ( 0 , Some ( 0 ) ) ,
168
173
Self :: Start { k } => at_start ( n, k) ,
169
174
Self :: Buffered { k, min_n } => {
170
175
// Same as `Start` minus the previously generated items.
171
- size_hint:: sub_scalar ( at_start ( n, k) , min_n - k + 1 )
176
+ size_hint:: sub_scalar ( at_start ( n, k) , min_n - k. value ( ) + 1 )
172
177
}
173
178
Self :: Loaded {
174
179
ref indices,
0 commit comments