use crate::weight::Weight;
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::sync::atomic;
pub struct Inner<T: ?Sized> {
weight: atomic::AtomicUsize,
data: T,
}
impl<T> Inner<T> {
#[inline]
pub fn new(data: T, starting_weight: usize) -> Inner<T> {
Inner {
weight: atomic::AtomicUsize::new(starting_weight),
data,
}
}
}
unsafe impl<T: ?Sized + Sync + Send> Send for Inner<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for Inner<T> {}
impl<T: ?Sized> Weight for Inner<T> {
fn add_weight(&self, weight: usize) -> Option<usize> {
let existing_weight = self.weight.load(atomic::Ordering::Acquire);
let new_weight = existing_weight.checked_add(weight);
match new_weight {
Some(weight) => {
self.weight.store(weight, atomic::Ordering::Release);
Some(weight)
}
None => None,
}
}
fn drop_weight(&self, weight: usize) -> Option<usize> {
let existing_weight = self.weight.load(atomic::Ordering::Acquire);
let new_weight = existing_weight.checked_sub(weight);
match new_weight {
Some(weight) => {
self.weight.store(weight, atomic::Ordering::Release);
Some(weight)
}
None => None,
}
}
fn get_weight(&self) -> usize {
self.weight.load(atomic::Ordering::Relaxed)
}
}
impl<T> Deref for Inner<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&self.data
}
}
impl<T> DerefMut for Inner<T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
&mut self.data
}
}
impl<T> fmt::Display for Inner<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.data, f)
}
}
impl<T> fmt::Debug for Inner<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.data, f)
}
}
impl<T: ?Sized + PartialEq> PartialEq for Inner<T> {
fn eq(&self, other: &Inner<T>) -> bool {
self.data == other.data
}
}
impl<T: PartialOrd> PartialOrd for Inner<T> {
fn partial_cmp(&self, other: &Inner<T>) -> Option<Ordering> {
self.data.partial_cmp(&other.data)
}
fn lt(&self, other: &Inner<T>) -> bool {
self.data < other.data
}
fn le(&self, other: &Inner<T>) -> bool {
self.data <= other.data
}
fn gt(&self, other: &Inner<T>) -> bool {
self.data > other.data
}
fn ge(&self, other: &Inner<T>) -> bool {
self.data >= other.data
}
}
impl<T: Ord> Ord for Inner<T> {
fn cmp(&self, other: &Inner<T>) -> Ordering {
self.data.cmp(&other.data)
}
}
impl<T: Eq> Eq for Inner<T> {}
impl<T: Hash> Hash for Inner<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.data.hash(state)
}
}