about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-15 23:05:06 +0000
committerbors <bors@rust-lang.org>2023-10-15 23:05:06 +0000
commit30d310cc1f7056fa9941b9f9c415d60091ed8fec (patch)
tree48c7f8917af0327fffd248ee26e54890b5a4e7ce
parent42b1224e9eb37177f608d3f6a6f2be2ee13902e4 (diff)
parent6b13950978c29e46636f3fb55aab1a479017045f (diff)
downloadrust-30d310cc1f7056fa9941b9f9c415d60091ed8fec.tar.gz
rust-30d310cc1f7056fa9941b9f9c415d60091ed8fec.zip
Auto merge of #113747 - clarfonthey:ip_bitops, r=dtolnay
impl Not, Bit{And,Or}{,Assign} for IP addresses

ACP: rust-lang/libs-team#235

Note: since these are insta-stable, these require an FCP.

Implements, where `N` is either `4` or `6`:

```rust
impl Not for IpvNAddr
impl Not for &IpvNAddr

impl BitAnd<IpvNAddr> for IpvNAddr
impl BitAnd<&IpvNAddr> for IpvNAddr
impl BitAnd<IpvNAddr> for &IpvNAddr
impl BitAnd<&IpvNAddr> for &IpvNAddr

impl BitAndAssign<IpvNAddr> for IpvNAddr
impl BitAndAssign<&IpvNAddr> for IpvNAddr

impl BitOr<IpvNAddr> for IpvNAddr
impl BitOr<&IpvNAddr> for IpvNAddr
impl BitOr<IpvNAddr> for &IpvNAddr
impl BitOr<&IpvNAddr> for &IpvNAddr

impl BitOrAssign<IpvNAddr> for IpvNAddr
impl BitOrAssign<&IpvNAddr> for IpvNAddr
```
-rw-r--r--library/core/src/net/ip_addr.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 6a36dfec098..33cc9add839 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1,6 +1,8 @@
 use crate::cmp::Ordering;
 use crate::fmt::{self, Write};
+use crate::iter;
 use crate::mem::transmute;
+use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
 
 use super::display_buffer::DisplayBuffer;
 
@@ -2122,3 +2124,132 @@ impl From<[u16; 8]> for IpAddr {
         IpAddr::V6(Ipv6Addr::from(segments))
     }
 }
+
+#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+impl Not for Ipv4Addr {
+    type Output = Ipv4Addr;
+
+    #[inline]
+    fn not(mut self) -> Ipv4Addr {
+        for octet in &mut self.octets {
+            *octet = !*octet;
+        }
+        self
+    }
+}
+
+#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+impl Not for &'_ Ipv4Addr {
+    type Output = Ipv4Addr;
+
+    #[inline]
+    fn not(self) -> Ipv4Addr {
+        !*self
+    }
+}
+
+#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+impl Not for Ipv6Addr {
+    type Output = Ipv6Addr;
+
+    #[inline]
+    fn not(mut self) -> Ipv6Addr {
+        for octet in &mut self.octets {
+            *octet = !*octet;
+        }
+        self
+    }
+}
+
+#[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+impl Not for &'_ Ipv6Addr {
+    type Output = Ipv6Addr;
+
+    #[inline]
+    fn not(self) -> Ipv6Addr {
+        !*self
+    }
+}
+
+macro_rules! bitop_impls {
+    ($(
+        $(#[$attr:meta])*
+        impl ($BitOp:ident, $BitOpAssign:ident) for $ty:ty = ($bitop:ident, $bitop_assign:ident);
+    )*) => {
+        $(
+            $(#[$attr])*
+            impl $BitOpAssign for $ty {
+                fn $bitop_assign(&mut self, rhs: $ty) {
+                    for (lhs, rhs) in iter::zip(&mut self.octets, rhs.octets) {
+                        lhs.$bitop_assign(rhs);
+                    }
+                }
+            }
+
+            $(#[$attr])*
+            impl $BitOpAssign<&'_ $ty> for $ty {
+                fn $bitop_assign(&mut self, rhs: &'_ $ty) {
+                    self.$bitop_assign(*rhs);
+                }
+            }
+
+            $(#[$attr])*
+            impl $BitOp for $ty {
+                type Output = $ty;
+
+                #[inline]
+                fn $bitop(mut self, rhs: $ty) -> $ty {
+                    self.$bitop_assign(rhs);
+                    self
+                }
+            }
+
+            $(#[$attr])*
+            impl $BitOp<&'_ $ty> for $ty {
+                type Output = $ty;
+
+                #[inline]
+                fn $bitop(mut self, rhs: &'_ $ty) -> $ty {
+                    self.$bitop_assign(*rhs);
+                    self
+                }
+            }
+
+            $(#[$attr])*
+            impl $BitOp<$ty> for &'_ $ty {
+                type Output = $ty;
+
+                #[inline]
+                fn $bitop(self, rhs: $ty) -> $ty {
+                    let mut lhs = *self;
+                    lhs.$bitop_assign(rhs);
+                    lhs
+                }
+            }
+
+            $(#[$attr])*
+            impl $BitOp<&'_ $ty> for &'_ $ty {
+                type Output = $ty;
+
+                #[inline]
+                fn $bitop(self, rhs: &'_ $ty) -> $ty {
+                    let mut lhs = *self;
+                    lhs.$bitop_assign(*rhs);
+                    lhs
+                }
+            }
+        )*
+    };
+}
+
+bitop_impls! {
+    #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+    impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign);
+    #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+    impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign);
+
+    #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+    impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign);
+    #[stable(feature = "ip_bitops", since = "CURRENT_RUSTC_VERSION")]
+    impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign);
+}