Skip to content

Instantly share code, notes, and snippets.

@oyvindln
Created January 9, 2018 22:22
Show Gist options
  • Save oyvindln/a543f0d62da990c18a3575950c39ada1 to your computer and use it in GitHub Desktop.
Save oyvindln/a543f0d62da990c18a3575950c39ada1 to your computer and use it in GitHub Desktop.
Range specialisation
macro_rules! spec_range { ($($t:ty)*) =>
($(
impl Iterator for ops::Range<$t> {
#[inline]
default fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end && self.start < <$t>::max_value() {
let temp = self.start;
self.start += 1;
Some(temp)
} else {
None
}
}
#[inline]
default fn size_hint(&self) -> (usize, Option<usize>) {
if self.start < self.end {
if let Ok(hint) = usize::try_from(self.end - self.start) {
return (hint, Some(hint))
}
}
(0, None)
}
#[inline]
default fn nth(&mut self, n: usize) -> Option<Self::Item> {
if let Ok(nconv) = <$t>::try_from(n) {
if let Some(res) = self.start.checked_add(nconv) {
if res < self.end {
self.start = res + 1;
return Some(res)
}
}
}
self.start = self.end;
None
}
}
)*)
}
spec_range!(usize u8 u16 u32 u64);
spec_range!(isize i8 i16 i32 i64);
macro_rules! spec_range {
($($t:ty)*) => ($(
#[unstable(feature = "iterator_step_by",
reason = "unstable replacement of Range::step_by",
issue = "27741")]
impl Iterator for StepBy<ops::Range<$t>> {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.iter.start < self.iter.end {
self.first_take = false;
if let Ok(n) = <$t>::try_from(self.step) {
if let Some(step) = self.iter.start.checked_add(n) {
let ret = self.iter.start;
self.iter.start = step;
return Some(ret)
}
}
let ret = self.iter.start;
self.iter.start = self.iter.end;
Some(ret)
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let inner_hint = self.iter.size_hint();
if self.first_take {
let f = |n| if n == 0 { 0 } else { 1 + (n-1)/(self.step+1) };
(f(inner_hint.0), inner_hint.1.map(f))
} else {
let f = |n| n / (self.step+1);
(f(inner_hint.0), inner_hint.1.map(f))
}
}
}
)*)
}
spec_range!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment