Skip to content

Commit

Permalink
impl Step for IP addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
clarfonthey committed Sep 16, 2023
1 parent e81f85f commit 8184c9c
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
67 changes: 66 additions & 1 deletion library/core/src/iter/range.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::ascii::Char as AsciiChar;
use crate::convert::TryFrom;
use crate::mem;
use crate::net::{Ipv4Addr, Ipv6Addr};
use crate::num::NonZeroUsize;
use crate::ops::{self, Try};

Expand All @@ -15,7 +16,7 @@ macro_rules! unsafe_impl_trusted_step {
unsafe impl TrustedStep for $type {}
)*};
}
unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize Ipv4Addr Ipv6Addr];

/// Objects that have a notion of *successor* and *predecessor* operations.
///
Expand Down Expand Up @@ -527,6 +528,70 @@ impl Step for AsciiChar {
}
}

#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
impl Step for Ipv4Addr {
#[inline]
fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> Option<usize> {
u32::steps_between(&start.to_bits(), &end.to_bits())
}

#[inline]
fn forward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
u32::forward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
}

#[inline]
fn backward_checked(start: Ipv4Addr, count: usize) -> Option<Ipv4Addr> {
u32::backward_checked(start.to_bits(), count).map(Ipv4Addr::from_bits)
}

#[inline]
unsafe fn forward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
// SAFETY: Since u32 and Ipv4Addr are losslessly convertible,
// this is as safe as the u32 version.
Ipv4Addr::from_bits(unsafe { u32::forward_unchecked(start.to_bits(), count) })
}

#[inline]
unsafe fn backward_unchecked(start: Ipv4Addr, count: usize) -> Ipv4Addr {
// SAFETY: Since u32 and Ipv4Addr are losslessly convertible,
// this is as safe as the u32 version.
Ipv4Addr::from_bits(unsafe { u32::backward_unchecked(start.to_bits(), count) })
}
}

#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
impl Step for Ipv6Addr {
#[inline]
fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> Option<usize> {
u128::steps_between(&start.to_bits(), &end.to_bits())
}

#[inline]
fn forward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
u128::forward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
}

#[inline]
fn backward_checked(start: Ipv6Addr, count: usize) -> Option<Ipv6Addr> {
u128::backward_checked(start.to_bits(), count).map(Ipv6Addr::from_bits)
}

#[inline]
unsafe fn forward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
// SAFETY: Since u128 and Ipv6Addr are losslessly convertible,
// this is as safe as the u128 version.
Ipv6Addr::from_bits(unsafe { u128::forward_unchecked(start.to_bits(), count) })
}

#[inline]
unsafe fn backward_unchecked(start: Ipv6Addr, count: usize) -> Ipv6Addr {
// SAFETY: Since u128 and Ipv6Addr are losslessly convertible,
// this is as safe as the u128 version.
Ipv6Addr::from_bits(unsafe { u128::backward_unchecked(start.to_bits(), count) })
}
}

macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/range/range-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LL | for i in false..true {}
i64
i128
usize
and 6 others
and 8 others
= note: required for `std::ops::Range<bool>` to implement `Iterator`
= note: required for `std::ops::Range<bool>` to implement `IntoIterator`

Expand Down

0 comments on commit 8184c9c

Please sign in to comment.