konst_macro_rules/into_iter/
slice_into_iter.rs

1use super::{IntoIterKind, IntoIterWrapper, IsIteratorKind, IsStdKind};
2
3use core::mem::ManuallyDrop;
4
5#[cfg(feature = "rust_1_51")]
6macro_rules! array_impls {
7    ($($tt:tt)*) => {
8        impl<T, const N: usize> IntoIterKind for &[T; N] {
9            type Kind = IsStdKind;
10        }
11
12        impl<T, const N: usize> IntoIterKind for &&[T; N] {
13            type Kind = IsStdKind;
14        }
15
16        impl<'a, T, const N: usize> IntoIterWrapper<&'a [T; N], IsStdKind> {
17            pub const fn const_into_iter(self) -> Iter<'a, T> {
18                Iter {
19                    slice: ManuallyDrop::into_inner(self.iter) as &[T],
20                }
21            }
22        }
23        impl<'a, T, const N: usize> IntoIterWrapper<&&'a [T; N], IsStdKind> {
24            pub const fn const_into_iter(self) -> Iter<'a, T> {
25                Iter {
26                    slice: (*ManuallyDrop::into_inner(self.iter)) as &[T],
27                }
28            }
29        }
30    };
31}
32
33#[cfg(not(feature = "rust_1_51"))]
34macro_rules! array_impls {
35    ($($len:literal),* $(,)* ) => (
36        $(
37            impl<T> IntoIterKind for &[T; $len] {
38                type Kind = IsStdKind;
39            }
40            impl<T> IntoIterKind for &&[T; $len] {
41                type Kind = IsStdKind;
42            }
43
44            impl<'a, T> IntoIterWrapper<&'a [T; $len], IsStdKind> {
45                pub const fn const_into_iter(self) -> Iter<'a, T> {
46                    Iter { slice: ManuallyDrop::into_inner(self.iter) as &[T] }
47                }
48            }
49            impl<'a, T> IntoIterWrapper<&&'a [T; $len], IsStdKind> {
50                pub const fn const_into_iter(self) -> Iter<'a, T> {
51                    Iter { slice: (*ManuallyDrop::into_inner(self.iter)) as &[T] }
52                }
53            }
54        )*
55    )
56}
57
58array_impls! {
59    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
60    16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
61    32,
62}
63
64impl<T> IntoIterKind for &[T] {
65    type Kind = IsStdKind;
66}
67
68impl<'a, T> IntoIterWrapper<&'a [T], IsStdKind> {
69    pub const fn const_into_iter(self) -> Iter<'a, T> {
70        Iter {
71            slice: ManuallyDrop::into_inner(self.iter),
72        }
73    }
74}
75
76impl<T> IntoIterKind for &&[T] {
77    type Kind = IsStdKind;
78}
79
80impl<'a, T> IntoIterWrapper<&&'a [T], IsStdKind> {
81    pub const fn const_into_iter(self) -> Iter<'a, T> {
82        Iter {
83            slice: *ManuallyDrop::into_inner(self.iter),
84        }
85    }
86}
87
88pub const fn iter<T>(slice: &[T]) -> Iter<'_, T> {
89    Iter { slice }
90}
91
92macro_rules! iter_shared {
93    (is_forward = $is_forward:ident) => {
94        iterator_shared! {
95            is_forward = $is_forward,
96            item = &'a T,
97            iter_forward = Iter<'a, T>,
98            iter_reversed = IterRev<'a, T>,
99            next(self) {
100                if let [elem, rem @ ..] = self.slice {
101                    self.slice = rem;
102                    Some((elem, self))
103                } else {
104                    None
105                }
106            },
107            next_back {
108                if let [rem @ .., elem] = self.slice {
109                    self.slice = rem;
110                    Some((elem, self))
111                } else {
112                    None
113                }
114            },
115            fields = {slice},
116        }
117
118        /// Accesses the remaining slice.
119        pub const fn as_slice(&self) -> &'a [T] {
120            self.slice
121        }
122    };
123}
124
125pub struct Iter<'a, T> {
126    slice: &'a [T],
127}
128impl<'a, T> IntoIterKind for Iter<'a, T> {
129    type Kind = IsIteratorKind;
130}
131
132pub struct IterRev<'a, T> {
133    slice: &'a [T],
134}
135impl<'a, T> IntoIterKind for IterRev<'a, T> {
136    type Kind = IsIteratorKind;
137}
138
139impl<'a, T> Iter<'a, T> {
140    iter_shared! {is_forward = true}
141}
142
143impl<'a, T> IterRev<'a, T> {
144    iter_shared! {is_forward = false}
145}
146
147#[cfg(feature = "rust_1_61")]
148pub use copied::{iter_copied, IterCopied, IterCopiedRev};
149
150#[cfg(feature = "rust_1_61")]
151mod copied {
152    use super::*;
153
154    #[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_61")))]
155    pub const fn iter_copied<T: Copy>(slice: &[T]) -> IterCopied<'_, T> {
156        IterCopied { slice }
157    }
158
159    macro_rules! iter_copied_shared {
160        (is_forward = $is_forward:ident) => {
161            iterator_shared! {
162                is_forward = $is_forward,
163                item = T,
164                iter_forward = IterCopied<'a, T>,
165                iter_reversed = IterCopiedRev<'a, T>,
166                next(self) {
167                    if let [elem, rem @ ..] = self.slice {
168                        self.slice = rem;
169                        Some((*elem, self))
170                    } else {
171                        None
172                    }
173                },
174                next_back {
175                    if let [rem @ .., elem] = self.slice {
176                        self.slice = rem;
177                        Some((*elem, self))
178                    } else {
179                        None
180                    }
181                },
182                fields = {slice},
183            }
184
185            /// Accesses the remaining slice.
186            pub const fn as_slice(&self) -> &'a [T] {
187                self.slice
188            }
189        };
190    }
191
192    #[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_61")))]
193    pub struct IterCopied<'a, T> {
194        slice: &'a [T],
195    }
196    impl<'a, T> IntoIterKind for IterCopied<'a, T> {
197        type Kind = IsIteratorKind;
198    }
199
200    #[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_61")))]
201    pub struct IterCopiedRev<'a, T> {
202        slice: &'a [T],
203    }
204    impl<'a, T> IntoIterKind for IterCopiedRev<'a, T> {
205        type Kind = IsIteratorKind;
206    }
207
208    impl<'a, T: Copy> IterCopied<'a, T> {
209        iter_copied_shared! {is_forward = true}
210    }
211
212    impl<'a, T: Copy> IterCopiedRev<'a, T> {
213        iter_copied_shared! {is_forward = false}
214    }
215}