Closed
Description
Currently, core::iter::Repeat::nth
calls core::iter::Repeat::next
n
times.
This allows a struct with interior mutability or other global state and a custom clone implementation to observe the number of times it has been cloned.
use std::sync::atomic::{AtomicUsize, Ordering};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
struct X;
impl Clone for X {
fn clone(&self) -> Self {
COUNTER.fetch_add(1, Ordering::SeqCst);
Self
}
}
fn main() {
let mut iter = core::iter::repeat(X);
for _ in 0..10_000 {
let _ = iter.next();
}
println!("counter: {}", COUNTER.load(Ordering::SeqCst));
let _ = iter.nth(555);
println!("counter: {}", COUNTER.load(Ordering::SeqCst));
}
Currently, this program outputs:
counter: 10000
counter: 10556
Would it be possible to override the implementations of some Iterator
methods that have default implementations without breaking any documented contract?
impl<A: Clone> Iterator for Repeat<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> {
Some(self.element.clone())
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
// Advancing an infinite iterator of a single element is a no-op.
let _ = n;
}
#[inline]
fn nth(&mut self, n: usize) -> Option<T> {
let _ = n;
Some(self.element.clone())
}
fn last(self) -> Option<T> {
loop {}
}
fn count(self) -> usize {
loop {}
}
}
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
Some(self.element.clone())
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
// Advancing an infinite iterator of a single element is a no-op.
let _ = n;
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<T> {
let _ = n;
Some(self.element.clone())
}
}