core/iter/sources/
repeat_n.rs1use crate::fmt;
2use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
3use crate::mem::{self, MaybeUninit};
4use crate::num::NonZero;
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    let element = if count == 0 {
61        MaybeUninit::uninit()
63    } else {
64        MaybeUninit::new(element)
65    };
66
67    RepeatN { element, count }
68}
69
70#[stable(feature = "iter_repeat_n", since = "1.82.0")]
75pub struct RepeatN<A> {
76    count: usize,
77    element: MaybeUninit<A>,
79}
80
81impl<A> RepeatN<A> {
82    fn element_ref(&self) -> Option<&A> {
84        if self.count > 0 {
85            Some(unsafe { self.element.assume_init_ref() })
87        } else {
88            None
89        }
90    }
91    #[inline]
95    fn take_element(&mut self) -> Option<A> {
96        if self.count > 0 {
97            self.count = 0;
98            let element = mem::replace(&mut self.element, MaybeUninit::uninit());
99            unsafe { Some(element.assume_init()) }
102        } else {
103            None
104        }
105    }
106}
107
108#[stable(feature = "iter_repeat_n", since = "1.82.0")]
109impl<A: Clone> Clone for RepeatN<A> {
110    fn clone(&self) -> RepeatN<A> {
111        RepeatN {
112            count: self.count,
113            element: self.element_ref().cloned().map_or_else(MaybeUninit::uninit, MaybeUninit::new),
114        }
115    }
116}
117
118#[stable(feature = "iter_repeat_n", since = "1.82.0")]
119impl<A: fmt::Debug> fmt::Debug for RepeatN<A> {
120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121        f.debug_struct("RepeatN")
122            .field("count", &self.count)
123            .field("element", &self.element_ref())
124            .finish()
125    }
126}
127
128#[stable(feature = "iter_repeat_n", since = "1.82.0")]
129impl<A> Drop for RepeatN<A> {
130    fn drop(&mut self) {
131        self.take_element();
132    }
133}
134
135#[stable(feature = "iter_repeat_n", since = "1.82.0")]
136impl<A: Clone> Iterator for RepeatN<A> {
137    type Item = A;
138
139    #[inline]
140    fn next(&mut self) -> Option<A> {
141        if self.count > 0 {
142            unsafe { Some(self.next_unchecked()) }
144        } else {
145            None
146        }
147    }
148
149    #[inline]
150    fn size_hint(&self) -> (usize, Option<usize>) {
151        let len = self.len();
152        (len, Some(len))
153    }
154
155    #[inline]
156    fn advance_by(&mut self, skip: usize) -> Result<(), NonZero<usize>> {
157        let len = self.count;
158
159        if skip >= len {
160            self.take_element();
161        }
162
163        if skip > len {
164            Err(unsafe { NonZero::new_unchecked(skip - len) })
166        } else {
167            self.count = len - skip;
168            Ok(())
169        }
170    }
171
172    #[inline]
173    fn last(mut self) -> Option<A> {
174        self.take_element()
175    }
176
177    #[inline]
178    fn count(self) -> usize {
179        self.len()
180    }
181}
182
183#[stable(feature = "iter_repeat_n", since = "1.82.0")]
184impl<A: Clone> ExactSizeIterator for RepeatN<A> {
185    fn len(&self) -> usize {
186        self.count
187    }
188}
189
190#[stable(feature = "iter_repeat_n", since = "1.82.0")]
191impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
192    #[inline]
193    fn next_back(&mut self) -> Option<A> {
194        self.next()
195    }
196
197    #[inline]
198    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
199        self.advance_by(n)
200    }
201
202    #[inline]
203    fn nth_back(&mut self, n: usize) -> Option<A> {
204        self.nth(n)
205    }
206}
207
208#[stable(feature = "iter_repeat_n", since = "1.82.0")]
209impl<A: Clone> FusedIterator for RepeatN<A> {}
210
211#[unstable(feature = "trusted_len", issue = "37572")]
212unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
213#[stable(feature = "iter_repeat_n", since = "1.82.0")]
214impl<A: Clone> UncheckedIterator for RepeatN<A> {
215    #[inline]
216    unsafe fn next_unchecked(&mut self) -> Self::Item {
217        self.count = unsafe { self.count.unchecked_sub(1) };
219        if self.count == 0 {
220            unsafe { mem::replace(&mut self.element, MaybeUninit::uninit()).assume_init() }
224        } else {
225            let element = unsafe { self.element.assume_init_ref() };
227            A::clone(element)
228        }
229    }
230}