1 use std::ops::{Deref, DerefMut};
2 use std::convert::AsRef;
3 use std::sync::atomic::*;
5 struct NABufferData<T> {
10 impl<T> NABufferData<T> {
11 fn new(data: T) -> Self {
14 refs: AtomicUsize::new(1),
17 fn inc_refs(obj: &mut Self) {
18 obj.refs.fetch_add(1, Ordering::SeqCst);
20 fn dec_refs(obj: &mut Self) -> bool {
21 obj.refs.fetch_sub(1, Ordering::SeqCst) == 1
23 fn get_num_refs(obj: &Self) -> usize {
24 obj.refs.load(Ordering::Relaxed)
26 fn get_read_ptr(obj: &Self) -> &T {
29 fn get_write_ptr(obj: &mut Self) -> Option<&mut T> {
34 pub struct NABufferRef<T> {
35 ptr: *mut NABufferData<T>,
38 impl<T> NABufferRef<T> {
39 pub fn new(val: T) -> Self {
40 let bdata = NABufferData::new(val);
41 let nbox: Box<_> = Box::new(bdata);
42 Self { ptr: Box::into_raw(nbox) }
44 pub fn get_num_refs(&self) -> usize {
46 NABufferData::get_num_refs(self.ptr.as_mut().unwrap())
49 pub fn as_mut(&mut self) -> Option<&mut T> {
51 NABufferData::get_write_ptr(self.ptr.as_mut().unwrap())
56 impl<T> AsRef<T> for NABufferRef<T> {
57 fn as_ref(&self) -> &T {
59 NABufferData::get_read_ptr(self.ptr.as_mut().unwrap())
64 impl<T> Deref for NABufferRef<T> {
66 fn deref(&self) -> &T { self.as_ref() }
69 impl<T> DerefMut for NABufferRef<T> {
70 fn deref_mut(&mut self) -> &mut T { self.as_mut().unwrap() }
73 impl<T> Clone for NABufferRef<T> {
74 fn clone(&self) -> Self {
76 NABufferData::inc_refs(self.ptr.as_mut().unwrap());
78 Self { ptr: self.ptr }
82 impl<T> Drop for NABufferRef<T> {
85 if NABufferData::dec_refs(self.ptr.as_mut().unwrap()) {
86 let data = Box::from_raw(self.ptr);
93 impl<T:Default> Default for NABufferRef<T> {
94 fn default() -> Self {
95 Self::new(T::default())