about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLoïc BRANSTETT <lolo.branstett@numericable.fr>2022-02-11 12:55:25 +0100
committerUrgau <urgau@numericable.fr>2023-04-26 10:18:53 +0200
commit95a383bebd6181b95271aa1ffa3c164f9eb92956 (patch)
treed1f81fb674881e0d0f801bbe5e87525952b09db2
parentbf73234d92f38f9c499282254ac8abb008b29f95 (diff)
downloadrust-95a383bebd6181b95271aa1ffa3c164f9eb92956.tar.gz
rust-95a383bebd6181b95271aa1ffa3c164f9eb92956.zip
Implement midpoint for all unsigned NonZeroU{8,16,32,64,128,size}
-rw-r--r--library/core/src/num/nonzero.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 54e03067d1c..bfd1cfef277 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -493,6 +493,43 @@ macro_rules! nonzero_unsigned_operations {
                 pub const fn ilog10(self) -> u32 {
                     super::int_log10::$Int(self.0)
                 }
+
+                /// Calculates the middle point of `self` and `rhs`.
+                ///
+                /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+                /// sufficiently-large signed integral type. This implies that the result is
+                /// always rounded towards negative infinity and that no overflow will ever occur.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(num_midpoint)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+                ///
+                /// assert_eq!(one.midpoint(four), two);
+                /// assert_eq!(four.midpoint(one), two);
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "num_midpoint", issue = "110840")]
+                #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+                #[rustc_allow_const_fn_unstable(const_num_midpoint)]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
+                #[inline]
+                pub const fn midpoint(self, rhs: Self) -> Self {
+                    // SAFETY: The only way to get `0` with midpoint is to have two opposite or
+                    // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because
+                    // of the unsignedness of this number and also because $Ty is guaranteed to
+                    // never being 0.
+                    unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
+                }
             }
         )+
     }