1use std::borrow;
2use std::borrow::Cow;
3use std::cmp::Ordering;
4use std::ffi::{CStr, CString};
5use std::fmt;
6use std::hash::{Hash, Hasher};
7use std::iter;
8use std::ops::Deref;
9use std::pin::Pin;
10use std::sync::atomic::{AtomicU16, AtomicU32, AtomicU64, AtomicU8, AtomicUsize};
11
12use crate::base::RcBase;
13use crate::refcount::RefCount;
14
15pub type Arc8<T> = ArcX<T, AtomicU8>;
17pub type Arc16<T> = ArcX<T, AtomicU16>;
19pub type Arc32<T> = ArcX<T, AtomicU32>;
21pub type Arc64<T> = ArcX<T, AtomicU64>;
23pub type Arc<T> = ArcX<T, AtomicUsize>;
25
26pub struct ArcX<T: ?Sized, C>(RcBase<T, C>)
38where
39 C: RefCount + Sync + Send;
40
41impl<T, C> ArcX<T, C>
42where
43 C: RefCount + Sync + Send,
44{
45 #[inline]
47 pub fn new(value: T) -> ArcX<T, C> {
48 ArcX(RcBase::new(value))
49 }
50
51 #[inline]
53 pub fn pin(value: T) -> Pin<ArcX<T, C>> {
54 unsafe { Pin::new_unchecked(Self::new(value)) }
55 }
56
57 #[inline]
59 pub fn try_unwrap(this: Self) -> Result<T, Self> {
60 RcBase::try_unwrap(this.0).map_err(Self)
61 }
62
63 #[inline]
69 pub unsafe fn from_raw(ptr: *const T) -> Self {
70 Self(RcBase::from_raw(ptr))
71 }
72
73 #[inline]
75 pub unsafe fn increment_strong_count(ptr: *const T) {
76 RcBase::<T, C>::increment_strong_count(ptr)
77 }
78
79 #[inline]
81 pub unsafe fn decrement_strong_count(ptr: *const T) {
82 RcBase::<T, C>::decrement_strong_count(ptr)
83 }
84
85 #[inline]
87 pub fn into_inner(this: Self) -> Option<T> {
88 RcBase::into_inner(this.0)
89 }
90}
91
92impl<T: ?Sized, C> ArcX<T, C>
93where
94 C: RefCount + Sync + Send,
95{
96 #[inline]
98 pub fn as_ptr(this: &Self) -> *const T {
99 RcBase::as_ptr(&this.0)
100 }
101
102 #[inline]
104 pub fn into_raw(this: Self) -> *const T {
105 RcBase::into_raw(this.0)
106 }
107
108 #[inline]
110 pub fn strong_count(this: &Self) -> <C as RefCount>::Value {
111 RcBase::strong_count(&this.0)
112 }
113
114 #[inline]
116 pub fn get_mut(this: &mut Self) -> Option<&mut T> {
117 RcBase::get_mut(&mut this.0)
118 }
119
120 #[inline]
122 pub fn ptr_eq(this: &Self, other: &Self) -> bool {
123 RcBase::ptr_eq(&this.0, &other.0)
124 }
125}
126
127impl<T: Clone, C> ArcX<T, C>
128where
129 C: RefCount + Sync + Send,
130{
131 #[inline]
133 pub fn make_mut(this: &mut Self) -> &mut T {
134 RcBase::make_mut(&mut this.0)
135 }
136}
137
138impl<T: ?Sized, C> Deref for ArcX<T, C>
139where
140 C: RefCount + Sync + Send,
141{
142 type Target = T;
143
144 #[inline(always)]
145 fn deref(&self) -> &T {
146 self.0.deref()
147 }
148}
149
150impl<T: ?Sized, C> Clone for ArcX<T, C>
151where
152 C: RefCount + Sync + Send,
153{
154 #[inline]
155 fn clone(&self) -> ArcX<T, C> {
156 Self(self.0.clone())
157 }
158}
159
160impl<T: Default, C> Default for ArcX<T, C>
161where
162 C: RefCount + Sync + Send,
163{
164 #[inline]
165 fn default() -> ArcX<T, C> {
166 ArcX::new(Default::default())
167 }
168}
169
170impl<T: ?Sized + PartialEq, C> PartialEq for ArcX<T, C>
171where
172 C: RefCount + Sync + Send,
173{
174 #[inline]
175 fn eq(&self, other: &ArcX<T, C>) -> bool {
176 PartialEq::eq(&self.0, &other.0)
177 }
178 #[inline]
179 fn ne(&self, other: &ArcX<T, C>) -> bool {
180 PartialEq::ne(&self.0, &other.0)
181 }
182}
183
184impl<T: ?Sized + Eq, C> Eq for ArcX<T, C> where C: RefCount + Sync + Send {}
185
186impl<T: ?Sized + PartialOrd, C> PartialOrd for ArcX<T, C>
187where
188 C: RefCount + Sync + Send,
189{
190 #[inline]
191 fn partial_cmp(&self, other: &ArcX<T, C>) -> Option<Ordering> {
192 PartialOrd::partial_cmp(&self.0, &other.0)
193 }
194}
195
196impl<T: ?Sized + Ord, C> Ord for ArcX<T, C>
197where
198 C: RefCount + Sync + Send,
199{
200 #[inline]
201 fn cmp(&self, other: &ArcX<T, C>) -> Ordering {
202 Ord::cmp(&self.0, &other.0)
203 }
204}
205
206impl<T: ?Sized + Hash, C> Hash for ArcX<T, C>
207where
208 C: RefCount + Sync + Send,
209{
210 #[inline]
211 fn hash<H: Hasher>(&self, state: &mut H) {
212 Hash::hash(&self.0, state)
213 }
214}
215
216impl<T: ?Sized + fmt::Display, C> fmt::Display for ArcX<T, C>
217where
218 C: RefCount + Sync + Send,
219{
220 #[inline]
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 fmt::Display::fmt(&self.0, f)
223 }
224}
225
226impl<T: ?Sized + fmt::Debug, C> fmt::Debug for ArcX<T, C>
227where
228 C: RefCount + Sync + Send,
229{
230 #[inline]
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 fmt::Debug::fmt(&self.0, f)
233 }
234}
235
236impl<T: ?Sized, C> fmt::Pointer for ArcX<T, C>
237where
238 C: RefCount + Sync + Send,
239{
240 #[inline]
241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242 fmt::Pointer::fmt(&self.0, f)
243 }
244}
245
246impl<T, C> From<T> for ArcX<T, C>
247where
248 C: RefCount + Sync + Send,
249{
250 #[inline]
251 fn from(t: T) -> Self {
252 Self(RcBase::from(t))
253 }
254}
255
256impl<T: Clone, C> From<&[T]> for ArcX<[T], C>
257where
258 C: RefCount + Sync + Send,
259{
260 #[inline]
261 fn from(v: &[T]) -> ArcX<[T], C> {
262 Self(RcBase::from(v))
263 }
264}
265
266impl<C> From<&str> for ArcX<str, C>
267where
268 C: RefCount + Sync + Send,
269{
270 #[inline]
271 fn from(s: &str) -> ArcX<str, C> {
272 Self(RcBase::from(s))
273 }
274}
275
276impl<C> From<String> for ArcX<str, C>
277where
278 C: RefCount + Sync + Send,
279{
280 #[inline]
281 fn from(s: String) -> ArcX<str, C> {
282 Self(RcBase::from(s))
283 }
284}
285
286impl<C> From<&CStr> for ArcX<CStr, C>
287where
288 C: RefCount + Sync + Send,
289{
290 #[inline]
291 fn from(s: &CStr) -> ArcX<CStr, C> {
292 Self(RcBase::from(s))
293 }
294}
295
296impl<C> From<CString> for ArcX<CStr, C>
297where
298 C: RefCount + Sync + Send,
299{
300 #[inline]
301 fn from(s: CString) -> ArcX<CStr, C> {
302 Self(RcBase::from(s))
303 }
304}
305
306impl<T, C> From<Box<T>> for ArcX<T, C>
307where
308 C: RefCount + Sync + Send,
309{
310 #[inline]
311 fn from(b: Box<T>) -> ArcX<T, C> {
312 Self(RcBase::from(b))
313 }
314}
315
316impl<T, C> From<Vec<T>> for ArcX<[T], C>
317where
318 C: RefCount + Sync + Send,
319{
320 #[inline]
321 fn from(v: Vec<T>) -> ArcX<[T], C> {
322 Self(RcBase::from(v))
323 }
324}
325
326impl<'a, B, C> From<Cow<'a, B>> for ArcX<B, C>
327where
328 C: RefCount + Sync + Send,
329 B: ToOwned + ?Sized,
330 ArcX<B, C>: From<&'a B> + From<B::Owned>,
331{
332 #[inline]
333 fn from(cow: Cow<'a, B>) -> ArcX<B, C> {
334 match cow {
335 Cow::Borrowed(s) => ArcX::from(s),
336 Cow::Owned(s) => ArcX::from(s),
337 }
338 }
339}
340
341impl<C> From<ArcX<str, C>> for ArcX<[u8], C>
342where
343 C: RefCount + Sync + Send,
344{
345 #[inline]
346 fn from(rc: ArcX<str, C>) -> Self {
347 Self(RcBase::from(rc.0))
348 }
349}
350
351impl<T, C, const N: usize> TryFrom<ArcX<[T], C>> for ArcX<[T; N], C>
352where
353 C: RefCount + Sync + Send,
354{
355 type Error = ArcX<[T], C>;
356
357 #[inline]
358 fn try_from(boxed_slice: ArcX<[T], C>) -> Result<Self, Self::Error> {
359 RcBase::try_from(boxed_slice.0)
360 .map(Self)
361 .map_err(ArcX::<[T], C>)
362 }
363}
364
365impl<T, C> iter::FromIterator<T> for ArcX<[T], C>
366where
367 C: RefCount + Sync + Send,
368{
369 #[inline]
370 fn from_iter<I: iter::IntoIterator<Item = T>>(iter: I) -> Self {
371 Self(RcBase::from_iter(iter))
372 }
373}
374
375impl<T: ?Sized, C> borrow::Borrow<T> for ArcX<T, C>
376where
377 C: RefCount + Sync + Send,
378{
379 #[inline]
380 fn borrow(&self) -> &T {
381 self.0.borrow()
382 }
383}
384
385impl<T: ?Sized, C> AsRef<T> for ArcX<T, C>
386where
387 C: RefCount + Sync + Send,
388{
389 #[inline]
390 fn as_ref(&self) -> &T {
391 self.0.as_ref()
392 }
393}
394
395#[cfg(test)]
396mod tests {
397 use super::*;
398
399 #[test]
400 fn pin() {
401 let rc = Arc8::pin(1i32);
402
403 assert_eq!(*rc, 1);
404 }
405
406 #[test]
407 fn from_cow() {
408 {
410 let v = "Hello".to_string();
411 let owned: Cow<str> = Cow::Owned(v);
412 assert!(matches!(owned, Cow::Owned(_)));
413 let rc = Arc8::<str>::from(owned);
414 assert_eq!(&*rc, "Hello");
415 }
416
417 {
419 let v = "Hello";
420 let borrowed: Cow<str> = Cow::Borrowed(v);
421 assert!(matches!(borrowed, Cow::Borrowed(_)));
422 let rc = Arc8::<str>::from(borrowed);
423 assert_eq!(&*rc, "Hello");
424 }
425 }
426}