1//! Macros for delegating newtype iterators to inner types.
2
3// Note: these place `impl` bounds at the end, as token gobbling is the only way
4// I know how to consume an arbitrary list of constraints, with `$($args:tt)*`.
5
6/// Creates a parallel iterator implementation which simply wraps an inner type
7/// and delegates all methods inward. The actual struct must already be
8/// declared with an `inner` field.
9///
10/// The implementation of `IntoParallelIterator` should be added separately.
11macro_rules! delegate_iterator {
12 ($iter:ty => $item:ty ,
13 impl $( $args:tt )*
14 ) => {
15 impl $( $args )* ParallelIterator for $iter {
16 type Item = $item;
17
18 fn drive_unindexed<C>(self, consumer: C) -> C::Result
19 where C: UnindexedConsumer<Self::Item>
20 {
21 self.inner.drive_unindexed(consumer)
22 }
23
24 fn opt_len(&self) -> Option<usize> {
25 self.inner.opt_len()
26 }
27 }
28 }
29}
30
31/// Creates an indexed parallel iterator implementation which simply wraps an
32/// inner type and delegates all methods inward. The actual struct must already
33/// be declared with an `inner` field.
34macro_rules! delegate_indexed_iterator {
35 ($iter:ty => $item:ty ,
36 impl $( $args:tt )*
37 ) => {
38 delegate_iterator!{
39 $iter => $item ,
40 impl $( $args )*
41 }
42
43 impl $( $args )* IndexedParallelIterator for $iter {
44 fn drive<C>(self, consumer: C) -> C::Result
45 where C: Consumer<Self::Item>
46 {
47 self.inner.drive(consumer)
48 }
49
50 fn len(&self) -> usize {
51 self.inner.len()
52 }
53
54 fn with_producer<CB>(self, callback: CB) -> CB::Output
55 where CB: ProducerCallback<Self::Item>
56 {
57 self.inner.with_producer(callback)
58 }
59 }
60 }
61}
62
63#[test]
64fn unindexed_example() {
65 use crate::collections::btree_map::IntoIter;
66 use crate::iter::plumbing::*;
67 use crate::prelude::*;
68
69 use std::collections::BTreeMap;
70
71 struct MyIntoIter<T: Ord + Send, U: Send> {
72 inner: IntoIter<T, U>,
73 }
74
75 delegate_iterator! {
76 MyIntoIter<T, U> => (T, U),
77 impl<T: Ord + Send, U: Send>
78 }
79
80 let map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]);
81 let iter = MyIntoIter {
82 inner: map.into_par_iter(),
83 };
84 let vec: Vec<_> = iter.map(|(k, _)| k).collect();
85 assert_eq!(vec, &[1, 2, 3]);
86}
87
88#[test]
89fn indexed_example() {
90 use crate::iter::plumbing::*;
91 use crate::prelude::*;
92 use crate::vec::IntoIter;
93
94 struct MyIntoIter<T: Send> {
95 inner: IntoIter<T>,
96 }
97
98 delegate_indexed_iterator! {
99 MyIntoIter<T> => T,
100 impl<T: Send>
101 }
102
103 let iter = MyIntoIter {
104 inner: vec![1, 2, 3].into_par_iter(),
105 };
106 let mut vec = vec![];
107 iter.collect_into_vec(&mut vec);
108 assert_eq!(vec, &[1, 2, 3]);
109}
110