diff options
| author | Tobias Bucher <tobiasbucher5991@gmail.com> | 2014-11-29 01:20:14 +0100 |
|---|---|---|
| committer | Tobias Bucher <tobiasbucher5991@gmail.com> | 2014-11-30 11:50:35 +0100 |
| commit | 5048953debe9eb44c672f3c453e894bd64a1301a (patch) | |
| tree | e4a5e414c378ed0f07f5a8f4d661481e8cb421bc /src/libcore | |
| parent | fb52e69a503fbe1c5f7641655bc45def875584b3 (diff) | |
| download | rust-5048953debe9eb44c672f3c453e894bd64a1301a.tar.gz rust-5048953debe9eb44c672f3c453e894bd64a1301a.zip | |
Simplify `RefCell` code a bit, make `deref` a no-op.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cell.rs | 118 |
1 files changed, 75 insertions, 43 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 587bb4cb110..ed4df101202 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -277,12 +277,9 @@ impl<T> RefCell<T> { /// Returns `None` if the value is currently mutably borrowed. #[unstable = "may be renamed, depending on global conventions"] pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> { - match self.borrow.get() { - WRITING => None, - borrow => { - self.borrow.set(borrow + 1); - Some(Ref { _parent: self }) - } + match BorrowRef::new(&self.borrow) { + Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }), + None => None, } } @@ -310,12 +307,9 @@ impl<T> RefCell<T> { /// Returns `None` if the value is currently borrowed. #[unstable = "may be renamed, depending on global conventions"] pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> { - match self.borrow.get() { - UNUSED => { - self.borrow.set(WRITING); - Some(RefMut { _parent: self }) - }, - _ => None + match BorrowRefMut::new(&self.borrow) { + Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }), + None => None, } } @@ -368,29 +362,56 @@ impl<T: PartialEq> PartialEq for RefCell<T> { } } -/// Wraps a borrowed reference to a value in a `RefCell` box. -#[unstable] -pub struct Ref<'b, T:'b> { - // FIXME #12808: strange name to try to avoid interfering with - // field accesses of the contained type via Deref - _parent: &'b RefCell<T> +struct BorrowRef<'b> { + _borrow: &'b Cell<BorrowFlag>, +} + +impl<'b> BorrowRef<'b> { + fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> { + match borrow.get() { + WRITING => None, + b => { + borrow.set(b + 1); + Some(BorrowRef { _borrow: borrow }) + }, + } + } } #[unsafe_destructor] -#[unstable] -impl<'b, T> Drop for Ref<'b, T> { +impl<'b> Drop for BorrowRef<'b> { fn drop(&mut self) { - let borrow = self._parent.borrow.get(); + let borrow = self._borrow.get(); debug_assert!(borrow != WRITING && borrow != UNUSED); - self._parent.borrow.set(borrow - 1); + self._borrow.set(borrow - 1); } } +impl<'b> Clone for BorrowRef<'b> { + fn clone(&self) -> BorrowRef<'b> { + // Since this Ref exists, we know the borrow flag + // is not set to WRITING. + let borrow = self._borrow.get(); + debug_assert!(borrow != WRITING && borrow != UNUSED); + self._borrow.set(borrow + 1); + BorrowRef { _borrow: self._borrow } + } +} + +/// Wraps a borrowed reference to a value in a `RefCell` box. +#[unstable] +pub struct Ref<'b, T:'b> { + // FIXME #12808: strange name to try to avoid interfering with + // field accesses of the contained type via Deref + _value: &'b T, + _borrow: BorrowRef<'b>, +} + #[unstable = "waiting for `Deref` to become stable"] impl<'b, T> Deref<T> for Ref<'b, T> { #[inline] fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self._parent.value.get() } + self._value } } @@ -401,41 +422,52 @@ impl<'b, T> Deref<T> for Ref<'b, T> { /// A `Clone` implementation would interfere with the widespread /// use of `r.borrow().clone()` to clone the contents of a `RefCell`. #[experimental = "likely to be moved to a method, pending language changes"] -pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> { - // Since this Ref exists, we know the borrow flag - // is not set to WRITING. - let borrow = orig._parent.borrow.get(); - debug_assert!(borrow != WRITING && borrow != UNUSED); - orig._parent.borrow.set(borrow + 1); - +pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> { Ref { - _parent: orig._parent, + _value: orig._value, + _borrow: orig._borrow.clone(), } } -/// Wraps a mutable borrowed reference to a value in a `RefCell` box. -#[unstable] -pub struct RefMut<'b, T:'b> { - // FIXME #12808: strange name to try to avoid interfering with - // field accesses of the contained type via Deref - _parent: &'b RefCell<T> +struct BorrowRefMut<'b> { + _borrow: &'b Cell<BorrowFlag>, } #[unsafe_destructor] -#[unstable] -impl<'b, T> Drop for RefMut<'b, T> { +impl<'b> Drop for BorrowRefMut<'b> { fn drop(&mut self) { - let borrow = self._parent.borrow.get(); + let borrow = self._borrow.get(); debug_assert!(borrow == WRITING); - self._parent.borrow.set(UNUSED); + self._borrow.set(UNUSED); } } +impl<'b> BorrowRefMut<'b> { + fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { + match borrow.get() { + UNUSED => { + borrow.set(WRITING); + Some(BorrowRefMut { _borrow: borrow }) + }, + _ => None, + } + } +} + +/// Wraps a mutable borrowed reference to a value in a `RefCell` box. +#[unstable] +pub struct RefMut<'b, T:'b> { + // FIXME #12808: strange name to try to avoid interfering with + // field accesses of the contained type via Deref + _value: &'b mut T, + _borrow: BorrowRefMut<'b>, +} + #[unstable = "waiting for `Deref` to become stable"] impl<'b, T> Deref<T> for RefMut<'b, T> { #[inline] fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self._parent.value.get() } + self._value } } @@ -443,7 +475,7 @@ impl<'b, T> Deref<T> for RefMut<'b, T> { impl<'b, T> DerefMut<T> for RefMut<'b, T> { #[inline] fn deref_mut<'a>(&'a mut self) -> &'a mut T { - unsafe { &mut *self._parent.value.get() } + self._value } } |
