1use std::alloc::{Layout, LayoutError};
2use std::borrow;
3use std::cmp::Ordering;
4use std::ffi::{CStr, CString};
5use std::fmt;
6use std::hash::{Hash, Hasher};
7use std::iter;
8use std::marker::PhantomData;
9use std::mem;
10use std::mem::{ManuallyDrop, MaybeUninit};
11use std::ops::Deref;
12use std::panic::{RefUnwindSafe, UnwindSafe};
13use std::ptr::NonNull;
14
15use crate::refcount::RefCount;
16
17#[repr(C)]
18struct RcBox<T: ?Sized, C> {
19 strong: C,
20 value: T,
21}
22
23impl<T: ?Sized, C: RefCount> RcBox<T, C> {
24 #[inline]
25 fn strong(&self) -> &C {
26 &self.strong
27 }
28
29 #[inline]
30 unsafe fn layout_nopad(layout_value: Layout) -> Result<(Layout, usize), LayoutError> {
31 let layout_strong = Layout::new::<C>();
32 layout_strong.extend(layout_value)
33 }
34
35 #[inline]
36 unsafe fn layout_nopad_for_value(value: &T) -> Result<(Layout, usize), LayoutError> {
37 let layout_value = Layout::for_value(value);
38 Self::layout_nopad(layout_value)
39 }
40
41 #[inline]
42 unsafe fn offset_of_value(value: &T) -> usize {
43 Self::layout_nopad_for_value(value).unwrap().1
44 }
45}
46
47impl<T, C: RefCount> RcBox<T, C> {
48 unsafe fn allocate_for_slice(len: usize) -> NonNull<RcBox<[MaybeUninit<T>], C>> {
53 let layout_value = Layout::array::<T>(len).unwrap();
54 let (layout_nopad, _) = Self::layout_nopad(layout_value).unwrap();
55 let pthin = std::alloc::alloc(layout_nopad.pad_to_align());
56 assume!(!pthin.is_null());
57
58 let pfat = std::ptr::slice_from_raw_parts_mut::<T>(pthin as *mut T, len);
60
61 let pbox = pfat as *mut RcBox<[MaybeUninit<T>], MaybeUninit<C>>;
62
63 (*pbox).strong.write(C::one());
65
66 let pbox = pfat as *mut RcBox<[MaybeUninit<T>], C>;
67
68 NonNull::new(pbox).unwrap_unchecked()
69 }
70
71 #[inline]
72 unsafe fn assume_init_slice(
73 ptr: NonNull<RcBox<[MaybeUninit<T>], C>>,
74 ) -> NonNull<RcBox<[T], C>> {
75 NonNull::new(ptr.as_ptr() as *mut RcBox<[T], C>).unwrap_unchecked()
76 }
77
78 unsafe fn alloc_copy_from_ptr(ptr: *const T) -> NonNull<RcBox<T, C>> {
83 let (layout_nopad, offset) = Self::layout_nopad_for_value(&*ptr).unwrap();
84 let nopad_size = layout_nopad.size();
85 let palloc = std::alloc::alloc(layout_nopad.pad_to_align());
86 assume!(!palloc.is_null());
87
88 let pbox = palloc.cast::<RcBox<MaybeUninit<T>, MaybeUninit<C>>>();
89
90 (*pbox).strong.write(C::one());
92
93 assume!(offset <= nopad_size);
95 let copy_size = nopad_size - offset;
96 std::ptr::copy_nonoverlapping(
97 ptr as *const u8,
98 (*pbox).value.as_mut_ptr() as *mut u8,
99 copy_size,
100 );
101
102 let pbox = pbox.cast::<RcBox<T, C>>();
103 NonNull::new(pbox).unwrap_unchecked()
104 }
105}
106
107impl<T, C: RefCount> RcBox<T, C> {
108 #[inline]
109 unsafe fn as_uninit(&mut self) -> &mut RcBox<MaybeUninit<T>, C> {
110 mem::transmute(self)
111 }
112}
113
114pub(crate) struct RcBase<T: ?Sized, C: RefCount> {
116 ptr: NonNull<RcBox<T, C>>,
117
118 _phantom: PhantomData<RcBox<T, C>>,
121}
122
123unsafe impl<T, C> Send for RcBase<T, C>
124where
125 T: ?Sized + Sync + Send,
126 C: RefCount + Sync + Send,
127{
128}
129unsafe impl<T, C> Sync for RcBase<T, C>
130where
131 T: ?Sized + Sync + Send,
132 C: RefCount + Sync + Send,
133{
134}
135
136impl<T: RefUnwindSafe + ?Sized, C: RefCount> UnwindSafe for RcBase<T, C> {}
137impl<T: RefUnwindSafe + ?Sized, C: RefCount> RefUnwindSafe for RcBase<T, C> {}
138
139impl<T, C: RefCount> RcBase<T, C> {
140 #[inline]
141 unsafe fn unwrap_unchecked(self) -> T {
142 let mut this: ManuallyDrop<Self> = ManuallyDrop::new(self);
144
145 let uninit_rcbox: &mut RcBox<MaybeUninit<T>, C> = this.ptr.as_mut().as_uninit();
147
148 let _this_box: Box<RcBox<MaybeUninit<T>, C>> = Box::from_raw(uninit_rcbox);
150
151 uninit_rcbox.value.assume_init_read()
153 }
154
155 #[inline]
156 pub(crate) fn new(value: T) -> RcBase<T, C> {
157 unsafe {
158 Self::from_inner(
159 Box::leak(Box::new(RcBox {
160 strong: C::one(),
161 value,
162 }))
163 .into(),
164 )
165 }
166 }
167
168 #[inline]
169 pub(crate) fn try_unwrap(this: Self) -> Result<T, Self> {
170 if Self::is_unique(&this) {
171 unsafe { Ok(Self::unwrap_unchecked(this)) }
172 } else {
173 Err(this)
174 }
175 }
176
177 #[inline]
178 unsafe fn from_box(v: Box<T>) -> RcBase<T, C> {
179 let ptr = v.as_ref() as *const T;
180 let inner = RcBox::<T, C>::alloc_copy_from_ptr(ptr);
181
182 deallocate_box(v);
183
184 RcBase::from_inner(inner)
185 }
186
187 #[inline]
188 pub(crate) unsafe fn from_raw(ptr: *const T) -> Self {
189 assume!(!ptr.is_null());
190
191 let offset = RcBox::<T, C>::offset_of_value(&*ptr);
192
193 let value_addr = ptr as usize;
195 assume!(offset <= value_addr);
196 let box_addr = value_addr - offset;
197
198 let pbox = box_addr as *mut RcBox<T, C>;
199 Self::from_inner(NonNull::new(pbox).unwrap_unchecked())
200 }
201
202 #[inline]
203 pub(crate) unsafe fn increment_strong_count(ptr: *const T) {
204 let rc = Self::from_raw(ptr);
205 mem::forget(rc.clone());
207 mem::forget(rc);
208 }
209
210 #[inline]
211 pub(crate) unsafe fn decrement_strong_count(ptr: *const T) {
212 let rc = Self::from_raw(ptr);
213 drop(rc);
215 }
216
217 #[inline]
218 pub(crate) fn into_inner(mut this: Self) -> Option<T> {
219 unsafe {
220 if !this.decref() {
221 mem::forget(this);
222 return None;
223 }
224
225 Some(Self::unwrap_unchecked(this))
226 }
227 }
228}
229
230#[inline]
232unsafe fn deallocate_box<T: ?Sized>(v: Box<T>) {
233 let _drop = Box::from_raw(Box::into_raw(v) as *mut ManuallyDrop<T>);
234}
235
236impl<T: ?Sized, C: RefCount> RcBase<T, C> {
237 #[inline(always)]
248 unsafe fn decref(&mut self) -> bool {
249 if !C::is_one(&self.inner().strong().fetch_dec_release()) {
250 return false;
251 }
252
253 self.inner().strong().fence_acquire();
256
257 true
258 }
259
260 #[inline]
261 unsafe fn inner(&self) -> &RcBox<T, C> {
262 self.ptr.as_ref()
263 }
264
265 #[inline]
266 unsafe fn inner_mut(&mut self) -> &mut RcBox<T, C> {
267 self.ptr.as_mut()
268 }
269
270 #[inline]
271 unsafe fn from_inner(ptr: NonNull<RcBox<T, C>>) -> Self {
272 Self {
273 ptr,
274 _phantom: PhantomData,
275 }
276 }
277
278 #[inline]
279 pub(crate) fn as_ptr(this: &Self) -> *const T {
280 unsafe { &(*NonNull::as_ptr(this.ptr)).value }
282 }
283
284 #[inline]
285 pub(crate) fn into_raw(this: Self) -> *const T {
286 let ptr = Self::as_ptr(&this);
287 mem::forget(this);
288 ptr
289 }
290
291 #[inline]
292 pub(crate) fn strong_count(this: &Self) -> C::Value {
293 unsafe { this.inner().strong().load_acquire() }
294 }
295
296 #[inline]
297 fn is_unique(this: &Self) -> bool {
298 C::is_one(&Self::strong_count(this))
299 }
300
301 #[inline]
302 unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
303 &mut this.inner_mut().value
304 }
305
306 #[inline]
307 pub(crate) fn get_mut(this: &mut Self) -> Option<&mut T> {
308 if Self::is_unique(this) {
309 Some(unsafe { Self::get_mut_unchecked(this) })
310 } else {
311 None
312 }
313 }
314
315 #[inline]
316 pub(crate) fn ptr_eq(this: &Self, other: &Self) -> bool {
317 std::ptr::addr_eq(Self::as_ptr(this), Self::as_ptr(other))
320 }
321}
322
323impl<T: Clone, C: RefCount> RcBase<T, C> {
324 #[inline]
325 pub(crate) fn make_mut(this: &mut Self) -> &mut T {
326 if !Self::is_unique(this) {
327 *this = Self::new((**this).clone());
328 }
329 unsafe { Self::get_mut_unchecked(this) }
330 }
331}
332
333impl<T: ?Sized, C: RefCount> Deref for RcBase<T, C> {
334 type Target = T;
335
336 #[inline(always)]
337 fn deref(&self) -> &T {
338 unsafe { &self.inner().value }
339 }
340}
341
342impl<T: ?Sized, C: RefCount> Drop for RcBase<T, C> {
343 #[inline]
344 fn drop(&mut self) {
345 unsafe {
346 if !self.decref() {
347 return;
348 }
349
350 drop(Box::from_raw(self.ptr.as_mut()));
351 }
352 }
353}
354
355impl<T: ?Sized, C: RefCount> Clone for RcBase<T, C> {
356 #[inline]
357 fn clone(&self) -> RcBase<T, C> {
358 unsafe {
359 self.inner().strong().fetch_inc_relaxed();
360 Self::from_inner(self.ptr)
361 }
362 }
363}
364
365impl<T: Default, C: RefCount> Default for RcBase<T, C> {
366 #[inline]
367 fn default() -> RcBase<T, C> {
368 RcBase::new(Default::default())
369 }
370}
371
372impl<T: ?Sized + PartialEq, C: RefCount> PartialEq for RcBase<T, C> {
373 #[inline]
374 fn eq(&self, other: &RcBase<T, C>) -> bool {
375 PartialEq::eq(&**self, &**other)
379 }
380 #[inline]
381 fn ne(&self, other: &RcBase<T, C>) -> bool {
382 PartialEq::ne(&**self, &**other)
383 }
384}
385
386impl<T: ?Sized + Eq, C: RefCount> Eq for RcBase<T, C> {}
387
388impl<T: ?Sized + PartialOrd, C: RefCount> PartialOrd for RcBase<T, C> {
389 #[inline]
390 fn partial_cmp(&self, other: &RcBase<T, C>) -> Option<Ordering> {
391 PartialOrd::partial_cmp(&**self, &**other)
392 }
393}
394
395impl<T: ?Sized + Ord, C: RefCount> Ord for RcBase<T, C> {
396 #[inline]
397 fn cmp(&self, other: &RcBase<T, C>) -> Ordering {
398 Ord::cmp(&**self, &**other)
399 }
400}
401
402impl<T: ?Sized + Hash, C: RefCount> Hash for RcBase<T, C> {
403 #[inline]
404 fn hash<H: Hasher>(&self, state: &mut H) {
405 Hash::hash(&**self, state)
406 }
407}
408
409impl<T: ?Sized + fmt::Display, C: RefCount> fmt::Display for RcBase<T, C> {
410 #[inline]
411 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
412 fmt::Display::fmt(&**self, f)
413 }
414}
415
416impl<T: ?Sized + fmt::Debug, C: RefCount> fmt::Debug for RcBase<T, C> {
417 #[inline]
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419 fmt::Debug::fmt(&**self, f)
420 }
421}
422
423impl<T: ?Sized, C: RefCount> fmt::Pointer for RcBase<T, C> {
424 #[inline]
425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426 fmt::Pointer::fmt(&(RcBase::as_ptr(self)), f)
427 }
428}
429
430impl<T, C: RefCount> From<T> for RcBase<T, C> {
431 #[inline]
432 fn from(t: T) -> Self {
433 Self::new(t)
434 }
435}
436
437impl<T: Clone, C: RefCount> From<&[T]> for RcBase<[T], C> {
438 #[inline]
439 fn from(v: &[T]) -> RcBase<[T], C> {
440 unsafe {
441 let mut pbox = RcBox::<T, C>::allocate_for_slice(v.len());
442 let pvalue = &mut pbox.as_mut().value as *mut [MaybeUninit<T>];
443 assume!((*pvalue).len() == v.len());
444 for i in 0..v.len() {
445 *(*pvalue).get_unchecked_mut(i) = MaybeUninit::new(v.get_unchecked(i).clone());
446 }
447 Self::from_inner(RcBox::assume_init_slice(pbox))
448 }
449 }
450}
451
452impl<C: RefCount> From<&str> for RcBase<str, C> {
453 #[inline]
454 fn from(s: &str) -> RcBase<str, C> {
455 let rc = RcBase::<[u8], C>::from(s.as_bytes());
456 unsafe { mem::transmute(rc) }
457 }
458}
459
460impl<C: RefCount> From<String> for RcBase<str, C> {
461 #[inline]
462 fn from(s: String) -> RcBase<str, C> {
463 RcBase::from(s.as_ref())
464 }
465}
466
467impl<C: RefCount> From<&CStr> for RcBase<CStr, C> {
468 #[inline]
469 fn from(s: &CStr) -> RcBase<CStr, C> {
470 let rc = RcBase::<[u8], C>::from(s.to_bytes_with_nul());
471 unsafe { mem::transmute(rc) }
472 }
473}
474
475impl<C: RefCount> From<CString> for RcBase<CStr, C> {
476 #[inline]
477 fn from(s: CString) -> RcBase<CStr, C> {
478 RcBase::from(s.as_ref())
479 }
480}
481
482impl<T, C: RefCount> From<Box<T>> for RcBase<T, C> {
483 #[inline]
484 fn from(b: Box<T>) -> RcBase<T, C> {
485 unsafe { RcBase::from_box(b) }
486 }
487}
488
489impl<T, C: RefCount> From<Vec<T>> for RcBase<[T], C> {
490 #[inline]
491 fn from(mut v: Vec<T>) -> RcBase<[T], C> {
492 unsafe {
493 let mut pbox = RcBox::<T, C>::allocate_for_slice(v.len());
494 let pvalue = &mut pbox.as_mut().value as *mut [MaybeUninit<T>];
495 std::ptr::copy_nonoverlapping(
496 v.as_ptr() as *const MaybeUninit<T>,
497 pvalue as *mut MaybeUninit<T>,
498 v.len(),
499 );
500
501 v.set_len(0);
503
504 Self::from_inner(RcBox::assume_init_slice(pbox))
505 }
506 }
507}
508
509impl<C: RefCount> From<RcBase<str, C>> for RcBase<[u8], C> {
510 #[inline]
511 fn from(rc: RcBase<str, C>) -> Self {
512 unsafe { mem::transmute(rc) }
513 }
514}
515
516impl<T, C: RefCount, const N: usize> TryFrom<RcBase<[T], C>> for RcBase<[T; N], C> {
517 type Error = RcBase<[T], C>;
518
519 #[inline]
520 fn try_from(boxed_slice: RcBase<[T], C>) -> Result<Self, Self::Error> {
521 if boxed_slice.len() == N {
522 Ok(unsafe { RcBase::from_raw(RcBase::into_raw(boxed_slice) as *mut [T; N]) })
523 } else {
524 Err(boxed_slice)
525 }
526 }
527}
528
529impl<T, C: RefCount> iter::FromIterator<T> for RcBase<[T], C> {
530 #[inline]
531 fn from_iter<I: iter::IntoIterator<Item = T>>(iter: I) -> Self {
532 Self::from(iter.into_iter().collect::<Vec<T>>())
533 }
534}
535
536impl<T: ?Sized, C: RefCount> borrow::Borrow<T> for RcBase<T, C> {
537 #[inline]
538 fn borrow(&self) -> &T {
539 &**self
540 }
541}
542
543impl<T: ?Sized, C: RefCount> AsRef<T> for RcBase<T, C> {
544 #[inline]
545 fn as_ref(&self) -> &T {
546 &**self
547 }
548}
549
550impl<T: ?Sized, C: RefCount> Unpin for RcBase<T, C> {}
551
552#[cfg(test)]
553mod tests {
554 use super::*;
555 use std::borrow::Borrow;
556 use std::cell::Cell;
557
558 type Rc8<T> = RcBase<T, Cell<u8>>;
559 type StdRc<T> = std::rc::Rc<T>;
560
561 #[test]
562 fn new_deref() {
563 let rc = Rc8::new(1);
564 assert_eq!(*rc, 1);
565 }
566
567 #[test]
568 fn clone_drop_strong_count() {
569 let rc1 = Rc8::new(1);
570 assert_eq!(RcBase::strong_count(&rc1), 1);
571
572 let rc2 = rc1.clone();
573 assert_eq!(RcBase::strong_count(&rc1), 2);
574 assert_eq!(RcBase::strong_count(&rc2), 2);
575 assert_eq!(*rc1, 1);
576 assert_eq!(*rc2, 1);
577
578 drop(rc1);
579 assert_eq!(RcBase::strong_count(&rc2), 1);
580 assert_eq!(*rc2, 1);
581 }
582
583 #[test]
584 fn default() {
585 let rc = Rc8::<String>::default();
586 let stdrc = StdRc::<String>::default();
587
588 assert_eq!(*rc, *stdrc);
589 }
590
591 #[test]
592 fn debug() {
593 let rc = Rc8::new("debug".to_string());
594 let stdrc = StdRc::new("debug".to_string());
595
596 assert_eq!(format!("{:?}", rc), format!("{:?}", stdrc));
597 }
598
599 #[test]
600 fn display() {
601 let rc = Rc8::new("debug".to_string());
602 let stdrc = StdRc::new("debug".to_string());
603
604 assert_eq!(format!("{}", rc), format!("{}", stdrc));
605 }
606
607 #[test]
608 fn pointer() {
609 let rc = Rc8::new("debug".to_string());
610
611 assert_eq!(format!("{:p}", rc), format!("{:p}", RcBase::as_ptr(&rc)));
612 }
613
614 #[test]
615 fn as_ptr() {
616 let rc = Rc8::<u32>::new(1);
617
618 unsafe {
619 assert_eq!(*RcBase::as_ptr(&rc), 1);
620 }
621 }
622
623 #[test]
624 fn eq_ne() {
625 let rc = Rc8::<u32>::new(1);
626 let rc1 = Rc8::<u32>::new(1);
627 let rc2 = Rc8::<u32>::new(2);
628
629 assert_eq!(rc, rc1);
630 assert_ne!(rc, rc2);
631 }
632
633 #[test]
634 fn partial_cmp() {
635 let rc = Rc8::<u32>::new(2);
636 let rc1 = Rc8::<u32>::new(1);
637 let rc2 = Rc8::<u32>::new(2);
638 let rc3 = Rc8::<u32>::new(3);
639
640 assert_eq!(
641 PartialOrd::partial_cmp(&rc, &rc1),
642 PartialOrd::partial_cmp(&2, &1)
643 );
644 assert_eq!(
645 PartialOrd::partial_cmp(&rc, &rc2),
646 PartialOrd::partial_cmp(&2, &2)
647 );
648 assert_eq!(
649 PartialOrd::partial_cmp(&rc, &rc3),
650 PartialOrd::partial_cmp(&2, &3)
651 );
652 }
653
654 #[test]
655 fn cmp() {
656 let rc = Rc8::<u32>::new(2);
657 let rc1 = Rc8::<u32>::new(1);
658 let rc2 = Rc8::<u32>::new(2);
659 let rc3 = Rc8::<u32>::new(3);
660
661 assert_eq!(Ord::cmp(&rc, &rc1), Ord::cmp(&2, &1));
662 assert_eq!(Ord::cmp(&rc, &rc2), Ord::cmp(&2, &2));
663 assert_eq!(Ord::cmp(&rc, &rc3), Ord::cmp(&2, &3));
664 }
665
666 #[test]
667 fn hash() {
668 let rc = Rc8::new("hello".to_string());
669
670 let mut h = std::collections::hash_map::DefaultHasher::default();
671 Hash::hash(&rc, &mut h);
672 let hash_rc = h.finish();
673
674 let mut h = std::collections::hash_map::DefaultHasher::default();
675 Hash::hash("hello", &mut h);
676 let hash_hello = h.finish();
677
678 assert_eq!(hash_rc, hash_hello);
679 }
680
681 #[test]
682 fn max_strong_count() {
683 let rc = Rc8::new("hello".to_string());
684 assert_eq!(Rc8::strong_count(&rc), 1);
685
686 let mut v = Vec::new();
687 for _ in 0..254 {
688 v.push(rc.clone());
689 }
690
691 assert_eq!(Rc8::strong_count(&rc), 255);
692 }
694
695 #[test]
696 fn get_mut() {
697 let mut rc = Rc8::new(1i32);
698
699 let rc2 = rc.clone();
700 assert!(Rc8::get_mut(&mut rc).is_none());
701
702 drop(rc2);
703 assert!(Rc8::get_mut(&mut rc).is_some());
704
705 *Rc8::get_mut(&mut rc).unwrap() = 2;
706 assert_eq!(*rc, 2);
707 }
708
709 #[test]
710 fn ptr_eq() {
711 let rc = Rc8::new(1i32);
712 let rc_eq = rc.clone();
713 let rc_ne = Rc8::new(1i32);
714
715 assert!(Rc8::ptr_eq(&rc, &rc_eq));
716 assert!(!Rc8::ptr_eq(&rc, &rc_ne));
717 }
718
719 #[test]
720 fn make_mut() {
721 let mut rc = Rc8::new(1i32);
722 assert_eq!(*rc, 1);
723
724 *Rc8::make_mut(&mut rc) = 2;
725 assert_eq!(*rc, 2);
726
727 let rc2 = rc.clone();
728 assert_eq!(*rc2, 2);
729
730 *Rc8::make_mut(&mut rc) = 3;
731 assert_eq!(*rc, 3);
732 assert_eq!(*rc2, 2);
733 }
734
735 #[test]
736 fn try_unwrap() {
737 {
738 let rc = Rc8::new(1i32);
739 let v = Rc8::try_unwrap(rc);
740 assert_eq!(v.unwrap(), 1);
741 }
742
743 {
744 let rc = Rc8::new(1i32);
745 let _rc2 = rc.clone();
746 let v = Rc8::try_unwrap(rc);
747 assert_eq!(*v.unwrap_err(), 1);
748 }
749
750 {
751 let rc = Rc8::new(1i32);
752 let rc2 = rc.clone();
753 drop(rc2);
754 let v = Rc8::try_unwrap(rc);
755 assert_eq!(v.unwrap(), 1);
756 }
757 }
758
759 #[test]
760 fn into_inner() {
761 {
762 let rc = Rc8::new(1i32);
763 let v = Rc8::into_inner(rc);
764 assert_eq!(v.unwrap(), 1);
765 }
766
767 {
768 let rc = Rc8::new(1i32);
769 let rc2 = rc.clone();
770 assert!(Rc8::into_inner(rc).is_none());
771 assert_eq!(Rc8::into_inner(rc2).unwrap(), 1);
772 }
773
774 {
775 let rc = Rc8::new(1i32);
776 let rc2 = rc.clone();
777 drop(rc2);
778 let v = Rc8::into_inner(rc);
779 assert_eq!(v.unwrap(), 1);
780 }
781 }
782
783 #[test]
784 fn borrow() {
785 let rc = Rc8::<i32>::new(1i32);
786
787 assert_eq!(<Rc8<i32> as Borrow<i32>>::borrow(&rc), &1i32);
788 }
789
790 #[test]
791 fn as_ref() {
792 let rc = Rc8::<i32>::new(1i32);
793
794 assert_eq!(rc.as_ref(), &1i32);
795 }
796
797 #[test]
798 fn from_t() {
799 let value: String = "hello".to_string();
800 let rc = Rc8::<String>::from(value);
801
802 assert_eq!(*rc, "hello");
803 }
804
805 #[test]
806 fn into_raw() {
807 let rc = Rc8::<i32>::new(1i32);
808 let ptr = Rc8::as_ptr(&rc);
809
810 let raw = Rc8::into_raw(rc);
811 assert_eq!(raw, ptr);
812
813 unsafe { Rc8::from_raw(raw) };
814 }
815
816 #[test]
817 fn from_raw() {
818 let rc = Rc8::<i32>::new(1i32);
819 let ptr = Rc8::as_ptr(&rc);
820
821 let raw = Rc8::into_raw(rc);
822 assert_eq!(raw, ptr);
823
824 let rc2 = unsafe { Rc8::from_raw(raw) };
825 let ptr2 = Rc8::as_ptr(&rc2);
826 assert_eq!(ptr, ptr2);
827 assert_eq!(*rc2, 1);
828 }
829
830 #[test]
831 fn increment_decrement_strong_count() {
832 let rc = Rc8::<i32>::new(1i32);
833 let rc2 = rc.clone();
834 let ptr = Rc8::into_raw(rc2);
835
836 assert_eq!(Rc8::strong_count(&rc), 2);
837 unsafe {
838 Rc8::increment_strong_count(ptr);
839 }
840 assert_eq!(Rc8::strong_count(&rc), 3);
841
842 unsafe {
843 Rc8::decrement_strong_count(ptr);
844 }
845 assert_eq!(Rc8::strong_count(&rc), 2);
846
847 unsafe {
848 let _rc3 = Rc8::from_raw(ptr);
849 }
850 }
851
852 #[test]
853 fn from_vec() {
854 let rc = Rc8::<[i64]>::from(vec![0, 1, 2, 3, 4]);
855 assert_eq!(rc.len(), 5);
856 assert_eq!(rc[0], 0);
857 assert_eq!(rc[1], 1);
858 assert_eq!(rc[2], 2);
859 assert_eq!(rc[3], 3);
860 assert_eq!(rc[4], 4);
861 }
862
863 #[test]
864 fn from_large_vec() {
865 let v = (0..1000).collect::<Vec<_>>();
866 let rc = Rc8::<[i64]>::from(v);
867 assert_eq!(rc.len(), 1000);
868 for i in 0..1000 {
869 assert_eq!(rc[i], i as i64);
870 }
871 }
872
873 #[test]
874 fn from_iter() {
875 let rc = Rc8::<[i64]>::from_iter(0..5);
876 assert_eq!(rc.len(), 5);
877 assert_eq!(rc[0], 0);
878 assert_eq!(rc[1], 1);
879 assert_eq!(rc[2], 2);
880 assert_eq!(rc[3], 3);
881 assert_eq!(rc[4], 4);
882 }
883
884 #[test]
885 fn from_slice() {
886 let data = [0, 1, 2, 3, 4];
887 let rc = Rc8::<[i64]>::from(&data[..]);
888 assert_eq!(rc.len(), 5);
889 assert_eq!(rc[0], 0);
890 assert_eq!(rc[1], 1);
891 assert_eq!(rc[2], 2);
892 assert_eq!(rc[3], 3);
893 assert_eq!(rc[4], 4);
894 }
895
896 #[test]
897 fn from_str() {
898 let s = "Hello";
899 let rc = Rc8::<str>::from(s);
900 assert_eq!(rc.len(), 5);
901 assert_eq!(&*rc, "Hello");
902 }
903
904 #[test]
905 fn from_string() {
906 let s = "Hello".to_string();
907 let rc = Rc8::<str>::from(s);
908 assert_eq!(rc.len(), 5);
909 assert_eq!(&*rc, "Hello");
910 }
911
912 #[test]
913 fn from_cstr() {
914 let s = CString::new("Hello").unwrap();
915 let cs = s.as_c_str();
916 let rc = Rc8::<CStr>::from(cs);
917 let bytes = rc.to_bytes_with_nul();
918 assert_eq!(bytes.len(), 6);
919 assert_eq!(bytes, b"Hello\0");
920 }
921
922 #[test]
923 fn from_cstring() {
924 let s = CString::new("Hello").unwrap();
925 let rc = Rc8::<CStr>::from(s);
926 let bytes = rc.to_bytes_with_nul();
927 assert_eq!(bytes.len(), 6);
928 assert_eq!(bytes, b"Hello\0");
929 }
930
931 #[test]
932 fn str_to_slice() {
933 let s = "Hello";
934 let rc_str = Rc8::<str>::from(s);
935 let rc_slice = Rc8::<[u8]>::from(rc_str);
936
937 assert_eq!(rc_slice.len(), 5);
938 assert_eq!(rc_slice[0], b'H');
939 assert_eq!(rc_slice[1], b'e');
940 assert_eq!(rc_slice[2], b'l');
941 assert_eq!(rc_slice[3], b'l');
942 assert_eq!(rc_slice[4], b'o');
943 }
944
945 #[test]
946 fn from_box() {
947 let b = Box::<String>::from("Hello".to_string());
948 let rc = Rc8::<String>::from(b);
949 assert_eq!(&*rc, "Hello");
950 }
951
952 #[test]
953 fn try_from() {
954 let data = [0, 1, 2, 3, 4];
955 {
956 let rc_slice3 = Rc8::<[i64]>::from(&data[1..4]);
957 let rc1 = Rc8::<[i64; 1]>::try_from(rc_slice3);
958 assert!(rc1.is_err());
959 }
960 {
961 let rc_slice3 = Rc8::<[i64]>::from(&data[1..4]);
962 let rc = Rc8::<[i64; 2]>::try_from(rc_slice3);
963 assert!(rc.is_err());
964 }
965 {
966 let rc_slice3 = Rc8::<[i64]>::from(&data[1..4]);
967 let rc = Rc8::<[i64; 3]>::try_from(rc_slice3);
968 assert!(rc.is_ok());
969 let rc = rc.unwrap();
970 assert_eq!(rc[0], 1);
971 assert_eq!(rc[1], 2);
972 assert_eq!(rc[2], 3);
973 }
974 {
975 let rc_slice3 = Rc8::<[i64]>::from(&data[1..4]);
976 let rc = Rc8::<[i64; 4]>::try_from(rc_slice3);
977 assert!(rc.is_err());
978 }
979 {
980 let rc_slice3 = Rc8::<[i64]>::from(&data[1..4]);
981 let rc = Rc8::<[i64; 5]>::try_from(rc_slice3);
982 assert!(rc.is_err());
983 }
984 }
985}
986
987#[cfg(test)]
988mod leak_ckeck {
989 use super::*;
990 use std::cell::Cell;
991 use std::sync::atomic::AtomicU8;
992 use std::thread;
993
994 type Rc8<T> = RcBase<T, Cell<u8>>;
995 type Arc8<T> = RcBase<T, AtomicU8>;
996
997 #[test]
998 fn send() {
999 let (counter, viewer) = dropcount::new();
1000
1001 let rc = Arc8::new(counter);
1002
1003 let rc2 = rc.clone();
1004 let th = thread::spawn(move || {
1005 drop(rc2);
1006 });
1007
1008 drop(rc);
1009
1010 th.join().unwrap();
1011
1012 assert_eq!(viewer.get(), 1);
1013 }
1014
1015 #[test]
1016 fn sync() {
1017 let (counter, viewer) = dropcount::new();
1018
1019 let rc = Arc8::new(counter);
1020
1021 thread::scope(|s| {
1022 s.spawn(|| {
1023 let rc2 = rc.clone();
1024 drop(rc2);
1025 assert_eq!(viewer.get(), 0);
1026 });
1027 });
1028
1029 drop(rc);
1030 assert_eq!(viewer.get(), 1);
1031 }
1032
1033 #[test]
1034 fn single() {
1035 let (counter, viewer) = dropcount::new();
1036
1037 let rc = Rc8::new(counter);
1038 drop(rc);
1039 assert_eq!(viewer.get(), 1);
1040 }
1041
1042 #[test]
1043 fn clone() {
1044 let (counter, viewer) = dropcount::new();
1045 let rc = Rc8::new(counter);
1046 let rc2 = rc.clone();
1047 drop(rc);
1048 drop(rc2);
1049 assert_eq!(viewer.get(), 1);
1050 }
1051
1052 #[test]
1053 fn try_unwrap() {
1054 {
1055 let (counter, viewer) = dropcount::new();
1056 {
1057 let rc = Rc8::new(counter);
1058 let v = Rc8::try_unwrap(rc);
1059 assert!(v.is_ok());
1060 }
1061 assert_eq!(viewer.get(), 1);
1062 }
1063
1064 {
1065 let (counter, viewer) = dropcount::new();
1066 {
1067 let rc = Rc8::new(counter);
1068 let _rc2 = rc.clone();
1069 let v = Rc8::try_unwrap(rc);
1070 assert!(v.is_err());
1071 }
1072 assert_eq!(viewer.get(), 1);
1073 }
1074
1075 {
1076 let (counter, viewer) = dropcount::new();
1077 {
1078 let rc = Rc8::new(counter);
1079 let rc2 = rc.clone();
1080 drop(rc2);
1081 let v = Rc8::try_unwrap(rc);
1082 assert!(v.is_ok());
1083 }
1084 assert_eq!(viewer.get(), 1);
1085 }
1086 }
1087
1088 #[test]
1089 fn increment_decrement_strong_count() {
1090 let (counter, viewer) = dropcount::new();
1091 let rc = Rc8::new(counter);
1092 let rc2 = rc.clone();
1093 let ptr = Rc8::into_raw(rc2);
1094
1095 unsafe {
1096 Rc8::increment_strong_count(ptr);
1097 Rc8::decrement_strong_count(ptr);
1098 }
1099
1100 unsafe {
1101 let _rc3 = Rc8::from_raw(ptr);
1102 }
1103 drop(rc);
1104
1105 assert_eq!(viewer.get(), 1);
1106 }
1107
1108 #[test]
1109 fn from_box() {
1110 let (counter, viewer) = dropcount::new();
1111 let b = Box::new(counter);
1112 let rc = Rc8::<dropcount::Counter>::from(b);
1113 drop(rc);
1114 assert_eq!(viewer.get(), 1);
1115 }
1116
1117 #[test]
1118 fn from_vec() {
1119 let (counters, viewers) = dropcount::new_vec(5);
1120
1121 {
1122 let rc = Rc8::<[dropcount::Counter]>::from(counters);
1123 assert_eq!(rc.len(), 5);
1124 }
1125
1126 assert_eq!(viewers[0].get(), 1);
1127 assert_eq!(viewers[1].get(), 1);
1128 assert_eq!(viewers[2].get(), 1);
1129 assert_eq!(viewers[3].get(), 1);
1130 assert_eq!(viewers[4].get(), 1);
1131 }
1132
1133 #[test]
1134 fn from_iter() {
1135 let (counters, viewers) = dropcount::new_vec(5);
1136
1137 {
1138 let rc = Rc8::<[dropcount::Counter]>::from_iter(counters.into_iter());
1139 assert_eq!(rc.len(), 5);
1140 }
1141
1142 assert_eq!(viewers[0].get(), 1);
1143 assert_eq!(viewers[1].get(), 1);
1144 assert_eq!(viewers[2].get(), 1);
1145 assert_eq!(viewers[3].get(), 1);
1146 assert_eq!(viewers[4].get(), 1);
1147 }
1148}
1149
1150#[cfg(test)]
1151#[cfg(target_arch = "x86_64")]
1152mod rcbox_x86_64 {
1153 use super::*;
1154 use std::cell::Cell;
1155
1156 type RcBox8<T> = RcBox<T, Cell<u8>>;
1157 type RcBox16<T> = RcBox<T, Cell<u16>>;
1158 type RcBox32<T> = RcBox<T, Cell<u32>>;
1159 type RcBox64<T> = RcBox<T, Cell<u64>>;
1160 type RcBoxU<T> = RcBox<T, Cell<usize>>;
1161
1162 #[test]
1163 fn offset_of_value() {
1164 unsafe {
1165 assert_eq!(1, RcBox8::<u8>::offset_of_value(&0));
1166 assert_eq!(2, RcBox16::<u8>::offset_of_value(&0));
1167 assert_eq!(4, RcBox32::<u8>::offset_of_value(&0));
1168 assert_eq!(8, RcBox64::<u8>::offset_of_value(&0));
1169 assert_eq!(8, RcBoxU::<u8>::offset_of_value(&0));
1170 }
1171
1172 unsafe {
1173 assert_eq!(2, RcBox8::<u16>::offset_of_value(&0));
1174 assert_eq!(2, RcBox16::<u16>::offset_of_value(&0));
1175 assert_eq!(4, RcBox32::<u16>::offset_of_value(&0));
1176 assert_eq!(8, RcBox64::<u16>::offset_of_value(&0));
1177 assert_eq!(8, RcBoxU::<u16>::offset_of_value(&0));
1178 }
1179
1180 unsafe {
1181 assert_eq!(4, RcBox8::<u32>::offset_of_value(&0));
1182 assert_eq!(4, RcBox16::<u32>::offset_of_value(&0));
1183 assert_eq!(4, RcBox32::<u32>::offset_of_value(&0));
1184 assert_eq!(8, RcBox64::<u32>::offset_of_value(&0));
1185 assert_eq!(8, RcBoxU::<u32>::offset_of_value(&0));
1186 }
1187
1188 unsafe {
1189 assert_eq!(8, RcBox8::<u64>::offset_of_value(&0));
1190 assert_eq!(8, RcBox16::<u64>::offset_of_value(&0));
1191 assert_eq!(8, RcBox32::<u64>::offset_of_value(&0));
1192 assert_eq!(8, RcBox64::<u64>::offset_of_value(&0));
1193 assert_eq!(8, RcBoxU::<u64>::offset_of_value(&0));
1194 }
1195
1196 unsafe {
1197 assert_eq!(8, RcBox8::<usize>::offset_of_value(&0));
1198 assert_eq!(8, RcBox16::<usize>::offset_of_value(&0));
1199 assert_eq!(8, RcBox32::<usize>::offset_of_value(&0));
1200 assert_eq!(8, RcBox64::<usize>::offset_of_value(&0));
1201 assert_eq!(8, RcBoxU::<usize>::offset_of_value(&0));
1202 }
1203
1204 unsafe {
1205 assert_eq!(2, RcBox8::<(u8, u16)>::offset_of_value(&(0, 0)));
1206 assert_eq!(2, RcBox16::<(u8, u16)>::offset_of_value(&(0, 0)));
1207 assert_eq!(4, RcBox32::<(u8, u16)>::offset_of_value(&(0, 0)));
1208 assert_eq!(8, RcBox64::<(u8, u16)>::offset_of_value(&(0, 0)));
1209 assert_eq!(8, RcBoxU::<(u8, u16)>::offset_of_value(&(0, 0)));
1210 }
1211 }
1212
1213 #[test]
1214 fn offset_of_value_unsized() {
1215 unsafe {
1217 let value = [0, 1, 2, 3];
1218 assert_eq!(1, RcBox8::<[u8]>::offset_of_value(&value));
1219 assert_eq!(2, RcBox16::<[u8]>::offset_of_value(&value));
1220 assert_eq!(4, RcBox32::<[u8]>::offset_of_value(&value));
1221 assert_eq!(8, RcBox64::<[u8]>::offset_of_value(&value));
1222 assert_eq!(8, RcBoxU::<[u8]>::offset_of_value(&value));
1223 }
1224
1225 unsafe {
1227 let value = [0, 1, 2, 3];
1228 assert_eq!(2, RcBox8::<[u16]>::offset_of_value(&value));
1229 assert_eq!(2, RcBox16::<[u16]>::offset_of_value(&value));
1230 assert_eq!(4, RcBox32::<[u16]>::offset_of_value(&value));
1231 assert_eq!(8, RcBox64::<[u16]>::offset_of_value(&value));
1232 assert_eq!(8, RcBoxU::<[u16]>::offset_of_value(&value));
1233 }
1234
1235 unsafe {
1237 let value = [0, 1, 2, 3];
1238 assert_eq!(4, RcBox8::<[u32]>::offset_of_value(&value));
1239 assert_eq!(4, RcBox16::<[u32]>::offset_of_value(&value));
1240 assert_eq!(4, RcBox32::<[u32]>::offset_of_value(&value));
1241 assert_eq!(8, RcBox64::<[u32]>::offset_of_value(&value));
1242 assert_eq!(8, RcBoxU::<[u32]>::offset_of_value(&value));
1243 }
1244
1245 unsafe {
1247 let value = [0, 1, 2, 3];
1248 assert_eq!(8, RcBox8::<[u64]>::offset_of_value(&value));
1249 assert_eq!(8, RcBox16::<[u64]>::offset_of_value(&value));
1250 assert_eq!(8, RcBox32::<[u64]>::offset_of_value(&value));
1251 assert_eq!(8, RcBox64::<[u64]>::offset_of_value(&value));
1252 assert_eq!(8, RcBoxU::<[u64]>::offset_of_value(&value));
1253 }
1254
1255 unsafe {
1257 let value = [0, 1, 2, 3];
1258 assert_eq!(8, RcBox8::<[usize]>::offset_of_value(&value));
1259 assert_eq!(8, RcBox16::<[usize]>::offset_of_value(&value));
1260 assert_eq!(8, RcBox32::<[usize]>::offset_of_value(&value));
1261 assert_eq!(8, RcBox64::<[usize]>::offset_of_value(&value));
1262 assert_eq!(8, RcBoxU::<[usize]>::offset_of_value(&value));
1263 }
1264
1265 unsafe {
1267 let value = "Hello";
1268 assert_eq!(1, RcBox8::<str>::offset_of_value(value));
1269 assert_eq!(2, RcBox16::<str>::offset_of_value(value));
1270 assert_eq!(4, RcBox32::<str>::offset_of_value(value));
1271 assert_eq!(8, RcBox64::<str>::offset_of_value(value));
1272 assert_eq!(8, RcBoxU::<str>::offset_of_value(value));
1273 }
1274
1275 unsafe {
1277 trait MyTrait {}
1278 struct MyStruct(u32);
1279 impl MyTrait for MyStruct {}
1280 let value = MyStruct(0);
1281 assert_eq!(0, value.0); assert_eq!(4, RcBox8::<dyn MyTrait>::offset_of_value(&value));
1283 assert_eq!(4, RcBox16::<dyn MyTrait>::offset_of_value(&value));
1284 assert_eq!(4, RcBox32::<dyn MyTrait>::offset_of_value(&value));
1285 assert_eq!(8, RcBox64::<dyn MyTrait>::offset_of_value(&value));
1286 assert_eq!(8, RcBoxU::<dyn MyTrait>::offset_of_value(&value));
1287 }
1288 }
1289}