1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132



use std::marker::{ Send, Sync };
use std::ptr::Shared;
use std::cell::Cell;
use std::ops::{Deref};
use std::sync::atomic::{AtomicUsize, Ordering};


use std::fmt;

/// Types capable of reference counting by itself
pub unsafe trait IntrusiveReferenceCounted {
	unsafe fn acquire_ref(ptr: Shared<Self>) { Self::multi_acquire_ref(ptr, 1) }
	unsafe fn release_ref(ptr: Shared<Self>) { Self::multi_release_ref(ptr, 1) }

	unsafe fn multi_acquire_ref(ptr: Shared<Self>, refs: usize);
	unsafe fn multi_release_ref(ptr: Shared<Self>, refs: usize);
}

pub struct Irc<T: IntrusiveReferenceCounted + ?Sized>(Shared<T>);

impl<T: IntrusiveReferenceCounted + ?Sized> Irc<T> {
	pub fn new(ptr: Shared<T>) -> Self {
		unsafe { T::acquire_ref(ptr); }
		Irc(ptr)
	}

	pub unsafe fn new_with_ref(ptr: Shared<T>) -> Self {
		Irc(ptr)
	}
}

impl<T: IntrusiveReferenceCounted + ?Sized> Clone for Irc<T> {
	fn clone(&self) -> Self { Irc::new(self.0) }
}
impl<T: IntrusiveReferenceCounted + ?Sized> Drop for Irc<T> {
	fn drop(&mut self) { unsafe { T::release_ref(self.0); } }
}
impl<T: IntrusiveReferenceCounted + ?Sized> Deref for Irc<T> {
	type Target = T;
	fn deref(&self) -> &T { unsafe { &**self.0 } }
}

unsafe impl<T: IntrusiveReferenceCounted + ?Sized> Send for Irc<T> where T: Send {}
unsafe impl<T: IntrusiveReferenceCounted + ?Sized> Sync for Irc<T> where T: Sync + Send {}



impl<T: fmt::Debug + IntrusiveReferenceCounted + ?Sized> fmt::Debug for Irc<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.deref().fmt(f)
	}
}

impl<T: fmt::Display + IntrusiveReferenceCounted + ?Sized> fmt::Display for Irc<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.deref().fmt(f)	
	}
}



pub struct IrcWrapped<T>(Cell<usize>, T);

impl<T> IrcWrapped<T> {
	fn new_box(value: T) -> *mut Self { Box::into_raw(Box::new(IrcWrapped(Cell::new(1), value))) }
	unsafe fn final_release(&mut self) { Self::del_box(self) }
	unsafe fn del_box(ptr: *mut Self) { Box::from_raw(ptr); }
	pub fn new_irc(value: T) -> Irc<Self> { unsafe { Irc::new_with_ref(Shared::new(Self::new_box(value))) } }
}

unsafe impl<T> IntrusiveReferenceCounted for IrcWrapped<T> {
	unsafe fn multi_acquire_ref(ptr: Shared<Self>, refs: usize) {
		let this = ptr.as_ref().unwrap();
		this.0.set(this.0.get() + refs);
	}
	unsafe fn multi_release_ref(ptr: Shared<Self>, refs: usize) {
		let this = ptr.as_ref().unwrap();
		if this.0.get() != refs {
			this.0.set(this.0.get() - refs)
		} else {
			(**ptr).final_release();
		}
	}
}

impl<T: fmt::Debug> fmt::Debug for IrcWrapped<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		write!(f, "[{:?}, {:?}]", self.1, self.0.get())
	}
}

impl<T: fmt::Display> fmt::Display for IrcWrapped<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.1.fmt(f)
	}
}


pub struct AircWrapped<T>(AtomicUsize, T);

impl<T> AircWrapped<T> {
	fn new_box(value: T) -> *mut Self { Box::into_raw(Box::new(AircWrapped(AtomicUsize::new(1), value))) }
	unsafe fn final_release(&mut self) { Self::del_box(self) }
	unsafe fn del_box(ptr: *mut Self) { Box::from_raw(ptr); }
pub fn new_irc(value: T) -> Irc<Self> { unsafe { Irc::new_with_ref(Shared::new(Self::new_box(value))) } }
}

unsafe impl<T> IntrusiveReferenceCounted for AircWrapped<T> {
	unsafe fn multi_acquire_ref(ptr: Shared<Self>, refs: usize) {
		ptr.as_ref().unwrap().0.fetch_add(refs, Ordering::Relaxed);
	}
	unsafe fn multi_release_ref(ptr: Shared<Self>, refs: usize) {
		if refs == ptr.as_ref().unwrap().0.fetch_sub(refs, Ordering::AcqRel) {
			(**ptr).final_release();
		}
	}
}

impl<T: fmt::Debug> fmt::Debug for AircWrapped<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		write!(f, "[{:?}, {:?}]", self.1, self.0.load(Ordering::Relaxed))
	}
}

impl<T: fmt::Display> fmt::Display for AircWrapped<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.1.fmt(f)
	}
}