Simplify RefCell
code a bit, make deref
a no-op.
This commit is contained in:
parent
fb52e69a50
commit
5048953deb
@ -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> {
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
impl<'b> Drop for BorrowRef<'b> {
|
||||
fn drop(&mut self) {
|
||||
let borrow = self._borrow.get();
|
||||
debug_assert!(borrow != WRITING && borrow != UNUSED);
|
||||
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
|
||||
_parent: &'b RefCell<T>
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
#[unstable]
|
||||
impl<'b, T> Drop for Ref<'b, T> {
|
||||
fn drop(&mut self) {
|
||||
let borrow = self._parent.borrow.get();
|
||||
debug_assert!(borrow != WRITING && borrow != UNUSED);
|
||||
self._parent.borrow.set(borrow - 1);
|
||||
}
|
||||
_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,15 +422,35 @@ 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(),
|
||||
}
|
||||
}
|
||||
|
||||
struct BorrowRefMut<'b> {
|
||||
_borrow: &'b Cell<BorrowFlag>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'b> Drop for BorrowRefMut<'b> {
|
||||
fn drop(&mut self) {
|
||||
let borrow = self._borrow.get();
|
||||
debug_assert!(borrow == WRITING);
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,24 +459,15 @@ pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
||||
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>
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
#[unstable]
|
||||
impl<'b, T> Drop for RefMut<'b, T> {
|
||||
fn drop(&mut self) {
|
||||
let borrow = self._parent.borrow.get();
|
||||
debug_assert!(borrow == WRITING);
|
||||
self._parent.borrow.set(UNUSED);
|
||||
}
|
||||
_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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user