Skip to content

Commit 13f5676

Browse files
committed
Implement RefCell::{try_replace, try_replace_with, try_swap}
Resolves #54493.
1 parent 3ec4308 commit 13f5676

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

library/core/src/cell.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,42 @@ impl<T> RefCell<T> {
899899
mem::replace(&mut *self.borrow_mut(), t)
900900
}
901901

902+
/// Replaces the wrapped value with a new one, returning the old value,
903+
/// without deinitializing either one.
904+
///
905+
/// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
906+
///
907+
/// This is the non-panicking variant of [`replace`](#method.replace).
908+
///
909+
/// # Examples
910+
///
911+
/// ```
912+
/// use std::cell::RefCell;
913+
///
914+
/// let cell = RefCell::new(5);
915+
///
916+
/// {
917+
/// let borrowed_five = cell.borrow();
918+
/// let replace_result = cell.try_replace(6);
919+
/// assert!(replace_result.is_err());
920+
/// assert_eq!(cell, RefCell::new(5));
921+
///
922+
/// }
923+
///
924+
/// {
925+
/// let replace_result = cell.try_replace(6)?;
926+
/// assert_eq!(replace_result, Ok(5));
927+
/// assert_eq!(cell, RefCell::new(6));
928+
/// }
929+
/// ```
930+
#[inline]
931+
#[unstable(feature = "refcell_try_replace_replace_with_swap", issue = "none")]
932+
#[track_caller]
933+
#[rustc_confusables("try_swap")]
934+
pub fn try_replace(&self, t: T) -> Result<T, BorrowMutError> {
935+
Ok(mem::replace(&mut *self.try_borrow_mut()?, t))
936+
}
937+
902938
/// Replaces the wrapped value with a new one computed from `f`, returning
903939
/// the old value, without deinitializing either one.
904940
///
@@ -924,6 +960,41 @@ impl<T> RefCell<T> {
924960
mem::replace(mut_borrow, replacement)
925961
}
926962

963+
/// Replaces the wrapped value with a new one computed from `f`, returning
964+
/// the old value, without deinitializing either one.
965+
///
966+
/// This is the non-panicking variant of [`replace_with`](#method.replace_with).
967+
///
968+
/// # Examples
969+
///
970+
/// ```
971+
/// use std::cell::RefCell;
972+
///
973+
/// let cell = RefCell::new(5);
974+
///
975+
/// {
976+
/// let borrowed_five = cell.borrow();
977+
/// let replace_result = cell.try_replace_with(|&mut old| old + 1);
978+
/// assert!(replace_result.is_err());
979+
/// assert_eq!(cell, RefCell::new(5));
980+
///
981+
/// }
982+
///
983+
/// {
984+
/// let replace_result = cell.try_replace_with(|&mut old| old + 1);
985+
/// assert_eq!(replace_result, Ok(5));
986+
/// assert_eq!(cell, RefCell::new(6));
987+
/// }
988+
/// ```
989+
#[inline]
990+
#[unstable(feature = "refcell_try_replace_replace_with_swap", issue = "none")]
991+
#[track_caller]
992+
pub fn try_replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> Result<T, BorrowMutError> {
993+
let mut_borrow = &mut *self.try_borrow_mut()?;
994+
let replacement = f(mut_borrow);
995+
Ok(mem::replace(mut_borrow, replacement))
996+
}
997+
927998
/// Swaps the wrapped value of `self` with the wrapped value of `other`,
928999
/// without deinitializing either one.
9291000
///
@@ -949,6 +1020,51 @@ impl<T> RefCell<T> {
9491020
pub fn swap(&self, other: &Self) {
9501021
mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
9511022
}
1023+
1024+
/// Swaps the wrapped value of `self` with the wrapped value of `other`,
1025+
/// without deinitializing either one.
1026+
///
1027+
/// This function corresponds to [`std::mem::swap`](../mem/fn.swap.html).
1028+
///
1029+
/// This is the non-panicking variant of [`swap`](#method.swap).
1030+
///
1031+
/// # Examples
1032+
///
1033+
/// ```
1034+
/// use std::cell::RefCell;
1035+
///
1036+
/// let c = RefCell::new(5);
1037+
/// let d = RefCell::new(6);
1038+
///
1039+
/// {
1040+
/// let borrowed_c = c.borrow();
1041+
/// let swap_result = c.swap(&d);
1042+
/// assert!(replace_result.is_err());
1043+
/// assert_eq!(c, RefCell::new(5));
1044+
/// assert_eq!(d, RefCell::new(6));
1045+
/// }
1046+
///
1047+
/// {
1048+
/// let borrowed_d = d.borrow();
1049+
/// let swap_result = c.swap(&d);
1050+
/// assert!(replace_result.is_err());
1051+
/// assert_eq!(c, RefCell::new(5));
1052+
/// assert_eq!(d, RefCell::new(6));
1053+
/// }
1054+
///
1055+
/// {
1056+
/// let swap_result = c.swap(&d);
1057+
/// assert!(swap_result.is_ok());
1058+
/// assert_eq!(c, RefCell::new(6));
1059+
/// assert_eq!(d, RefCell::new(5));
1060+
/// }
1061+
/// ```
1062+
#[inline]
1063+
#[unstable(feature = "refcell_try_replace_replace_with_swap", issue = "none")]
1064+
#[track_caller]
1065+
pub fn try_swap(&self, other: &Self) -> Result<(), BorrowMutError> {
1066+
Ok(mem::swap(&mut *self.try_borrow_mut()?, &mut *other.try_borrow_mut()?))
1067+
}
9521068
}
9531069

9541070
impl<T: ?Sized> RefCell<T> {

0 commit comments

Comments
 (0)