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}