From 47279b33e03587e55c50eacdf710d64ff15f17fb Mon Sep 17 00:00:00 2001 From: Dave Rolsky Date: Sat, 31 Oct 2020 11:34:32 -0500 Subject: Clarify handling of final line ending in str::lines() I found the description as it stands a bit confusing. I've added a bit more explanation to make it clear that a trailing line ending does not produce a final empty line. --- library/core/src/str/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'library/core') diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index b36d9f5c388..f4e8529a58f 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -842,7 +842,9 @@ impl str { /// Lines are ended with either a newline (`\n`) or a carriage return with /// a line feed (`\r\n`). /// - /// The final line ending is optional. + /// The final line ending is optional. A string that ends with a final line + /// ending (carriage return or line feed) will return the same lines as an + /// otherwise identical string without a final line ending. /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From 66d68cdc6f5bb508052b890f8766a84a98533865 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Sun, 1 Nov 2020 08:22:25 +0530 Subject: Trivial fixes to bitwise operator documentation Added fixes to documentation of `BitAnd`, `BitOr`, `BitXor` and `BitAndAssign`, where the documentation for implementation on `Vector` was using logical operators in place of the bitwise operators. r? @steveklabnik cc #78619 --- library/core/src/ops/bit.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'library/core') diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 6120da50c3c..3dae57938be 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -111,7 +111,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(lhs.len(), rhs.len()); /// Self(lhs.iter() /// .zip(rhs.iter()) -/// .map(|(x, y)| *x && *y) +/// .map(|(x, y)| *x & *y) /// .collect()) /// } /// } @@ -207,7 +207,10 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// fn bitor(self, Self(rhs): Self) -> Self::Output { /// let Self(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); -/// Self(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect()) +/// Self(lhs.iter() +/// .zip(rhs.iter()) +/// .map(|(x, y)| *x | *y) +/// .collect()) /// } /// } /// @@ -304,7 +307,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(lhs.len(), rhs.len()); /// Self(lhs.iter() /// .zip(rhs.iter()) -/// .map(|(x, y)| (*x || *y) && !(*x && *y)) +/// .map(|(x, y)| *x ^ *y)) /// .collect()) /// } /// } @@ -646,7 +649,7 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// *self = Self(self.0 /// .iter() /// .zip(rhs.0.iter()) -/// .map(|(x, y)| *x && *y) +/// .map(|(x, y)| *x & *y) /// .collect()); /// } /// } -- cgit 1.4.1-3-g733a5 From 7c88bcc3f6a055093eafff8d4cfb1dfcd813ebbe Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Sun, 1 Nov 2020 09:08:19 +0530 Subject: Fixes incorrect paranthesis. --- library/core/src/ops/bit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'library/core') diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 3dae57938be..b91f87be90a 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -307,7 +307,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// assert_eq!(lhs.len(), rhs.len()); /// Self(lhs.iter() /// .zip(rhs.iter()) -/// .map(|(x, y)| *x ^ *y)) +/// .map(|(x, y)| *x ^ *y) /// .collect()) /// } /// } -- cgit 1.4.1-3-g733a5 From d422e2424f08ebc420882e2a668174028341dc65 Mon Sep 17 00:00:00 2001 From: Abhijit Gadgil Date: Sun, 1 Nov 2020 18:53:22 +0530 Subject: documentation examples fixes in rustfmt convention --- library/core/src/ops/bit.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'library/core') diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index b91f87be90a..51f80438173 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -109,10 +109,12 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// fn bitand(self, Self(rhs): Self) -> Self::Output { /// let Self(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); -/// Self(lhs.iter() +/// Self( +/// lhs.iter() /// .zip(rhs.iter()) /// .map(|(x, y)| *x & *y) -/// .collect()) +/// .collect() +/// ) /// } /// } /// @@ -207,10 +209,12 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// fn bitor(self, Self(rhs): Self) -> Self::Output { /// let Self(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); -/// Self(lhs.iter() +/// Self( +/// lhs.iter() /// .zip(rhs.iter()) /// .map(|(x, y)| *x | *y) -/// .collect()) +/// .collect() +/// ) /// } /// } /// @@ -305,10 +309,12 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// fn bitxor(self, Self(rhs): Self) -> Self::Output { /// let Self(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); -/// Self(lhs.iter() +/// Self( +/// lhs.iter() /// .zip(rhs.iter()) /// .map(|(x, y)| *x ^ *y) -/// .collect()) +/// .collect() +/// ) /// } /// } /// @@ -646,11 +652,13 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// // `rhs` is the "right-hand side" of the expression `a &= b`. /// fn bitand_assign(&mut self, rhs: Self) { /// assert_eq!(self.0.len(), rhs.0.len()); -/// *self = Self(self.0 -/// .iter() -/// .zip(rhs.0.iter()) -/// .map(|(x, y)| *x & *y) -/// .collect()); +/// *self = Self( +/// self.0 +/// .iter() +/// .zip(rhs.0.iter()) +/// .map(|(x, y)| *x & *y) +/// .collect() +/// ); /// } /// } /// -- cgit 1.4.1-3-g733a5 From b2d7b3aa26e1821bfdfd8be8a8b65cd6e674ff04 Mon Sep 17 00:00:00 2001 From: Dave Rolsky Date: Sun, 1 Nov 2020 09:11:20 -0600 Subject: Remove incorrect statement about line ending content in lines doc change --- library/core/src/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'library/core') diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index f4e8529a58f..5658e28fbff 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -843,8 +843,8 @@ impl str { /// a line feed (`\r\n`). /// /// The final line ending is optional. A string that ends with a final line - /// ending (carriage return or line feed) will return the same lines as an - /// otherwise identical string without a final line ending. + /// ending will return the same lines as an otherwise identical string + /// without a final line ending. /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From a79059d42d8f6b1e2c2f109aa55a8ff98f4eb453 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 1 Nov 2020 14:27:36 +0100 Subject: Point out that total_cmp is no strict superset of partial comparison Partial comparison and total_cmp are not equal. This helps preventing the mistake of creating float wrappers that base their Ord impl on total_cmp and their PartialOrd impl on the PartialOrd impl of the float type. PartialOrd and Ord are required to agree with each other. --- library/core/src/num/f32.rs | 4 ++++ library/core/src/num/f64.rs | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'library/core') diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index bf7c87f685d..86e6352d132 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -876,6 +876,10 @@ impl f32 { /// - Positive signaling NaN /// - Positive quiet NaN /// + /// Note that this function does not always agree with the [`PartialOrd`] + /// and [`PartialEq`] implementations of `f32`. In particular, they regard + /// negative and positive zero as equal, while `total_cmp` doesn't. + /// /// # Example /// ``` /// #![feature(total_cmp)] diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index e31e176ba1b..9b1405b479f 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -890,6 +890,10 @@ impl f64 { /// - Positive signaling NaN /// - Positive quiet NaN /// + /// Note that this function does not always agree with the [`PartialOrd`] + /// and [`PartialEq`] implementations of `f64`. In particular, they regard + /// negative and positive zero as equal, while `total_cmp` doesn't. + /// /// # Example /// ``` /// #![feature(total_cmp)] -- cgit 1.4.1-3-g733a5 From 00f32e6631cb5603d072b24e0c1db2104fc63a26 Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Sun, 1 Nov 2020 13:24:22 -0500 Subject: Add fetch_update methods to AtomicBool and AtomicPtr These methods were stabilized for the integer atomics in #71843, but the methods were not added for the non-integer atomics `AtomicBool` and `AtomicPtr`. --- library/core/src/sync/atomic.rs | 125 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) (limited to 'library/core') diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index a3d93d7074b..0c53b6ed54a 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -801,6 +801,64 @@ impl AtomicBool { pub fn as_mut_ptr(&self) -> *mut bool { self.v.get() as *mut bool } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function + /// returned `Some(_)`, else `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been + /// changed from other threads in the meantime, as long as the function + /// returns `Some(_)`, but the function will have been applied only once to + /// the stored value. + /// + /// `fetch_update` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. The first describes the required ordering for + /// when the operation finally succeeds while the second describes the + /// required ordering for loads. These correspond to the success and failure + /// orderings of [`AtomicBool::compare_exchange`] respectively. + /// + /// Using [`Acquire`] as success ordering makes the store part of this + /// operation [`Relaxed`], and using [`Release`] makes the final successful + /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], + /// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the + /// success ordering. + /// + /// **Note:** This method is only available on platforms that support atomic + /// operations on `u8`. + /// + /// # Examples + /// + /// ```rust + /// #![feature(atomic_fetch_update)] + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let x = AtomicBool::new(false); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false)); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false)); + /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true)); + /// assert_eq!(x.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[unstable(feature = "atomic_fetch_update", reason = "recently added", issue = "78639")] + #[cfg(target_has_atomic = "8")] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result + where + F: FnMut(bool) -> Option, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } } #[cfg(target_has_atomic_load_store = "ptr")] @@ -1123,6 +1181,73 @@ impl AtomicPtr { } } } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function + /// returned `Some(_)`, else `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been + /// changed from other threads in the meantime, as long as the function + /// returns `Some(_)`, but the function will have been applied only once to + /// the stored value. + /// + /// `fetch_update` takes two [`Ordering`] arguments to describe the memory + /// ordering of this operation. The first describes the required ordering for + /// when the operation finally succeeds while the second describes the + /// required ordering for loads. These correspond to the success and failure + /// orderings of [`AtomicPtr::compare_exchange`] respectively. + /// + /// Using [`Acquire`] as success ordering makes the store part of this + /// operation [`Relaxed`], and using [`Release`] makes the final successful + /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], + /// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the + /// success ordering. + /// + /// **Note:** This method is only available on platforms that support atomic + /// operations on pointers. + /// + /// # Examples + /// + /// ```rust + /// #![feature(atomic_fetch_update)] + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr: *mut _ = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let new: *mut _ = &mut 10; + /// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr)); + /// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| { + /// if x == ptr { + /// Some(new) + /// } else { + /// None + /// } + /// }); + /// assert_eq!(result, Ok(ptr)); + /// assert_eq!(some_ptr.load(Ordering::SeqCst), new); + /// ``` + #[inline] + #[unstable(feature = "atomic_fetch_update", reason = "recently added", issue = "78639")] + #[cfg(target_has_atomic = "ptr")] + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: F, + ) -> Result<*mut T, *mut T> + where + F: FnMut(*mut T) -> Option<*mut T>, + { + let mut prev = self.load(fetch_order); + while let Some(next) = f(prev) { + match self.compare_exchange_weak(prev, next, set_order, fetch_order) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } } #[cfg(target_has_atomic_load_store = "8")] -- cgit 1.4.1-3-g733a5