impl Step for IP addresses

This commit is contained in:
ltdk 2023-07-15 23:17:46 -04:00
parent e81f85fe9e
commit 8184c9c50d
2 changed files with 67 additions and 2 deletions

View File

@ -1,6 +1,7 @@
use crate::ascii::Char as AsciiChar; use crate::ascii::Char as AsciiChar;
use crate::convert::TryFrom; use crate::convert::TryFrom;
use crate::mem; use crate::mem;
use crate::net::{Ipv4Addr, Ipv6Addr};
use crate::num::NonZeroUsize; use crate::num::NonZeroUsize;
use crate::ops::{self, Try}; use crate::ops::{self, Try};
@ -15,7 +16,7 @@ macro_rules! unsafe_impl_trusted_step {
unsafe impl TrustedStep for $type {} 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. /// Objects that have a notion of *successor* and *predecessor* operations.
/// ///
@ -527,6 +528,70 @@ unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> 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 { macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($( ($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View File

@ -19,7 +19,7 @@ LL | for i in false..true {}
i64 i64
i128 i128
usize 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 `Iterator`
= note: required for `std::ops::Range<bool>` to implement `IntoIterator` = note: required for `std::ops::Range<bool>` to implement `IntoIterator`