compact_rc/
base.rs

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    /// Allocate an RcBox with the given length.
49    ///
50    /// Returns a pointer to the allocated RcBox.
51    /// Its values are uninitialized, but counter initialized.
52    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        // Convert thin pointer to fat pointer.
59        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        // Initialize the refcount
64        (*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    /// Allocate and initialize an RcBox from a raw pointer.
79    ///
80    /// Returns a pointer to the allocated RcBox;
81    /// its contents are copied from the ptr, and counter initialized.
82    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        // Initialize the refcount
91        (*pbox).strong.write(C::one());
92
93        // memcpy the content.
94        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
114/// Base type of [RcX](crate::rc::RcX) and [ArcX](crate::arc::ArcX)
115pub(crate) struct RcBase<T: ?Sized, C: RefCount> {
116    ptr: NonNull<RcBox<T, C>>,
117
118    // NOTE PhantomData for dropck.
119    // This field indicates that this struct owns the data of type RcBox<T, C>.
120    _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        // this forgets calling RcBase's destructor.
143        let mut this: ManuallyDrop<Self> = ManuallyDrop::new(self);
144
145        // uninit_rcbox prevents calling T's destructor.
146        let uninit_rcbox: &mut RcBox<MaybeUninit<T>, C> = this.ptr.as_mut().as_uninit();
147
148        // this_box deallocates its memory at the end of this function, but does not call T's destructor.
149        let _this_box: Box<RcBox<MaybeUninit<T>, C>> = Box::from_raw(uninit_rcbox);
150
151        // move the value
152        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        // Get address of the RcBox.
194        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        // Increment the refcount, but do not drop it.
206        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        // Decrement the refcount by dropping it.
214        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/// Deallocate the box without dropping its contents
231#[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    /// Decrements its refcount,
238    /// then returns true if it is unique, otherwise false.
239    ///
240    /// If this method is called from every clones in multi-threaded code,
241    /// it is guaranteed that exactly one of the calls returns true.
242    /// See also [std::sync::Arc::into_inner].
243    ///
244    /// # Warning
245    /// The object MUST be destructed and deallocated by caller when true is returned,
246    /// but NOT when false.
247    #[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        // Memory fence
254        // Fence with acquire ordering is needed before dropping the object.
255        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        // The value should be initialized.
281        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        // This function ignores the metadata of fat pointers.
318        // See Rc::ptr_eq.
319        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        // NOTE
376        // Optimization by comparing their addresses can not be used for T: PartialEq.
377        // For T: Eq, it is possible. But the specialization is unstable feature.
378        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            // Deallocate the vec without dropping its contents.
502            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        // rc.clone(); // overflow
693    }
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        // slice
1216        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        // slice
1226        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        // slice
1236        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        // slice
1246        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        // slice
1256        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        // str
1266        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        // trait object
1276        unsafe {
1277            trait MyTrait {}
1278            struct MyStruct(u32);
1279            impl MyTrait for MyStruct {}
1280            let value = MyStruct(0);
1281            assert_eq!(0, value.0); // To suppress unused warning
1282            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}