Skip to main content

orx_concurrent_iter/copied/
con_iter.rs

1use super::chunk_puller::CopiedChunkPuller;
2use crate::{ExactSizeConcurrentIter, concurrent_iter::ConcurrentIter};
3use core::{iter::Copied, marker::PhantomData};
4
5/// A concurrent iterator which copies all elements.
6///
7/// This is useful when you have an iterator over `&T`, but you need an iterator over `T`.
8///
9/// Copied concurrent iterator can be created by calling [`copied`] on a concurrent iterator.
10///
11/// [`copied`]: crate::ConcurrentIter::copied
12pub struct ConIterCopied<'a, I, T>
13where
14    T: Copy,
15    I: ConcurrentIter<Item = &'a T>,
16{
17    con_iter: I,
18    phantom: PhantomData<&'a T>,
19}
20
21unsafe impl<'a, I, T> Sync for ConIterCopied<'a, I, T>
22where
23    T: Copy + Send,
24    I: ConcurrentIter<Item = &'a T>,
25{
26}
27
28impl<'a, I, T> ConIterCopied<'a, I, T>
29where
30    T: Copy,
31    I: ConcurrentIter<Item = &'a T>,
32{
33    pub(crate) fn new(con_iter: I) -> Self {
34        Self {
35            con_iter,
36            phantom: PhantomData,
37        }
38    }
39}
40
41impl<'a, I, T> ConcurrentIter for ConIterCopied<'a, I, T>
42where
43    T: Copy + Send,
44    I: ConcurrentIter<Item = &'a T>,
45{
46    type Item = T;
47
48    type SequentialIter = Copied<I::SequentialIter>;
49
50    type ChunkPuller<'i>
51        = CopiedChunkPuller<'a, T, I::ChunkPuller<'i>>
52    where
53        Self: 'i;
54
55    fn is_source_serialized() -> bool {
56        I::is_source_serialized()
57    }
58
59    fn into_seq_iter(self) -> Self::SequentialIter {
60        self.con_iter.into_seq_iter().copied()
61    }
62
63    fn skip_to_end(&self) {
64        self.con_iter.skip_to_end()
65    }
66
67    fn next(&self) -> Option<Self::Item> {
68        self.con_iter.next().copied()
69    }
70
71    fn next_with_idx(&self) -> Option<(usize, Self::Item)> {
72        self.con_iter.next_with_idx().map(|(i, x)| (i, *x))
73    }
74
75    fn size_hint(&self) -> (usize, Option<usize>) {
76        self.con_iter.size_hint()
77    }
78
79    fn is_completed_when_none_returned(&self) -> bool {
80        true
81    }
82
83    fn chunk_puller(&self, chunk_size: usize) -> Self::ChunkPuller<'_> {
84        self.con_iter.chunk_puller(chunk_size).into()
85    }
86}
87
88impl<'a, I, T> ExactSizeConcurrentIter for ConIterCopied<'a, I, T>
89where
90    T: Copy + Send,
91    I: ExactSizeConcurrentIter<Item = &'a T>,
92{
93    fn len(&self) -> usize {
94        self.con_iter.len()
95    }
96}