wiwi/rc/
str.rs

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
use crate::prelude_std::*;
use super::{ Rc, RcWeak, Counter, ThreadCounter, AtomicCounter };

#[repr(transparent)]
pub struct RcStr<C, M = ()>
where
	C: Counter
{
	inner: Rc<C, M, u8>
}

#[repr(transparent)]
pub struct RcStrWeak<C, M = ()>
where
	C: Counter
{
	inner: RcWeak<C, M, u8>
}

/// Single threaded reference counting thin pointer to a [`prim@str`],
/// optionally carrying arbitrary additional metadata
pub type RcStrThread<M = ()> = RcStr<ThreadCounter, M>;

/// Weak pointer to a single threaded reference counted thin pointer [`RcStrThread`]
pub type RcStrThreadWeak<M = ()> = RcStrWeak<ThreadCounter, M>;

/// Atomically counted reference counting thin pointer to a [`prim@str`],
/// optionally carrying arbitrary additional metadata
pub type RcStrAtomic<M = ()> = RcStr<AtomicCounter, M>;

/// Weak pointer to an atomically counted reference counted thin pointer [`RcStrAtomic`]
pub type RcStrAtomicWeak<M = ()> = RcStrWeak<AtomicCounter, M>;

impl<C> RcStr<C>
where
	C: Counter
{
	#[inline]
	pub fn new(s: &str) -> Self {
		Self { inner: Rc::from_slice_copy(s.as_bytes()) }
	}
}

impl<C, M> RcStr<C, M>
where
	C: Counter
{
	#[inline]
	pub fn with_metadata(s: &str, metadata: M) -> Self {
		Self { inner: Rc::from_value_and_slice_copy(metadata, s.as_bytes()) }
	}
}

impl<C, M> RcStr<C, M>
where
	C: Counter
{
	#[inline]
	pub fn strong_count(&self) -> usize {
		self.inner.strong_count()
	}

	#[inline]
	pub fn weak_count(&self) -> usize {
		self.inner.weak_count()
	}

	#[inline]
	pub fn downgrade(&self) -> RcStrWeak<C, M> {
		RcStrWeak { inner: self.inner.downgrade() }
	}
}

impl<C, M> Clone for RcStr<C, M>
where
	C: Counter
{
	#[inline]
	fn clone(&self) -> Self {
		Self { inner: self.inner.clone() }
	}
}

impl<C, M> Deref for RcStr<C, M>
where
	C: Counter
{
	type Target = str;

	#[inline]
	fn deref(&self) -> &str {
		// SAFETY: `RcStr` has invariant of containing valid utf-8
		unsafe { str::from_utf8_unchecked(self.inner.as_slice_ref()) }
	}
}

impl<C, M> RcStrWeak<C, M>
where
	C: Counter
{
	#[inline]
	pub fn strong_count(&self) -> usize {
		self.inner.strong_count()
	}

	#[inline]
	pub fn weak_count(&self) -> usize {
		self.inner.weak_count()
	}

	#[inline]
	pub fn upgrade(&self) -> Option<RcStr<C, M>> {
		self.inner.upgrade().map(|inner| RcStr { inner })
	}
}

impl<C, M> Clone for RcStrWeak<C, M>
where
	C: Counter
{
	#[inline]
	fn clone(&self) -> Self {
		Self { inner: self.inner.clone() }
	}
}