1 macro_rules! clone_fields {
2     ($name:ident, $($field:ident),+ $(,)*) => (
3         fn clone(&self) -> Self {
4             $name {
5                 $(
6                     $field : self . $field .clone()
7                 ),*
8             }
9         }
10     );
11 }
12 
13 macro_rules! iterator_wrap {
14     (impl () for
15     struct $name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
16      item: $item: ty,
17      iter: $iter: ty,
18      ) => ();
19     (
20     impl (Iterator $($rest:tt)*)  for
21     $(#[$derive:meta])*
22      struct $name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
23      item: $item: ty,
24      iter: $iter: ty,
25      ) => (
26         // having complex iterator types is kind of the point of this macro
27         #[allow(clippy::type_complexity)]
28         $(#[$derive])*
29         pub struct $name <$($typarm),*> where $($bounds)* {
30             iter: $iter,
31         }
32         impl<$($typarm),*> Iterator for $name <$($typarm),*>
33             where $($bounds)*
34         {
35             type Item = $item;
36             #[inline]
37             fn next(&mut self) -> Option<Self::Item> {
38                 self.iter.next()
39             }
40 
41             #[inline]
42             fn size_hint(&self) -> (usize, Option<usize>) {
43                 self.iter.size_hint()
44             }
45         }
46         iterator_wrap!(
47             impl ($($rest)*)  for
48             struct $name <$($typarm),*> where { $($bounds)* }
49             item: $item,
50             iter: $iter,
51             );
52         );
53 
54     (
55 impl (ExactSizeIterator $($rest:tt)*)  for
56     $(#[$derive:meta])*
57      struct $name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
58      item: $item: ty,
59      iter: $iter: ty,
60      ) => (
61         impl<$($typarm),*> ExactSizeIterator for $name <$($typarm),*>
62             where $($bounds)*
63         {
64             #[inline]
65             fn len(&self) -> usize {
66                 self.iter.len()
67             }
68         }
69         iterator_wrap!(
70             impl ($($rest)*)  for
71          $(#[$derive])*
72             struct $name <$($typarm),*> where { $($bounds)* }
73             item: $item,
74             iter: $iter,
75             );
76     );
77 
78     (
79 impl (DoubleEndedIterator $($rest:tt)*)  for
80     $(#[$derive:meta])*
81      struct $name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
82      item: $item: ty,
83      iter: $iter: ty,
84      ) => (
85         impl<$($typarm),*> DoubleEndedIterator for $name <$($typarm),*>
86             where $($bounds)*
87         {
88             fn next_back(&mut self) -> Option<Self::Item> {
89                 self.iter.next_back()
90             }
91             fn rfold<B, F>(self, accum: B, f: F) -> B
92                 where
93                     F: FnMut(B, Self::Item) -> B,
94                 { self.iter.rfold(accum, f) }
95             fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
96                 where
97                     P: FnMut(&Self::Item) -> bool,
98                 { self.iter.rfind(predicate) }
99         }
100         iterator_wrap!(
101             impl ($($rest)*)  for
102          $(#[$derive])*
103            struct $name <$($typarm),*> where { $($bounds)* }
104             item: $item,
105             iter: $iter,
106             );
107     );
108 }
109