Skip to content

Commit 79f52b2

Browse files
committed
Move MaybeConstUsize, PoolIndex to lazy_buffer
1 parent 98b79de commit 79f52b2

File tree

3 files changed

+90
-86
lines changed

3 files changed

+90
-86
lines changed

src/combinations.rs

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use core::array;
2-
use core::borrow::BorrowMut;
32
use std::fmt;
43
use std::iter::FusedIterator;
54

6-
use super::lazy_buffer::LazyBuffer;
5+
use super::lazy_buffer::{LazyBuffer, PoolIndex};
76
use alloc::vec::Vec;
87

98
use crate::adaptors::checked_binomial;
9+
use crate::lazy_buffer::MaybeConstUsize as _;
1010

1111
/// Iterator for `Vec` valued combinations returned by [`.combinations()`](crate::Itertools::combinations)
1212
pub type Combinations<I> = CombinationsGeneric<I, Vec<usize>>;
@@ -39,79 +39,6 @@ pub struct CombinationsGeneric<I: Iterator, Idx> {
3939
first: bool,
4040
}
4141

42-
pub trait MaybeConstUsize : Clone + Copy + std::fmt::Debug {
43-
/*TODO const*/fn value(self) -> usize;
44-
}
45-
46-
#[derive(Clone, Copy, Debug)]
47-
pub struct ConstUsize<const N: usize>;
48-
impl<const N: usize> MaybeConstUsize for ConstUsize<N> {
49-
fn value(self) -> usize {
50-
N
51-
}
52-
}
53-
54-
impl MaybeConstUsize for usize {
55-
fn value(self) -> usize {
56-
self
57-
}
58-
}
59-
60-
/// A type holding indices of elements in a pool or buffer of items from an inner iterator
61-
/// and used to pick out different combinations in a generic way.
62-
pub trait PoolIndex: BorrowMut<[usize]> {
63-
type Item<T>;
64-
type Length: MaybeConstUsize;
65-
66-
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
67-
where
68-
I::Item: Clone;
69-
70-
fn from_fn<T, F: Fn(usize)->T>(k: Self::Length, f: F) -> Self::Item<T>;
71-
72-
fn len(&self) -> Self::Length;
73-
}
74-
75-
impl PoolIndex for Vec<usize> {
76-
type Item<T> = Vec<T>;
77-
type Length = usize;
78-
79-
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
80-
where
81-
I::Item: Clone
82-
{
83-
pool.get_at(self)
84-
}
85-
86-
fn from_fn<T, F: Fn(usize)->T>(k: Self::Length, f: F) -> Self::Item<T> {
87-
(0..k).map(f).collect()
88-
}
89-
90-
fn len(&self) -> Self::Length {
91-
self.len()
92-
}
93-
}
94-
95-
impl<const K: usize> PoolIndex for [usize; K] {
96-
type Item<T> = [T; K];
97-
type Length = ConstUsize<K>;
98-
99-
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
100-
where
101-
I::Item: Clone
102-
{
103-
pool.get_array(*self)
104-
}
105-
106-
fn from_fn<T, F: Fn(usize)->T>(_k: Self::Length, f: F) -> Self::Item<T> {
107-
std::array::from_fn(f)
108-
}
109-
110-
fn len(&self) -> Self::Length {
111-
ConstUsize::<K>
112-
}
113-
}
114-
11542
impl<I, Idx> Clone for CombinationsGeneric<I, Idx>
11643
where
11744
I: Iterator + Clone,

src/lazy_buffer.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use alloc::vec::Vec;
2+
use core::borrow::BorrowMut;
23
use std::iter::Fuse;
34
use std::ops::Index;
45

