1use crate::util::cmp_ptr;
4use crate::Nw;
5use std::cmp::Ordering;
6use std::fmt::{Display, Formatter, Result};
7use std::hash::{Hash, Hasher};
8use std::mem;
9use std::ops::Deref;
10use std::rc::{Rc, Weak};
11
12#[repr(transparent)]
14#[derive(Debug, Default)]
15pub struct Nr<T: ?Sized>(Rc<T>);
16
17impl<T> Nr<T> {
18 pub fn new(value: T) -> Self {
20 Self(Rc::new(value))
21 }
22
23 pub fn new_cyclic<F>(data_fn: F) -> Self
25 where
26 F: FnOnce(&Nw<T>) -> T,
27 {
28 let conv_arg = |w: &_| Nw::from_base(Weak::clone(w));
29 let base = Rc::new_cyclic(|w| data_fn(&conv_arg(w)));
30 Self(base)
31 }
32}
33
34impl<T: ?Sized> Nr<T> {
35 #[must_use]
37 #[inline(always)]
38 pub fn as_base(base: &Rc<T>) -> &Self {
39 unsafe { mem::transmute(base) }
40 }
41
42 #[must_use]
44 #[inline(always)]
45 pub fn from_base(base: Rc<T>) -> Self {
46 Self(base)
47 }
48
49 #[must_use]
51 #[inline(always)]
52 pub fn base(this: &Self) -> &Rc<T> {
53 &this.0
54 }
55
56 #[must_use]
58 pub fn downgrade(this: &Self) -> Nw<T> {
59 Nw::from_base(Rc::downgrade(&this.0))
60 }
61
62 #[inline(always)]
64 pub fn strong_count(this: &Self) -> usize {
65 Rc::strong_count(&this.0)
66 }
67
68 #[inline(always)]
70 pub fn weak_count(this: &Self) -> usize {
71 Rc::weak_count(&this.0)
72 }
73}
74
75impl<T: ?Sized> Clone for Nr<T> {
76 fn clone(&self) -> Self {
77 Self(Rc::clone(&self.0))
78 }
79}
80
81impl<T: ?Sized> Deref for Nr<T> {
82 type Target = T;
83
84 fn deref(&self) -> &Self::Target {
85 self.0.deref()
86 }
87}
88
89impl<T: ?Sized + Display> Display for Nr<T> {
90 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
91 self.0.fmt(f)
92 }
93}
94
95impl<T: ?Sized> Eq for Nr<T> {}
96
97impl<T: ?Sized> Hash for Nr<T> {
98 fn hash<H: Hasher>(&self, state: &mut H) {
99 Rc::as_ptr(&self.0).hash(state);
100 }
101}
102
103impl<T: ?Sized> Ord for Nr<T> {
104 fn cmp(&self, other: &Self) -> Ordering {
105 cmp_ptr(Rc::as_ptr(&self.0), Rc::as_ptr(&other.0))
106 }
107}
108
109impl<T: ?Sized> PartialEq for Nr<T> {
110 fn eq(&self, other: &Self) -> bool {
111 Rc::ptr_eq(&self.0, &other.0)
112 }
113}
114
115impl<T: ?Sized> PartialOrd for Nr<T> {
116 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
117 Some(self.cmp(other))
118 }
119}