|
| 1 | +// ignore-tidy-filelength |
1 | 2 | //! Definitions of a bunch of iterators for `[T]`.
|
2 | 3 |
|
3 | 4 | #[macro_use] // import iterator! and forward_iterator!
|
@@ -2967,3 +2968,176 @@ unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
|
2967 | 2968 | false
|
2968 | 2969 | }
|
2969 | 2970 | }
|
| 2971 | + |
| 2972 | +/// An iterator over slice in (non-overlapping) chunks separated by a predicate. |
| 2973 | +/// |
| 2974 | +/// This struct is created by the [`group_by`] method on [slices]. |
| 2975 | +/// |
| 2976 | +/// [`group_by`]: ../../std/primitive.slice.html#method.group_by |
| 2977 | +/// [slices]: ../../std/primitive.slice.html |
| 2978 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 2979 | +pub struct GroupBy<'a, T: 'a, P> { |
| 2980 | + slice: &'a [T], |
| 2981 | + predicate: P, |
| 2982 | +} |
| 2983 | + |
| 2984 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 2985 | +impl<'a, T: 'a, P> GroupBy<'a, T, P> { |
| 2986 | + pub(super) fn new(slice: &'a [T], predicate: P) -> Self { |
| 2987 | + GroupBy { slice, predicate } |
| 2988 | + } |
| 2989 | +} |
| 2990 | + |
| 2991 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 2992 | +impl<'a, T: 'a, P> Iterator for GroupBy<'a, T, P> |
| 2993 | +where |
| 2994 | + P: FnMut(&T, &T) -> bool, |
| 2995 | +{ |
| 2996 | + type Item = &'a [T]; |
| 2997 | + |
| 2998 | + #[inline] |
| 2999 | + fn next(&mut self) -> Option<Self::Item> { |
| 3000 | + if self.slice.is_empty() { |
| 3001 | + None |
| 3002 | + } else { |
| 3003 | + let mut len = 1; |
| 3004 | + let mut iter = self.slice.windows(2); |
| 3005 | + while let Some([l, r]) = iter.next() { |
| 3006 | + if (self.predicate)(l, r) { len += 1 } else { break } |
| 3007 | + } |
| 3008 | + let (head, tail) = self.slice.split_at(len); |
| 3009 | + self.slice = tail; |
| 3010 | + Some(head) |
| 3011 | + } |
| 3012 | + } |
| 3013 | + |
| 3014 | + #[inline] |
| 3015 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 3016 | + if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) } |
| 3017 | + } |
| 3018 | + |
| 3019 | + #[inline] |
| 3020 | + fn last(mut self) -> Option<Self::Item> { |
| 3021 | + self.next_back() |
| 3022 | + } |
| 3023 | +} |
| 3024 | + |
| 3025 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3026 | +impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P> |
| 3027 | +where |
| 3028 | + P: FnMut(&T, &T) -> bool, |
| 3029 | +{ |
| 3030 | + #[inline] |
| 3031 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 3032 | + if self.slice.is_empty() { |
| 3033 | + None |
| 3034 | + } else { |
| 3035 | + let mut len = 1; |
| 3036 | + let mut iter = self.slice.windows(2); |
| 3037 | + while let Some([l, r]) = iter.next_back() { |
| 3038 | + if (self.predicate)(l, r) { len += 1 } else { break } |
| 3039 | + } |
| 3040 | + let (head, tail) = self.slice.split_at(self.slice.len() - len); |
| 3041 | + self.slice = head; |
| 3042 | + Some(tail) |
| 3043 | + } |
| 3044 | + } |
| 3045 | +} |
| 3046 | + |
| 3047 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3048 | +impl<'a, T: 'a, P> FusedIterator for GroupBy<'a, T, P> where P: FnMut(&T, &T) -> bool {} |
| 3049 | + |
| 3050 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3051 | +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupBy<'a, T, P> { |
| 3052 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 3053 | + f.debug_struct("GroupBy").field("slice", &self.slice).finish() |
| 3054 | + } |
| 3055 | +} |
| 3056 | + |
| 3057 | +/// An iterator over slice in (non-overlapping) mutable chunks separated |
| 3058 | +/// by a predicate. |
| 3059 | +/// |
| 3060 | +/// This struct is created by the [`group_by_mut`] method on [slices]. |
| 3061 | +/// |
| 3062 | +/// [`group_by_mut`]: ../../std/primitive.slice.html#method.group_by_mut |
| 3063 | +/// [slices]: ../../std/primitive.slice.html |
| 3064 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3065 | +pub struct GroupByMut<'a, T: 'a, P> { |
| 3066 | + slice: &'a mut [T], |
| 3067 | + predicate: P, |
| 3068 | +} |
| 3069 | + |
| 3070 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3071 | +impl<'a, T: 'a, P> GroupByMut<'a, T, P> { |
| 3072 | + pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self { |
| 3073 | + GroupByMut { slice, predicate } |
| 3074 | + } |
| 3075 | +} |
| 3076 | + |
| 3077 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3078 | +impl<'a, T: 'a, P> Iterator for GroupByMut<'a, T, P> |
| 3079 | +where |
| 3080 | + P: FnMut(&T, &T) -> bool, |
| 3081 | +{ |
| 3082 | + type Item = &'a mut [T]; |
| 3083 | + |
| 3084 | + #[inline] |
| 3085 | + fn next(&mut self) -> Option<Self::Item> { |
| 3086 | + if self.slice.is_empty() { |
| 3087 | + None |
| 3088 | + } else { |
| 3089 | + let mut len = 1; |
| 3090 | + let mut iter = self.slice.windows(2); |
| 3091 | + while let Some([l, r]) = iter.next() { |
| 3092 | + if (self.predicate)(l, r) { len += 1 } else { break } |
| 3093 | + } |
| 3094 | + let slice = mem::take(&mut self.slice); |
| 3095 | + let (head, tail) = slice.split_at_mut(len); |
| 3096 | + self.slice = tail; |
| 3097 | + Some(head) |
| 3098 | + } |
| 3099 | + } |
| 3100 | + |
| 3101 | + #[inline] |
| 3102 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 3103 | + if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) } |
| 3104 | + } |
| 3105 | + |
| 3106 | + #[inline] |
| 3107 | + fn last(mut self) -> Option<Self::Item> { |
| 3108 | + self.next_back() |
| 3109 | + } |
| 3110 | +} |
| 3111 | + |
| 3112 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3113 | +impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P> |
| 3114 | +where |
| 3115 | + P: FnMut(&T, &T) -> bool, |
| 3116 | +{ |
| 3117 | + #[inline] |
| 3118 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 3119 | + if self.slice.is_empty() { |
| 3120 | + None |
| 3121 | + } else { |
| 3122 | + let mut len = 1; |
| 3123 | + let mut iter = self.slice.windows(2); |
| 3124 | + while let Some([l, r]) = iter.next_back() { |
| 3125 | + if (self.predicate)(l, r) { len += 1 } else { break } |
| 3126 | + } |
| 3127 | + let slice = mem::take(&mut self.slice); |
| 3128 | + let (head, tail) = slice.split_at_mut(slice.len() - len); |
| 3129 | + self.slice = head; |
| 3130 | + Some(tail) |
| 3131 | + } |
| 3132 | + } |
| 3133 | +} |
| 3134 | + |
| 3135 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3136 | +impl<'a, T: 'a, P> FusedIterator for GroupByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {} |
| 3137 | + |
| 3138 | +#[unstable(feature = "slice_group_by", issue = "80552")] |
| 3139 | +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupByMut<'a, T, P> { |
| 3140 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 3141 | + f.debug_struct("GroupByMut").field("slice", &self.slice).finish() |
| 3142 | + } |
| 3143 | +} |
0 commit comments