@@ -6,32 +6,36 @@ use std::iter::FusedIterator;
66
77use super :: lazy_buffer:: LazyBuffer ;
88use 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+ }
916
1017/// An iterator adaptor that iterates through all the `k`-permutations of the
1118/// elements from an iterator.
1219///
1320/// See [`.permutations()`](crate::Itertools::permutations) for
1421/// 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 > > ;
2023
21- impl < I > Clone for Permutations < I >
24+ impl < I , Idx > Clone for PermutationsGeneric < I , Idx >
2225where
2326 I : Clone + Iterator ,
2427 I :: Item : Clone ,
28+ Idx : Clone + PoolIndex ,
2529{
2630 clone_fields ! ( vals, state) ;
2731}
2832
2933#[ derive( Clone , Debug ) ]
30- enum PermutationState {
34+ enum PermutationState < Idx : PoolIndex > {
3135 /// No permutation generated yet.
32- Start { k : usize } ,
36+ Start { k : Idx :: Length } ,
3337 /// 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 } ,
3539 /// All values from the iterator are known so `n` is known.
3640 Loaded {
3741 indices : Box < [ usize ] > ,
@@ -41,12 +45,13 @@ enum PermutationState {
4145 End ,
4246}
4347
44- impl < I > fmt:: Debug for Permutations < I >
48+ impl < I , Idx : PoolIndex > fmt:: Debug for PermutationsGeneric < I , Idx >
4549where
4650 I : Iterator + fmt:: Debug ,
4751 I :: Item : fmt:: Debug ,
52+ Idx : fmt:: Debug ,
4853{
49- debug_fmt_fields ! ( Permutations , vals, state) ;
54+ debug_fmt_fields ! ( PermutationsGeneric , vals, state) ;
5055}
5156
5257pub 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> {
5661 }
5762}
5863
59- impl < I > Iterator for Permutations < I >
64+ impl < I , Idx : PoolIndex > Iterator for PermutationsGeneric < I , Idx >
6065where
6166 I : Iterator ,
6267 I :: Item : Clone ,
@@ -67,39 +72,39 @@ where
6772 let Self { vals, state } = self ;
6873 match state {
6974 & mut PermutationState :: Start { k } => {
70- if k == 0 {
75+ if k. value ( ) == 0 {
7176 * state = PermutationState :: End ;
7277 } else {
73- vals. prefill ( k) ;
74- if vals. len ( ) != k {
78+ vals. prefill ( k. value ( ) ) ;
79+ if vals. len ( ) != k. value ( ) {
7580 * state = PermutationState :: End ;
7681 return None ;
7782 }
78- * state = PermutationState :: Buffered { k, min_n : k } ;
83+ * state = PermutationState :: Buffered { k, min_n : k. value ( ) } ;
7984 }
80- Some ( vals[ 0 ..k] . to_vec ( ) )
85+ Some ( vals[ 0 ..k. value ( ) ] . to_vec ( ) )
8186 }
8287 PermutationState :: Buffered { ref k, min_n } => {
8388 if vals. get_next ( ) {
84- let item = ( 0 ..* k - 1 )
89+ let item = ( 0 ..k . value ( ) - 1 )
8590 . chain ( once ( * min_n) )
8691 . map ( |i| vals[ i] . clone ( ) )
8792 . collect ( ) ;
8893 * min_n += 1 ;
8994 Some ( item)
9095 } else {
9196 let n = * min_n;
92- let prev_iteration_count = n - * k + 1 ;
97+ let prev_iteration_count = n - k . value ( ) + 1 ;
9398 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 ( ) ;
95100 // Advance the state to the correct point.
96101 for _ in 0 ..prev_iteration_count {
97102 if advance ( & mut indices, & mut cycles) {
98103 * state = PermutationState :: End ;
99104 return None ;
100105 }
101106 }
102- let item = vals. get_at ( & indices[ 0 ..* k ] ) ;
107+ let item = vals. get_at ( & indices[ 0 ..k . value ( ) ] ) ;
103108 * state = PermutationState :: Loaded { indices, cycles } ;
104109 Some ( item)
105110 }
@@ -130,7 +135,7 @@ where
130135 }
131136}
132137
133- impl < I > FusedIterator for Permutations < I >
138+ impl < I , Idx : PoolIndex > FusedIterator for PermutationsGeneric < I , Idx >
134139where
135140 I : Iterator ,
136141 I :: Item : Clone ,
@@ -155,20 +160,20 @@ fn advance(indices: &mut [usize], cycles: &mut [usize]) -> bool {
155160 true
156161}
157162
158- impl PermutationState {
163+ impl < Idx : PoolIndex > PermutationState < Idx > {
159164 fn size_hint_for ( & self , n : usize ) -> SizeHint {
160165 // 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) ) ;
164169 ( total. unwrap_or ( usize:: MAX ) , total)
165170 } ;
166171 match * self {
167- Self :: Start { k } if n < k => ( 0 , Some ( 0 ) ) ,
172+ Self :: Start { k } if n < k. value ( ) => ( 0 , Some ( 0 ) ) ,
168173 Self :: Start { k } => at_start ( n, k) ,
169174 Self :: Buffered { k, min_n } => {
170175 // 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 )
172177 }
173178 Self :: Loaded {
174179 ref indices,
0 commit comments