use std::sync::Mutex;
use std::ops::Deref;
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use weight::Weight;
pub struct Inner<T: ?Sized> {
weight: Mutex<usize>,
data: T,
}
impl<T> Inner<T> {
#[inline]
pub fn new(data: T, starting_weight: usize) -> Inner<T> {
Inner {
weight: Mutex::new(starting_weight),
data: data,
}
}
#[inline]
fn data(&self) -> &T {
&self.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 mut existing_weight = self.weight.lock().expect("Unable to acquire WRC inner lock");
let new_weight = existing_weight.checked_add(weight);
match new_weight {
Some(weight) => {
*existing_weight = weight;
Some(weight)
}
None => None,
}
}
fn drop_weight(&self, weight: usize) -> Option<usize> {
let mut existing_weight = self.weight.lock().expect("Unable to acquire WRC inner lock");
let new_weight = existing_weight.checked_sub(weight);
match new_weight {
Some(weight) => {
*existing_weight = weight;
Some(weight)
}
None => None,
}
}
fn get_weight(&self) -> usize {
self.weight.lock().expect("Unable to acquire WRC inner lock").clone()
}
}
impl<T> Deref for Inner<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&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
}
fn ne(&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)
}
}