use clone::Clone;
use cmp::PartialEq;
use default::Default;
use fmt;
use kinds::{Copy, Send};
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{None, Some};
#[stable]
pub struct Cell<T> {
value: UnsafeCell<T>,
}
impl<T:Copy> Cell<T> {
#[stable]
pub fn new(value: T) -> Cell<T> {
Cell {
value: UnsafeCell::new(value),
}
}
#[inline]
#[stable]
pub fn get(&self) -> T {
unsafe{ *self.value.get() }
}
#[inline]
#[stable]
pub fn set(&self, value: T) {
unsafe {
*self.value.get() = value;
}
}
#[inline]
#[experimental]
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
&self.value
}
}
#[stable]
unsafe impl<T> Send for Cell<T> where T: Send {}
#[stable]
impl<T:Copy> Clone for Cell<T> {
fn clone(&self) -> Cell<T> {
Cell::new(self.get())
}
}
#[stable]
impl<T:Default + Copy> Default for Cell<T> {
#[stable]
fn default() -> Cell<T> {
Cell::new(Default::default())
}
}
#[stable]
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
fn eq(&self, other: &Cell<T>) -> bool {
self.get() == other.get()
}
}
#[stable]
pub struct RefCell<T> {
value: UnsafeCell<T>,
borrow: Cell<BorrowFlag>,
}
type BorrowFlag = uint;
const UNUSED: BorrowFlag = 0;
const WRITING: BorrowFlag = -1;
impl<T> RefCell<T> {
#[stable]
pub fn new(value: T) -> RefCell<T> {
RefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(UNUSED),
}
}
#[stable]
pub fn into_inner(self) -> T {
debug_assert!(self.borrow.get() == UNUSED);
unsafe { self.value.into_inner() }
}
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> T { self.into_inner() }
#[unstable = "may be renamed or removed"]
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
match BorrowRef::new(&self.borrow) {
Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }),
None => None,
}
}
#[stable]
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
match self.try_borrow() {
Some(ptr) => ptr,
None => panic!("RefCell<T> already mutably borrowed")
}
}
#[unstable = "may be renamed or removed"]
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
match BorrowRefMut::new(&self.borrow) {
Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }),
None => None,
}
}
#[stable]
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
match self.try_borrow_mut() {
Some(ptr) => ptr,
None => panic!("RefCell<T> already borrowed")
}
}
#[inline]
#[experimental]
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
&self.value
}
}
#[stable]
unsafe impl<T> Send for RefCell<T> where T: Send {}
#[stable]
impl<T: Clone> Clone for RefCell<T> {
fn clone(&self) -> RefCell<T> {
RefCell::new(self.borrow().clone())
}
}
#[stable]
impl<T:Default> Default for RefCell<T> {
#[stable]
fn default() -> RefCell<T> {
RefCell::new(Default::default())
}
}
#[stable]
impl<T: PartialEq> PartialEq for RefCell<T> {
fn eq(&self, other: &RefCell<T>) -> bool {
*self.borrow() == *other.borrow()
}
}
#[unstable]
impl<T:fmt::Show> fmt::Show for RefCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.try_borrow() {
Some(val) => write!(f, "{}", val),
None => write!(f, "<borrowed RefCell>")
}
}
}
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> {
let borrow = self._borrow.get();
debug_assert!(borrow != WRITING && borrow != UNUSED);
self._borrow.set(borrow + 1);
BorrowRef { _borrow: self._borrow }
}
}
#[stable]
pub struct Ref<'b, T:'b> {
_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 {
self._value
}
}
#[experimental = "likely to be moved to a method, pending language changes"]
pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> {
Ref {
_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,
}
}
}
#[stable]
pub struct RefMut<'b, T:'b> {
_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 {
self._value
}
}
#[unstable = "waiting for `DerefMut` to become stable"]
impl<'b, T> DerefMut<T> for RefMut<'b, T> {
#[inline]
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
self._value
}
}
#[lang="unsafe"]
#[stable]
pub struct UnsafeCell<T> {
#[unstable]
pub value: T,
}
impl<T> UnsafeCell<T> {
#[stable]
pub fn new(value: T) -> UnsafeCell<T> {
UnsafeCell { value: value }
}
#[inline]
#[stable]
pub fn get(&self) -> *mut T { &self.value as *const T as *mut T }
#[inline]
#[stable]
pub unsafe fn into_inner(self) -> T { self.value }
#[deprecated = "renamed to into_inner()"]
pub unsafe fn unwrap(self) -> T { self.into_inner() }
}