konst_macro_rules/into_iter/
range_into_iter.rs

1use core::{
2    mem::ManuallyDrop,
3    ops::{Range, RangeFrom, RangeInclusive},
4};
5
6use super::{IntoIterKind, IntoIterWrapper, IsIteratorKind, IsStdKind};
7
8macro_rules! impl_std_kinds {
9    ($($ty:ident),*) => (
10        $(
11            impl<T> IntoIterKind for $ty<T> {
12                type Kind = IsStdKind;
13            }
14            impl<T> IntoIterKind for &$ty<T> {
15                type Kind = IsStdKind;
16            }
17        )*
18    )
19}
20impl_std_kinds! {Range, RangeInclusive, RangeFrom}
21
22pub struct RangeIter<T> {
23    start: T,
24    end: T,
25}
26impl<T> IntoIterKind for RangeIter<T> {
27    type Kind = IsIteratorKind;
28}
29
30pub struct RangeIterRev<T> {
31    start: T,
32    end: T,
33}
34impl<T> IntoIterKind for RangeIterRev<T> {
35    type Kind = IsIteratorKind;
36}
37
38pub struct RangeInclusiveIter<T> {
39    start: T,
40    end: T,
41}
42impl<T> IntoIterKind for RangeInclusiveIter<T> {
43    type Kind = IsIteratorKind;
44}
45
46pub struct RangeInclusiveIterRev<T> {
47    start: T,
48    end: T,
49}
50impl<T> IntoIterKind for RangeInclusiveIterRev<T> {
51    type Kind = IsIteratorKind;
52}
53
54pub struct RangeFromIter<T> {
55    start: T,
56}
57impl<T> IntoIterKind for RangeFromIter<T> {
58    type Kind = IsIteratorKind;
59}
60
61macro_rules! int_range_shared {
62    (is_forward = $is_forward:ident, int = $Int:ty) => {
63        iterator_shared! {
64            is_forward = $is_forward,
65            item = $Int,
66            iter_forward = RangeIter<$Int>,
67            iter_reversed = RangeIterRev<$Int>,
68            next(self){
69                if self.start >= self.end {
70                    None
71                } else {
72                    let ret = self.start;
73                    self.start += 1;
74                    Some((ret, self))
75                }
76            },
77            next_back {
78                if self.start >= self.end {
79                    None
80                } else {
81                    self.end -= 1;
82                    Some((self.end, self))
83                }
84            },
85            fields = {start, end},
86        }
87    };
88}
89
90macro_rules! range_exc_impls {
91    ($($ty:ty),*) => (
92        $(
93            impl RangeIter<$ty> {
94                int_range_shared!{is_forward = true, int = $ty}
95            }
96
97            impl RangeIterRev<$ty> {
98                int_range_shared!{is_forward = false, int = $ty}
99            }
100        )*
101    )
102}
103
104//////////////////////////////////////////////////
105
106macro_rules! int_range_inc_shared {
107    (is_forward = $is_forward:ident, int = $Int:ty) => {
108        iterator_shared! {
109            is_forward = $is_forward,
110            item = $Int,
111            iter_forward = RangeInclusiveIter<$Int>,
112            iter_reversed = RangeInclusiveIterRev<$Int>,
113            next(self){
114                if self.start > self.end {
115                    None
116                } else {
117                    let ret = self.start;
118                    if self.start == self.end {
119                        self.end = 0;
120                        self.start = 1;
121                    } else {
122                        self.start += 1;
123                    }
124                    Some((ret, self))
125                }
126            },
127            next_back {
128                if self.start > self.end {
129                    None
130                } else {
131                    let ret;
132                    if self.start == self.end {
133                        ret = self.end;
134                        self.end = 0;
135                        self.start = 1;
136                    } else {
137                        ret = self.end;
138                        self.end -= 1;
139                    }
140                    Some((ret, self))
141                }
142            },
143            fields = {start, end},
144        }
145    };
146}
147
148macro_rules! range_inc_impls {
149    ($($ty:ty),*) => (
150        $(
151            impl RangeInclusiveIter<$ty> {
152                int_range_inc_shared!{is_forward = true, int = $ty}
153            }
154
155            impl RangeInclusiveIterRev<$ty> {
156                int_range_inc_shared!{is_forward = false, int = $ty}
157            }
158        )*
159    )
160}
161
162////////////////////////////////////////////////////////////////////////////////////////////////////
163
164macro_rules! int_range_from_shared {
165    (int = $Int:ty) => {
166        iterator_shared! {
167            is_forward = true,
168            item = $Int,
169            iter_forward = RangeFromIter<$Int>,
170            next(self){
171                let ret = self.start;
172                self.start += 1;
173                Some((ret, self))
174            },
175            fields = {start},
176        }
177    };
178}
179
180macro_rules! range_from_impls {
181    ($($ty:ty),*) => (
182        $(
183            impl RangeFromIter<$ty> {
184                int_range_from_shared!{int = $ty}
185            }
186        )*
187    )
188}
189
190//////////////////////////////////////////////////
191
192macro_rules! ii_wrapper_range_impls {
193    ($Int:ty, $($reff:tt)?) => {
194        impl IntoIterWrapper<$($reff)? Range<$Int>, IsStdKind> {
195            pub const fn const_into_iter(self) -> RangeIter<$Int> {
196                let range = ManuallyDrop::into_inner(self.iter);
197                RangeIter {
198                    start: range.start,
199                    end: range.end,
200                }
201            }
202        }
203
204        impl IntoIterWrapper<$($reff)? RangeInclusive<$Int>, IsStdKind> {
205            pub const fn const_into_iter(self) -> RangeInclusiveIter<$Int> {
206                let range = ManuallyDrop::into_inner(self.iter);
207                RangeInclusiveIter {
208                    start: *range.start(),
209                    end: *range.end(),
210                }
211            }
212        }
213
214        impl IntoIterWrapper<$($reff)? RangeFrom<$Int>, IsStdKind> {
215            pub const fn const_into_iter(self) -> RangeFromIter<$Int> {
216                let range = ManuallyDrop::into_inner(self.iter);
217                RangeFromIter {
218                    start: range.start,
219                }
220            }
221        }
222
223    }
224}
225
226macro_rules! all_range_impls {
227    ($($Int:ty),*) => (
228
229        $(
230            ii_wrapper_range_impls!{$Int, }
231            ii_wrapper_range_impls!{$Int, &}
232        )*
233
234        range_exc_impls!{$($Int),*}
235
236        range_inc_impls!{$($Int),*}
237
238        range_from_impls!{$($Int),*}
239    )
240}
241
242all_range_impls! {usize}