konst/iter/
iterator_adaptors.rs

1use crate::iter::{ConstIntoIter, IsIteratorKind};
2
3/// Const analog of [`core::iter::repeat`],
4/// except that this requires the repeated value to impl `Copy`
5/// (instead of `Clone`).
6///
7/// # Example
8///
9/// ```rust
10/// use konst::iter::{self, collect_const};
11///
12/// const ARR: &[u8] = &collect_const!(u8 => iter::repeat(3),take(5));
13///
14/// assert_eq!(ARR, &[3, 3, 3, 3, 3]);
15/// ```
16pub const fn repeat<T: Copy>(val: T) -> Repeat<T> {
17    Repeat(val)
18}
19
20/// Const analog of [`core::iter::Repeat`],
21/// constructed by [`repeat`](crate::iter::repeat).
22pub struct Repeat<T>(T);
23
24impl<T> ConstIntoIter for Repeat<T> {
25    type Kind = IsIteratorKind;
26    type IntoIter = Self;
27    type Item = T;
28
29    // since the constructor requires T: Copy, it doesn't need dropping
30    const ITEMS_NEED_DROP: bool = false;
31}
32
33impl<T: Copy> Repeat<T> {
34    /// Gets the next element in the iterator
35    pub const fn next(&mut self) -> Option<T> {
36        Some(self.0)
37    }
38    /// Gets the next element in the iterator
39    pub const fn next_back(&mut self) -> Option<T> {
40        Some(self.0)
41    }
42    /// Reverses the iterator
43    pub const fn rev(self) -> Self {
44        self
45    }
46    /// Clones the iterator
47    pub const fn copy(&self) -> Self {
48        Self(self.0)
49    }
50}
51
52/////////////////////////////////////////////////////
53
54/// Const analog of [`core::iter::repeat_n`],
55/// except that this requires the repeated value to impl `Copy`
56/// (instead of `Clone`).
57///
58/// # Example
59///
60/// ```rust
61/// use konst::iter::{self, collect_const};
62///
63/// const ARR: &[u8] = &collect_const!(u8 => iter::repeat_n(8, 3));
64///
65/// assert_eq!(ARR, &[8, 8, 8]);
66/// ```
67pub const fn repeat_n<T: Copy>(val: T, count: usize) -> RepeatN<T> {
68    RepeatN { val, count }
69}
70
71/// Const analog of [`core::iter::RepeatN`],
72/// constructed by [`repeat_n`](crate::iter::repeat_n).
73pub struct RepeatN<T> {
74    val: T,
75    count: usize,
76}
77
78impl<T> ConstIntoIter for RepeatN<T> {
79    type Kind = IsIteratorKind;
80    type IntoIter = Self;
81    type Item = T;
82
83    // since the constructor requires T: Copy, it doesn't need dropping
84    const ITEMS_NEED_DROP: bool = false;
85}
86
87impl<T: Copy> RepeatN<T> {
88    /// Gets the next element in the iterator
89    pub const fn next(&mut self) -> Option<T> {
90        if let Some(ncount) = self.count.checked_sub(1) {
91            self.count = ncount;
92            Some(self.val)
93        } else {
94            None
95        }
96    }
97    /// Gets the next element in the iterator
98    pub const fn next_back(&mut self) -> Option<T> {
99        self.next()
100    }
101    /// Reverses the iterator
102    pub const fn rev(self) -> Self {
103        self
104    }
105    /// Clones the iterator
106    pub const fn copy(&self) -> Self {
107        Self { ..*self }
108    }
109}