use std::cell::Cell;
use std::cell::UnsafeCell;
use std::cmp::Ordering;
use std::fmt;
use std::fmt::Debug;
use std::fmt::Display;
use std::mem;
use std::ops::Deref;
use std::ops::DerefMut;
pub struct RefCell<T: ?Sized> {
borrow: Cell<BorrowFlag>,
value: UnsafeCell<T>,
}
pub struct BorrowError {
_private: (),
}
impl Debug for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("BorrowError").finish()
}
}
impl Display for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt("already mutably borrowed", f)
}
}
pub struct BorrowMutError {
_private: (),
}
impl Debug for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("BorrowMutError").finish()
}
}
impl Display for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt("already borrowed", f)
}
}
type BorrowFlag = isize;
const UNUSED: BorrowFlag = 0;
#[inline(always)]
fn is_writing(x: BorrowFlag) -> bool {
x < UNUSED
}
#[inline(always)]
fn is_reading(x: BorrowFlag) -> bool {
x > UNUSED
}
impl<T> RefCell<T> {
#[inline]
pub const fn new(value: T) -> RefCell<T> {
RefCell {
value: UnsafeCell::new(value),
borrow: Cell::new(UNUSED),
}
}
#[inline]
pub fn into_inner(self) -> T {
debug_assert!(self.borrow.get() == UNUSED);
self.value.into_inner()
}
#[inline]
pub fn replace(&self, t: T) -> T {
mem::replace(&mut *self.borrow_mut(), t)
}
#[inline]
pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
let mut_borrow = &mut *self.borrow_mut();
let replacement = f(mut_borrow);
mem::replace(mut_borrow, replacement)
}
#[inline]
pub fn swap(&self, other: &Self) {
mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
}
}
impl<T: ?Sized> RefCell<T> {
#[inline]
pub fn borrow(&self) -> Ref<T> {
self.try_borrow().expect("already mutably borrowed")
}
#[inline]
pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError> {
match BorrowRef::new(&self.borrow) {
Some(b) => Ok(Ref {
value: unsafe { &*self.value.get() },
borrow: b,
}),
None => Err(BorrowError { _private: () }),
}
}
#[inline]
pub fn borrow_mut(&self) -> RefMut<T> {
self.try_borrow_mut().expect("already borrowed")
}
#[inline]
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError> {
match BorrowRefMut::new(&self.borrow) {
Some(b) => Ok(RefMut {
value: unsafe { &mut *self.value.get() },
borrow: b,
}),
None => Err(BorrowMutError { _private: () }),
}
}
#[inline]
pub fn as_ptr(&self) -> *mut T {
self.value.get()
}
#[inline]
pub fn get_mut(&mut self) -> &mut T {
unsafe {
&mut *self.value.get()
}
}
}
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
impl<T: Clone> Clone for RefCell<T> {
#[inline]
fn clone(&self) -> RefCell<T> {
RefCell::new(self.borrow().clone())
}
}
impl<T:Default> Default for RefCell<T> {
#[inline]
fn default() -> RefCell<T> {
RefCell::new(Default::default())
}
}
impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
#[inline]
fn eq(&self, other: &RefCell<T>) -> bool {
*self.borrow() == *other.borrow()
}
}
impl<T: ?Sized + Eq> Eq for RefCell<T> {}
impl<T: ?Sized + PartialOrd> PartialOrd for RefCell<T> {
#[inline]
fn partial_cmp(&self, other: &RefCell<T>) -> Option<Ordering> {
self.borrow().partial_cmp(&*other.borrow())
}
#[inline]
fn lt(&self, other: &RefCell<T>) -> bool {
*self.borrow() < *other.borrow()
}
#[inline]
fn le(&self, other: &RefCell<T>) -> bool {
*self.borrow() <= *other.borrow()
}
#[inline]
fn gt(&self, other: &RefCell<T>) -> bool {
*self.borrow() > *other.borrow()
}
#[inline]
fn ge(&self, other: &RefCell<T>) -> bool {
*self.borrow() >= *other.borrow()
}
}
impl<T: ?Sized + Ord> Ord for RefCell<T> {
#[inline]
fn cmp(&self, other: &RefCell<T>) -> Ordering {
self.borrow().cmp(&*other.borrow())
}
}
impl<T> From<T> for RefCell<T> {
fn from(t: T) -> RefCell<T> {
RefCell::new(t)
}
}
struct BorrowRef<'b> {
borrow: &'b Cell<BorrowFlag>,
}
impl<'b> BorrowRef<'b> {
#[inline]
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
let b = borrow.get();
if is_writing(b) || b == isize::max_value() {
None
} else {
borrow.set(b + 1);
Some(BorrowRef { borrow })
}
}
}
impl Drop for BorrowRef<'_> {
#[inline]
fn drop(&mut self) {
let borrow = self.borrow.get();
debug_assert!(is_reading(borrow));
self.borrow.set(borrow - 1);
}
}
impl Clone for BorrowRef<'_> {
#[inline]
fn clone(&self) -> Self {
let borrow = self.borrow.get();
debug_assert!(is_reading(borrow));
assert!(borrow != isize::max_value());
self.borrow.set(borrow + 1);
BorrowRef { borrow: self.borrow }
}
}
pub struct Ref<'b, T: ?Sized + 'b> {
value: &'b T,
borrow: BorrowRef<'b>,
}
impl<T: ?Sized> Deref for Ref<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'b, T: ?Sized> Ref<'b, T> {
#[inline]
pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
Ref {
value: orig.value,
borrow: orig.borrow.clone(),
}
}
#[inline]
pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
where F: FnOnce(&T) -> &U
{
Ref {
value: f(orig.value),
borrow: orig.borrow,
}
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
where F: FnOnce(&T) -> (&U, &V)
{
let (a, b) = f(orig.value);
let borrow = orig.borrow.clone();
(Ref { value: a, borrow }, Ref { value: b, borrow: orig.borrow })
}
#[inline]
pub fn map_val<U: Sized, F>(orig: Ref<'b, T>, f: F) -> RefVal<'b, U>
where F: FnOnce(&'b T) -> U
{
RefVal {
value: f(orig.value),
borrow: orig.borrow,
}
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for Ref<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<'b, T: ?Sized> RefMut<'b, T> {
#[inline]
pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
where F: FnOnce(&mut T) -> &mut U
{
let RefMut { value, borrow } = orig;
RefMut {
value: f(value),
borrow,
}
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
orig: RefMut<'b, T>, f: F
) -> (RefMut<'b, U>, RefMut<'b, V>)
where F: FnOnce(&mut T) -> (&mut U, &mut V)
{
let (a, b) = f(orig.value);
let borrow = orig.borrow.clone();
(RefMut { value: a, borrow }, RefMut { value: b, borrow: orig.borrow })
}
#[inline]
pub fn map_val<U: Sized, F>(orig: RefMut<'b, T>, f: F) -> RefValMut<'b, U>
where F: FnOnce(&'b mut T) -> U
{
RefValMut {
value: f(orig.value),
borrow: orig.borrow,
}
}
}
struct BorrowRefMut<'b> {
borrow: &'b Cell<BorrowFlag>,
}
impl Drop for BorrowRefMut<'_> {
#[inline]
fn drop(&mut self) {
let borrow = self.borrow.get();
debug_assert!(is_writing(borrow));
self.borrow.set(borrow + 1);
}
}
impl<'b> BorrowRefMut<'b> {
#[inline]
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
match borrow.get() {
UNUSED => {
borrow.set(UNUSED - 1);
Some(BorrowRefMut { borrow })
},
_ => None,
}
}
#[inline]
fn clone(&self) -> BorrowRefMut<'b> {
let borrow = self.borrow.get();
debug_assert!(is_writing(borrow));
assert!(borrow != isize::min_value());
self.borrow.set(borrow - 1);
BorrowRefMut { borrow: self.borrow }
}
}
pub struct RefMut<'b, T: ?Sized + 'b> {
value: &'b mut T,
borrow: BorrowRefMut<'b>,
}
impl<T: ?Sized> Deref for RefMut<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<T: ?Sized> DerefMut for RefMut<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.value
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
pub struct RefVal<'b, T> {
value: T,
borrow: BorrowRef<'b>,
}
impl<'b, T> RefVal<'b, T> {
#[inline]
pub fn clone(orig: &RefVal<'b, T>) -> RefVal<'b, T>
where T: Clone
{
RefVal {
value: orig.value.clone(),
borrow: orig.borrow.clone(),
}
}
#[inline]
pub fn map<U: Sized, F>(orig: RefVal<'b, T>, f: F) -> RefVal<'b, U>
where F: FnOnce(T) -> U
{
RefVal {
value: f(orig.value),
borrow: orig.borrow,
}
}
}
impl<T> Deref for RefVal<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&self.value
}
}
impl<T> DerefMut for RefVal<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T: fmt::Display> fmt::Display for RefVal<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
pub struct RefValMut<'b, T> {
value: T,
borrow: BorrowRefMut<'b>,
}
impl<'b, T> RefValMut<'b, T> {
#[inline]
pub fn map<U: Sized, F>(orig: RefValMut<'b, T>, f: F) -> RefValMut<'b, U>
where F: FnOnce(T) -> U
{
RefValMut {
value: f(orig.value),
borrow: orig.borrow,
}
}
}
impl<T> Deref for RefValMut<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&self.value
}
}
impl<T> DerefMut for RefValMut<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T: fmt::Display> fmt::Display for RefValMut<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}