#![allow(dead_code)]
use std::cell::{Cell, UnsafeCell};
use std::ops::{Deref, DerefMut};
pub struct RefCell<T: ?Sized> {
borrow: Cell<BorrowFlag>,
value: UnsafeCell<T>
}
#[derive(Debug, Clone, Copy)]
struct BorrowFlag(isize);
impl BorrowFlag {
const fn unused() -> Self {
Self(0)
}
const fn is_writing(&self) -> bool {
self.0 < 0
}
const fn is_reading(&self) -> bool {
self.0 > 0
}
#[must_use]
fn add_ref(&mut self) -> bool {
if self.is_writing() {
false
} else {
match self.0.checked_add(1) {
Some(n) => {
self.0 = n;
true
},
None => false
}
}
}
fn rm_ref(&mut self) {
self.0 -= 1;
assert!(self.0 >= 0);
}
#[must_use]
fn add_ref_mut(&mut self) -> bool {
if self.0 != 0 {
false
} else {
self.0 -= 1;
true
}
}
fn rm_ref_mut(&mut self) {
self.0 += 1;
assert_eq!(self.0, 0);
}
}
impl<T> RefCell<T> {
pub const fn new(v: T) -> Self {
Self {
value: UnsafeCell::new(v),
borrow: Cell::new(BorrowFlag::unused())
}
}
}
impl<T: ?Sized> RefCell<T> {
pub fn increment_ref(&self) {
let mut flag = self.borrow.get();
if !flag.add_ref() {
panic!("value borrowed mutably");
}
self.borrow.set(flag);
}
pub fn increment_ref_mut(&self) {
let mut flag = self.borrow.get();
if !flag.add_ref_mut() {
panic!("value borrowed mutably");
}
self.borrow.set(flag);
}
pub fn leak_ref<'a>(&'a self) -> &'a T {
self.increment_ref();
unsafe { &*self.value.get() }
}
pub fn borrow(&self) -> Ref<'_, &T> {
self.increment_ref();
Ref {
value: unsafe { &*self.value.get() },
borrow: BorrowRef { inner: &self.borrow, mutably: false }
}
}
pub fn borrow_mut(&self) -> Ref<'_, &mut T> {
self.increment_ref_mut();
Ref {
value: unsafe { &mut *self.value.get() },
borrow: BorrowRef { inner: &self.borrow, mutably: true }
}
}
}
unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
impl<T> From<T> for RefCell<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
struct BorrowRef<'a> {
inner: &'a Cell<BorrowFlag>,
mutably: bool
}
impl Drop for BorrowRef<'_> {
fn drop(&mut self) {
let mut flag = self.inner.get();
if !self.mutably {
flag.rm_ref();
} else {
flag.rm_ref_mut();
}
self.inner.set(flag);
}
}
pub struct Ref<'a, T: 'a> {
value: T,
borrow: BorrowRef<'a>
}
impl<'a, T> Ref<'a, T> {
pub unsafe fn map<F, U>(me: Self, f: F) -> Ref<'a, U>
where F: FnOnce(T) -> U {
Ref {
value: f(me.value),
borrow: me.borrow
}
}
}
impl<'a, R, E> Ref<'a, Result<R, E>> {
pub fn transpose(me: Self) -> Result<Ref<'a, R>, E> {
match me.value {
Ok(value) => Ok(Ref {
value,
borrow: me.borrow
}),
Err(e) => Err(e)
}
}
}
impl<T> Deref for Ref<'_, T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
impl<T> DerefMut for Ref<'_, T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.value
}
}