use std::{
cell::UnsafeCell,
ops::{Deref, DerefMut},
};
#[cfg(test)]
impl<T> PartialEq for UC<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
std::ptr::addr_eq(self, other)
}
}
#[cfg_attr(test, derive(Debug))]
pub struct UC<T>(UnsafeCell<T>);
impl<T> UC<T> {
pub const fn aq_ref(&self) -> &T {
let t = self.0.get();
unsafe { t.as_mut().unwrap_unchecked() }
}
pub const fn promote(&self) -> &mut T {
let t = self.0.get();
unsafe { t.as_mut().unwrap_unchecked() }
}
pub const fn aq_mut(&mut self) -> &mut T {
self.0.get_mut()
}
pub const fn new(t: T) -> Self {
Self(UnsafeCell::new(t))
}
}
impl<T> Deref for UC<T> {
type Target = T;
fn deref(&self) -> &T {
self.aq_ref()
}
}
impl<T> DerefMut for UC<T> {
fn deref_mut(&mut self) -> &mut T {
self.aq_mut()
}
}
#[cfg(test)]
mod tests_of_units {
use crate::aide::address;
use std::ops::{Deref, DerefMut};
use super::UC;
mod partial_eq {
use super::super::UC;
#[test]
fn eq() {
let uc = UC::new(vec![0; 1]);
assert_eq!(true, uc.eq(&uc));
}
#[test]
fn not_eq() {
let uc1 = UC::new(vec![0; 1]);
let uc2 = UC::new(vec![0; 1]);
assert_eq!(false, uc1.eq(&uc2));
}
}
#[test]
fn aq_ref() {
let zero = &0usize as *const usize;
let uc = UC::new(zero);
let test = uc.aq_ref();
assert_eq!(zero as usize, *test as usize);
}
#[test]
fn aq_mut() {
let zero = &0usize as *const usize;
let mut uc = UC::new(zero);
let test = uc.aq_mut();
assert_eq!(zero as usize, *test as usize);
}
#[test]
fn promote() {
let zero = &0usize as *const usize;
let uc = UC::new(zero);
let test = uc.promote();
assert_eq!(zero as usize, *test as usize);
}
#[test]
fn new() {
let uc = UC::new(333);
let mut test = uc.0;
assert_eq!(333, *test.get_mut());
}
#[test]
fn deref() {
let uc = UC::new(11);
assert_eq!(uc.aq_ref(), uc.deref());
}
#[test]
fn deref_mut() {
let mut uc = UC::new(11);
let aq_add = address(uc.aq_mut());
let deref_add = address(uc.deref_mut());
assert_eq!(aq_add, deref_add);
}
}