@@ -77,3 +78,77 @@ where
7778
self.buffer.index(index)
7879
}
7980
}
81+
82+
pub trait MaybeConstUsize: Clone + Copy + std::fmt::Debug {
83+
/*TODO const*/
84+
fn value(self) -> usize;
85+
}
86+
87+
#[derive(Clone, Copy, Debug)]
88+
pub struct ConstUsize<const N: usize>;
89+
impl<const N: usize> MaybeConstUsize for ConstUsize<N> {
90+
fn value(self) -> usize {
91+
N
92+
}
93+
}
94+
95+
impl MaybeConstUsize for usize {
96+
fn value(self) -> usize {
97+
self
98+
}
99+
}
100+
101+
/// A type holding indices of elements in a pool or buffer of items from an inner iterator
102+
/// and used to pick out different combinations in a generic way.
103+
pub trait PoolIndex: BorrowMut<[usize]> {
104+
type Item<T>;
105+
type Length: MaybeConstUsize;
106+
107+
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
108+
where
109+
I::Item: Clone;
110+
111+
fn from_fn<T, F: Fn(usize) -> T>(k: Self::Length, f: F) -> Self::Item<T>;
112+
113+
fn len(&self) -> Self::Length;
114+
}
115+
116+
impl PoolIndex for Vec<usize> {
117+
type Item<T> = Vec<T>;
118+
type Length = usize;
119+
120+
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
121+
where
122+
I::Item: Clone,
123+
{
124+
pool.get_at(self)
125+
}
126+
127+
fn from_fn<T, F: Fn(usize) -> T>(k: Self::Length, f: F) -> Self::Item<T> {
128+
(0..k).map(f).collect()
129+
}
130+
131+
fn len(&self) -> Self::Length {
132+
self.len()
133+
}
134+
}
135+
136+
impl<const K: usize> PoolIndex for [usize; K] {
137+
type Item<T> = [T; K];
138+
type Length = ConstUsize<K>;
139+
140+
fn extract_item<I: Iterator>(&self, pool: &LazyBuffer<I>) -> Self::Item<I::Item>
141+
where
142+
I::Item: Clone,
143+
{
144+
pool.get_array(*self)
145+
}
146+
147+
fn from_fn<T, F: Fn(usize) -> T>(_k: Self::Length, f: F) -> Self::Item<T> {
148+
std::array::from_fn(f)
149+
}
150+
151+
fn len(&self) -> Self::Length {
152+
ConstUsize::<K>
153+
}
154+
}

src/permutations.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ use alloc::vec::Vec;
33
use std::fmt;
44
use std::iter::FusedIterator;
55

6-
use super::lazy_buffer::LazyBuffer;
6+
use super::lazy_buffer::{LazyBuffer, MaybeConstUsize as _, PoolIndex};
77
use crate::size_hint::{self, SizeHint};
8-
use crate::combinations::{MaybeConstUsize, PoolIndex};
98

109
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
1110
pub struct PermutationsGeneric<I: Iterator, Idx: PoolIndex> {
@@ -39,7 +38,7 @@ enum PermutationState<Idx: PoolIndex> {
3938
Loaded {
4039
indices: Box<[usize]>,
4140
cycles: Box<[usize]>, // TODO Should be Idx::Item<usize>
42-
k: Idx::Length, // TODO Should be inferred from cycles
41+
k: Idx::Length, // TODO Should be inferred from cycles
4342
},
4443
/// No permutation left to generate.
4544
End,
@@ -80,19 +79,18 @@ where
8079
*state = PermutationState::End;
8180
return None;
8281
}
83-
*state = PermutationState::Buffered { k, min_n: k.value() };
82+
*state = PermutationState::Buffered {
83+
k,
84+
min_n: k.value(),
85+
};
8486
}
8587
Some(Idx::from_fn(k, |i| vals[i].clone()))
8688
}
8789
PermutationState::Buffered { k, min_n } => {
8890
if vals.get_next() {
8991
// TODO This is ugly. Maybe working on indices is better?
9092
let item = Idx::from_fn(*k, |i| {
91-
vals[if i==k.value()-1 {
92-
*min_n
93-
} else {
94-
i
95-
}].clone()
93+
vals[if i == k.value() - 1 { *min_n } else { i }].clone()
9694
});
9795
*min_n += 1;
9896
Some(item)
@@ -109,11 +107,15 @@ where
109107
}
110108
}
111109
let item = Idx::from_fn(*k, |i| vals[indices[i]].clone());
112-
*state = PermutationState::Loaded { indices, cycles, k:*k };
110+
*state = PermutationState::Loaded {
111+
indices,
112+
cycles,
113+
k: *k,
114+
};
113115
Some(item)
114116
}
115117
}
116-
PermutationState::Loaded { indices, cycles, k} => {
118+
PermutationState::Loaded { indices, cycles, k } => {
117119
if advance(indices, cycles) {
118120
*state = PermutationState::End;
119121
return None;

0 commit comments

Comments
 (0)