core/iter/sources/
repeat_n.rs1use crate::fmt;
2use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
3use crate::num::NonZero;
4use crate::ops::Try;
5
6#[inline]
58#[stable(feature = "iter_repeat_n", since = "1.82.0")]
59pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
60    RepeatN { inner: RepeatNInner::new(element, count) }
61}
62
63#[derive(Clone, Copy)]
64struct RepeatNInner<T> {
65    count: NonZero<usize>,
66    element: T,
67}
68
69impl<T> RepeatNInner<T> {
70    fn new(element: T, count: usize) -> Option<Self> {
71        let count = NonZero::<usize>::new(count)?;
72        Some(Self { element, count })
73    }
74}
75
76#[stable(feature = "iter_repeat_n", since = "1.82.0")]
81#[derive(Clone)]
82pub struct RepeatN<A> {
83    inner: Option<RepeatNInner<A>>,
84}
85
86impl<A> RepeatN<A> {
87    #[inline]
89    fn take_element(&mut self) -> Option<A> {
90        self.inner.take().map(|inner| inner.element)
91    }
92}
93
94#[stable(feature = "iter_repeat_n", since = "1.82.0")]
95impl<A: fmt::Debug> fmt::Debug for RepeatN<A> {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        let (count, element) = match self.inner.as_ref() {
98            Some(inner) => (inner.count.get(), Some(&inner.element)),
99            None => (0, None),
100        };
101        f.debug_struct("RepeatN").field("count", &count).field("element", &element).finish()
102    }
103}
104
105#[stable(feature = "iter_repeat_n", since = "1.82.0")]
106impl<A: Clone> Iterator for RepeatN<A> {
107    type Item = A;
108
109    #[inline]
110    fn next(&mut self) -> Option<A> {
111        let inner = self.inner.as_mut()?;
112        let count = inner.count.get();
113
114        if let Some(decremented) = NonZero::<usize>::new(count - 1) {
115            let tmp = inner.element.clone();
117            inner.count = decremented;
118            return Some(tmp);
119        }
120
121        return self.take_element();
122    }
123
124    #[inline]
125    fn size_hint(&self) -> (usize, Option<usize>) {
126        let len = self.len();
127        (len, Some(len))
128    }
129
130    #[inline]
131    fn advance_by(&mut self, skip: usize) -> Result<(), NonZero<usize>> {
132        let Some(inner) = self.inner.as_mut() else {
133            return NonZero::<usize>::new(skip).map(Err).unwrap_or(Ok(()));
134        };
135
136        let len = inner.count.get();
137
138        if let Some(new_len) = len.checked_sub(skip).and_then(NonZero::<usize>::new) {
139            inner.count = new_len;
140            return Ok(());
141        }
142
143        self.inner = None;
144        return NonZero::<usize>::new(skip - len).map(Err).unwrap_or(Ok(()));
145    }
146
147    #[inline]
148    fn last(mut self) -> Option<A> {
149        self.take_element()
150    }
151
152    #[inline]
153    fn count(self) -> usize {
154        self.len()
155    }
156}
157
158#[stable(feature = "iter_repeat_n", since = "1.82.0")]
159impl<A: Clone> ExactSizeIterator for RepeatN<A> {
160    fn len(&self) -> usize {
161        self.inner.as_ref().map(|inner| inner.count.get()).unwrap_or(0)
162    }
163}
164
165#[stable(feature = "iter_repeat_n", since = "1.82.0")]
166impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
167    #[inline]
168    fn next_back(&mut self) -> Option<A> {
169        self.next()
170    }
171
172    #[inline]
173    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
174        self.advance_by(n)
175    }
176
177    #[inline]
178    fn nth_back(&mut self, n: usize) -> Option<A> {
179        self.nth(n)
180    }
181
182    #[inline]
183    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
184    where
185        F: FnMut(B, A) -> R,
186        R: Try<Output = B>,
187    {
188        self.try_fold(init, f)
189    }
190
191    #[inline]
192    fn rfold<B, F>(self, init: B, f: F) -> B
193    where
194        F: FnMut(B, A) -> B,
195    {
196        self.fold(init, f)
197    }
198}
199
200#[stable(feature = "iter_repeat_n", since = "1.82.0")]
201impl<A: Clone> FusedIterator for RepeatN<A> {}
202
203#[unstable(feature = "trusted_len", issue = "37572")]
204unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
205#[stable(feature = "iter_repeat_n", since = "1.82.0")]
206impl<A: Clone> UncheckedIterator for RepeatN<A> {}