1use crate::fmt;
2use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
3use crate::mem::MaybeUninit;
4use crate::num::NonZero;
5use crate::ops::{NeverShortCircuit, Try};
67/// Creates a new iterator that repeats a single element a given number of times.
8///
9/// The `repeat_n()` function repeats a single value exactly `n` times.
10///
11/// This is very similar to using [`repeat()`] with [`Iterator::take()`],
12/// but `repeat_n()` can return the original value, rather than always cloning.
13///
14/// [`repeat()`]: crate::iter::repeat
15///
16/// # Examples
17///
18/// Basic usage:
19///
20/// ```
21/// use std::iter;
22///
23/// // four of the number four:
24/// let mut four_fours = iter::repeat_n(4, 4);
25///
26/// assert_eq!(Some(4), four_fours.next());
27/// assert_eq!(Some(4), four_fours.next());
28/// assert_eq!(Some(4), four_fours.next());
29/// assert_eq!(Some(4), four_fours.next());
30///
31/// // no more fours
32/// assert_eq!(None, four_fours.next());
33/// ```
34///
35/// For non-`Copy` types,
36///
37/// ```
38/// use std::iter;
39///
40/// let v: Vec<i32> = Vec::with_capacity(123);
41/// let mut it = iter::repeat_n(v, 5);
42///
43/// for i in 0..4 {
44/// // It starts by cloning things
45/// let cloned = it.next().unwrap();
46/// assert_eq!(cloned.len(), 0);
47/// assert_eq!(cloned.capacity(), 0);
48/// }
49///
50/// // ... but the last item is the original one
51/// let last = it.next().unwrap();
52/// assert_eq!(last.len(), 0);
53/// assert_eq!(last.capacity(), 123);
54///
55/// // ... and now we're done
56/// assert_eq!(None, it.next());
57/// ```
58#[inline]
59#[stable(feature = "iter_repeat_n", since = "1.82.0")]
60pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
61let element = if count == 0 {
62// `element` gets dropped eagerly.
63MaybeUninit::uninit()
64 } else {
65 MaybeUninit::new(element)
66 };
6768 RepeatN { element, count }
69}
7071/// An iterator that repeats an element an exact number of times.
72///
73/// This `struct` is created by the [`repeat_n()`] function.
74/// See its documentation for more.
75#[stable(feature = "iter_repeat_n", since = "1.82.0")]
76pub struct RepeatN<A> {
77 count: usize,
78// Invariant: uninit iff count == 0.
79element: MaybeUninit<A>,
80}
8182impl<A> RepeatN<A> {
83/// Returns the element if it hasn't been dropped already.
84fn element_ref(&self) -> Option<&A> {
85if self.count > 0 {
86// SAFETY: The count is non-zero, so it must be initialized.
87Some(unsafe { self.element.assume_init_ref() })
88 } else {
89None
90}
91 }
92/// If we haven't already dropped the element, return it in an option.
93 ///
94 /// Clears the count so it won't be dropped again later.
95#[inline]
96fn take_element(&mut self) -> Option<A> {
97if self.count > 0 {
98self.count = 0;
99// SAFETY: We just set count to zero so it won't be dropped again,
100 // and it used to be non-zero so it hasn't already been dropped.
101let element = unsafe { self.element.assume_init_read() };
102Some(element)
103 } else {
104None
105}
106 }
107}
108109#[stable(feature = "iter_repeat_n", since = "1.82.0")]
110impl<A: Clone> Clone for RepeatN<A> {
111fn clone(&self) -> RepeatN<A> {
112 RepeatN {
113 count: self.count,
114 element: self.element_ref().cloned().map_or_else(MaybeUninit::uninit, MaybeUninit::new),
115 }
116 }
117}
118119#[stable(feature = "iter_repeat_n", since = "1.82.0")]
120impl<A: fmt::Debug> fmt::Debug for RepeatN<A> {
121fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 f.debug_struct("RepeatN")
123 .field("count", &self.count)
124 .field("element", &self.element_ref())
125 .finish()
126 }
127}
128129#[stable(feature = "iter_repeat_n", since = "1.82.0")]
130impl<A> Drop for RepeatN<A> {
131fn drop(&mut self) {
132self.take_element();
133 }
134}
135136#[stable(feature = "iter_repeat_n", since = "1.82.0")]
137impl<A: Clone> Iterator for RepeatN<A> {
138type Item = A;
139140#[inline]
141fn next(&mut self) -> Option<A> {
142if self.count > 0 {
143// SAFETY: Just checked it's not empty
144unsafe { Some(self.next_unchecked()) }
145 } else {
146None
147}
148 }
149150#[inline]
151fn size_hint(&self) -> (usize, Option<usize>) {
152let len = self.len();
153 (len, Some(len))
154 }
155156#[inline]
157fn advance_by(&mut self, skip: usize) -> Result<(), NonZero<usize>> {
158let len = self.count;
159160if skip >= len {
161self.take_element();
162 }
163164if skip > len {
165// SAFETY: we just checked that the difference is positive
166Err(unsafe { NonZero::new_unchecked(skip - len) })
167 } else {
168self.count = len - skip;
169Ok(())
170 }
171 }
172173fn try_fold<B, F, R>(&mut self, mut acc: B, mut f: F) -> R
174where
175F: FnMut(B, A) -> R,
176 R: Try<Output = B>,
177 {
178if self.count > 0 {
179while self.count > 1 {
180self.count -= 1;
181// SAFETY: the count was larger than 1, so the element is
182 // initialized and hasn't been dropped.
183acc = f(acc, unsafe { self.element.assume_init_ref().clone() })?;
184 }
185186// We could just set the count to zero directly, but doing it this
187 // way should make it easier for the optimizer to fold this tail
188 // into the loop when `clone()` is equivalent to copying.
189self.count -= 1;
190// SAFETY: we just set the count to zero from one, so the element
191 // is still initialized, has not been dropped yet and will not be
192 // accessed by future calls.
193f(acc, unsafe { self.element.assume_init_read() })
194 } else {
195try { acc }
196 }
197 }
198199fn fold<B, F>(mut self, init: B, f: F) -> B
200where
201F: FnMut(B, A) -> B,
202 {
203self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
204}
205206#[inline]
207fn last(mut self) -> Option<A> {
208self.take_element()
209 }
210211#[inline]
212fn count(self) -> usize {
213self.len()
214 }
215}
216217#[stable(feature = "iter_repeat_n", since = "1.82.0")]
218impl<A: Clone> ExactSizeIterator for RepeatN<A> {
219fn len(&self) -> usize {
220self.count
221 }
222}
223224#[stable(feature = "iter_repeat_n", since = "1.82.0")]
225impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
226#[inline]
227fn next_back(&mut self) -> Option<A> {
228self.next()
229 }
230231#[inline]
232fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
233self.advance_by(n)
234 }
235236#[inline]
237fn nth_back(&mut self, n: usize) -> Option<A> {
238self.nth(n)
239 }
240241#[inline]
242fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
243where
244F: FnMut(B, A) -> R,
245 R: Try<Output = B>,
246 {
247self.try_fold(init, f)
248 }
249250#[inline]
251fn rfold<B, F>(self, init: B, f: F) -> B
252where
253F: FnMut(B, A) -> B,
254 {
255self.fold(init, f)
256 }
257}
258259#[stable(feature = "iter_repeat_n", since = "1.82.0")]
260impl<A: Clone> FusedIterator for RepeatN<A> {}
261262#[unstable(feature = "trusted_len", issue = "37572")]
263unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
264#[stable(feature = "iter_repeat_n", since = "1.82.0")]
265impl<A: Clone> UncheckedIterator for RepeatN<A> {
266#[inline]
267unsafe fn next_unchecked(&mut self) -> Self::Item {
268// SAFETY: The caller promised the iterator isn't empty
269self.count = unsafe { self.count.unchecked_sub(1) };
270if self.count == 0 {
271// SAFETY: the check above ensured that the count used to be non-zero,
272 // so element hasn't been dropped yet, and we just lowered the count to
273 // zero so it won't be dropped later, and thus it's okay to take it here.
274unsafe { self.element.assume_init_read() }
275 } else {
276// SAFETY: the count is non-zero, so it must have not been dropped yet.
277let element = unsafe { self.element.assume_init_ref() };
278 A::clone(element)
279 }
280 }
281}