counting_pointer/
sc.rs

1// Copyright 2020 Shin Yoshida
2//
3// "LGPL-3.0-or-later OR Apache-2.0 OR BSD-2-Clause"
4//
5// This is part of counting-pointer
6//
7//  counting-pointer is free software: you can redistribute it and/or modify
8//  it under the terms of the GNU Lesser General Public License as published by
9//  the Free Software Foundation, either version 3 of the License, or
10//  (at your option) any later version.
11//
12//  counting-pointer is distributed in the hope that it will be useful,
13//  but WITHOUT ANY WARRANTY; without even the implied warranty of
14//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//  GNU Lesser General Public License for more details.
16//
17//  You should have received a copy of the GNU Lesser General Public License
18//  along with counting-pointer.  If not, see <http://www.gnu.org/licenses/>.
19//
20//
21// Licensed under the Apache License, Version 2.0 (the "License");
22// you may not use this file except in compliance with the License.
23// You may obtain a copy of the License at
24//
25//     http://www.apache.org/licenses/LICENSE-2.0
26//
27// Unless required by applicable law or agreed to in writing, software
28// distributed under the License is distributed on an "AS IS" BASIS,
29// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30// See the License for the specific language governing permissions and
31// limitations under the License.
32//
33//
34// Redistribution and use in source and binary forms, with or without modification, are permitted
35// provided that the following conditions are met:
36//
37// 1. Redistributions of source code must retain the above copyright notice, this list of
38//    conditions and the following disclaimer.
39// 2. Redistributions in binary form must reproduce the above copyright notice, this
40//    list of conditions and the following disclaimer in the documentation and/or other
41//    materials provided with the distribution.
42//
43// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
44// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
47// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
49// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
50// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52// POSSIBILITY OF SUCH DAMAGE.
53
54use core::alloc::{GlobalAlloc, Layout};
55use core::any::Any;
56use core::cmp::Ordering;
57use core::hash::{Hash, Hasher};
58use core::mem::{self, align_of, size_of, MaybeUninit};
59use core::ops::Deref;
60use core::result::Result;
61use std::alloc::{handle_alloc_error, System};
62use std::borrow::Borrow;
63use std::fmt;
64
65/// Bucket of `Sc` to allocate/deallocate memory for reference count and value at once.
66#[repr(C)]
67struct Bucket<T: ?Sized> {
68    count: usize,
69    size: usize,
70    val: T,
71}
72
73impl<T> From<T> for Bucket<T> {
74    fn from(val: T) -> Self {
75        debug_assert_eq!(align_of::<usize>(), align_of::<Self>());
76
77        Self {
78            count: 1,
79            size: size_of::<Self>(),
80            val,
81        }
82    }
83}
84
85impl<T: ?Sized> Bucket<T> {
86    unsafe fn count(val: &mut T) -> &mut usize {
87        let ptr: *mut T = val;
88        let ptr: *mut usize = ptr.cast();
89        let ptr = ptr.sub(2);
90        &mut *ptr
91    }
92
93    unsafe fn size(ptr: *const T) -> usize {
94        let ptr: *const usize = ptr.cast();
95        let ptr = ptr.sub(1);
96        *ptr
97    }
98
99    unsafe fn dealloc_ptr(ptr: *mut T) -> *mut u8 {
100        let ptr: *mut usize = ptr.cast();
101        let ptr = ptr.sub(2);
102        ptr as *mut u8
103    }
104}
105
106/// A single-threaded strong reference-counting pointer. 'Sc' stands for 'Strong Counted.'
107///
108/// It behaves like `std::rc::Rc` except for that this treats only strong pointer; i.e. `Sc` gives
109/// up weak pointer for the performance.
110///
111/// The inherent methods of `Sc` are all associated funcitons, which means that you have to call
112/// them as e.g., `Sc::get_mut(&mut value)` instead of `value.get_mut()` . This avoids conflicts
113/// with methods of the inner type `T` .
114pub struct Sc<T: ?Sized, A = System>
115where
116    A: GlobalAlloc,
117{
118    ptr: *mut T,
119    alloc: A,
120}
121
122impl<T: ?Sized, A> Drop for Sc<T, A>
123where
124    A: GlobalAlloc,
125{
126    fn drop(&mut self) {
127        unsafe {
128            let count = Bucket::count(&mut *self.ptr);
129            *count -= 1;
130
131            if *count == 0 {
132                let layout =
133                    Layout::from_size_align(Bucket::size(self.ptr), align_of::<usize>()).unwrap();
134                let ptr = Bucket::dealloc_ptr(self.ptr);
135
136                self.ptr.drop_in_place();
137                self.alloc.dealloc(ptr, layout);
138            }
139        }
140    }
141}
142
143impl<T, A> Default for Sc<T, A>
144where
145    T: Default,
146    A: Default + GlobalAlloc,
147{
148    fn default() -> Self {
149        Self::new(T::default(), A::default())
150    }
151}
152
153impl<T, A> From<T> for Sc<T, A>
154where
155    A: Default + GlobalAlloc,
156{
157    fn from(val: T) -> Self {
158        Self::new(val, A::default())
159    }
160}
161
162impl<T, A> From<&'_ [T]> for Sc<[T], A>
163where
164    T: Clone,
165    A: Default + GlobalAlloc,
166{
167    fn from(vals: &'_ [T]) -> Self {
168        Sc::<T, A>::from_slice_alloc(vals, A::default())
169    }
170}
171
172impl<T: ?Sized, A> Clone for Sc<T, A>
173where
174    A: Clone + GlobalAlloc,
175{
176    fn clone(&self) -> Self {
177        // increment the count.
178        unsafe {
179            let val = &mut *self.ptr;
180            *Bucket::count(val) += 1;
181        };
182
183        Self {
184            ptr: self.ptr,
185            alloc: self.alloc.clone(),
186        }
187    }
188}
189
190impl<T, A> Sc<T, A>
191where
192    A: GlobalAlloc,
193{
194    /// Creates a new instance.
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use std::alloc::System;
200    /// use counting_pointer::Sc;
201    ///
202    /// let _five = Sc::new(5, System);
203    /// ```
204    pub fn new(val: T, alloc: A) -> Self {
205        let bucket = unsafe {
206            let layout = Layout::new::<Bucket<T>>();
207            let ptr = alloc.alloc(layout) as *mut Bucket<T>;
208            if ptr.is_null() {
209                handle_alloc_error(layout);
210            }
211
212            ptr.write(Bucket::from(val));
213            &mut *ptr
214        };
215        Self {
216            ptr: &mut bucket.val,
217            alloc,
218        }
219    }
220
221    /// Creates a new instance of `Sc<[T], A>` .
222    ///
223    /// # Examples
224    ///
225    /// ```
226    /// use std::alloc::System;
227    /// use counting_pointer::Sc;
228    ///
229    /// let vals: [i32; 4] = [0, 1, 2, 3];
230    /// let sc = Sc::from_slice_alloc(&vals, System);
231    /// assert_eq!(&vals, &*sc);
232    /// ```
233    pub fn from_slice_alloc(vals: &[T], alloc: A) -> Sc<[T], A>
234    where
235        T: Clone,
236    {
237        unsafe {
238            let layout = {
239                let align = align_of::<Bucket<T>>();
240                let size = size_of::<Bucket<T>>() - size_of::<Bucket<T>>()
241                    + vals.len() * size_of::<Bucket<T>>();
242                Layout::from_size_align_unchecked(size, align)
243            };
244
245            let ptr = alloc.alloc(layout) as *mut Bucket<T>;
246            if ptr.is_null() {
247                handle_alloc_error(layout);
248            }
249
250            let mut bucket = &mut *ptr;
251            bucket.count = 1;
252            bucket.size = layout.size();
253
254            let ptr = &mut bucket.val as *mut T;
255            for i in 0..vals.len() {
256                let v = vals[i].clone();
257                let ptr = ptr.add(i);
258                ptr.write(v);
259            }
260
261            let slice_ref = core::slice::from_raw_parts_mut(ptr, vals.len());
262            Sc::<[T], A> {
263                ptr: &mut *slice_ref,
264                alloc,
265            }
266        }
267    }
268}
269
270impl<A> Sc<dyn Any, A>
271where
272    A: GlobalAlloc,
273{
274    /// Creates `Sc<dyn Any>` instance.
275    ///
276    /// # Examples
277    ///
278    /// ```
279    /// use std::alloc::System;
280    /// use counting_pointer::Sc;
281    ///
282    /// let _five = Sc::new_any(5, System);
283    /// ```
284    pub fn new_any<T>(val: T, alloc: A) -> Self
285    where
286        T: Any,
287    {
288        let bucket = unsafe {
289            let layout = Layout::new::<Bucket<T>>();
290            let ptr = alloc.alloc(layout) as *mut Bucket<T>;
291            if ptr.is_null() {
292                handle_alloc_error(layout);
293            }
294
295            ptr.write(Bucket::from(val));
296            &mut *ptr
297        };
298        Self {
299            ptr: &mut bucket.val,
300            alloc,
301        }
302    }
303}
304
305impl<T: ?Sized, A> fmt::Debug for Sc<T, A>
306where
307    A: fmt::Debug + GlobalAlloc,
308{
309    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310        let ptr = format!("{:p}", self.ptr);
311        let alloc = format!("{:?}", self.alloc);
312
313        f.debug_struct("Sc")
314            .field("ptr", &ptr)
315            .field("alloc", &alloc)
316            .finish()
317    }
318}
319
320impl<T: ?Sized, A> PartialEq for Sc<T, A>
321where
322    T: PartialEq,
323    A: GlobalAlloc,
324{
325    fn eq(&self, other: &Self) -> bool {
326        let this: &T = self.borrow();
327        let other: &T = other.borrow();
328        this.eq(other)
329    }
330}
331
332impl<T: ?Sized, A> Eq for Sc<T, A>
333where
334    T: Eq,
335    A: GlobalAlloc,
336{
337}
338
339impl<T: ?Sized, A> PartialOrd for Sc<T, A>
340where
341    T: PartialOrd,
342    A: GlobalAlloc,
343{
344    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
345        let this: &T = self.borrow();
346        let other: &T = other.borrow();
347        this.partial_cmp(other)
348    }
349}
350
351impl<T: ?Sized, A> Ord for Sc<T, A>
352where
353    T: Ord,
354    A: GlobalAlloc,
355{
356    fn cmp(&self, other: &Self) -> Ordering {
357        let this: &T = self.borrow();
358        let other: &T = other.borrow();
359        this.cmp(other)
360    }
361}
362
363impl<T: ?Sized, A> Hash for Sc<T, A>
364where
365    T: Hash,
366    A: GlobalAlloc,
367{
368    fn hash<H>(&self, hasher: &mut H)
369    where
370        H: Hasher,
371    {
372        let inner: &T = self.borrow();
373        inner.hash(hasher);
374    }
375}
376
377impl<T: ?Sized, A> fmt::Display for Sc<T, A>
378where
379    T: fmt::Display,
380    A: GlobalAlloc,
381{
382    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
383        let inner: &T = self.deref();
384        fmt::Display::fmt(inner, f)
385    }
386}
387
388impl<T: ?Sized, A> AsRef<T> for Sc<T, A>
389where
390    A: GlobalAlloc,
391{
392    fn as_ref(&self) -> &T {
393        self.deref()
394    }
395}
396
397impl<T: ?Sized, A> Borrow<T> for Sc<T, A>
398where
399    A: GlobalAlloc,
400{
401    fn borrow(&self) -> &T {
402        self.deref()
403    }
404}
405
406impl<T: ?Sized, A> Deref for Sc<T, A>
407where
408    A: GlobalAlloc,
409{
410    type Target = T;
411
412    fn deref(&self) -> &Self::Target {
413        unsafe { &*self.ptr }
414    }
415}
416
417impl<T, A> Sc<T, A>
418where
419    A: GlobalAlloc,
420{
421    /// Consumes `this`, returning `Sc<dyn Any, A>`
422    ///
423    /// # Examples
424    ///
425    /// ```
426    /// use counting_pointer::Sc;
427    ///
428    /// let sc: Sc<i32> = Sc::from(6);
429    /// let any = Sc::to_any(sc);
430    /// ```
431    pub fn to_any(this: Self) -> Sc<dyn Any, A>
432    where
433        T: Any,
434    {
435        let (ptr, alloc) = Self::decouple(this);
436        Sc::<dyn Any, A> { ptr, alloc }
437    }
438}
439
440impl<T: ?Sized, A> Sc<T, A>
441where
442    A: GlobalAlloc,
443{
444    /// Provides a raw pointer to the data.
445    ///
446    /// The counts are not affected in any way and the `Sc` is not consumed. The pointer is valid
447    /// for as long as another `Sc` instance is pointing to the address.
448    ///
449    /// # Examples
450    ///
451    /// ```
452    /// use counting_pointer::Sc;
453    ///
454    /// let x: Sc<String> = Sc::from(String::from("Hello"));
455    /// let x_ptr = Sc::as_ptr(&x);
456    /// assert_eq!("Hello", unsafe { &*x_ptr });
457    /// ```
458    pub fn as_ptr(this: &Self) -> *const T {
459        this.ptr
460    }
461
462    /// Returns the number of `Sc` pointers pointing to the same address.
463    ///
464    /// # Examples
465    ///
466    /// ```
467    /// use counting_pointer::Sc;
468    ///
469    /// let five: Sc<i32> = Sc::from(5);
470    /// assert_eq!(1, Sc::count(&five));
471    ///
472    /// let _also_five = five.clone();
473    /// assert_eq!(2, Sc::count(&five));
474    /// assert_eq!(2, Sc::count(&_also_five));
475    ///
476    /// drop(five);
477    /// assert_eq!(1, Sc::count(&_also_five));
478    /// ```
479    pub fn count(this: &Self) -> usize {
480        unsafe {
481            let val = &mut *this.ptr;
482            *Bucket::count(val)
483        }
484    }
485
486    /// Returns a mutable reference into the given `Sc` , if no other `Sc` instance is pointing to
487    /// the same address; otherwise returns `None` .
488    ///
489    /// See also [`make_mut`] , which will `clone` the inner value when some other `Sc` instances
490    /// are.
491    ///
492    /// [`make_mut`]: #method.make_mut
493    ///
494    /// # Examples
495    ///
496    /// ```
497    /// use counting_pointer::Sc;
498    ///
499    /// let mut x: Sc<i32> = Sc::from(3);
500    /// assert_eq!(3, *x);
501    ///
502    /// *Sc::get_mut(&mut x).unwrap() = 4;
503    /// assert_eq!(4, *x);
504    ///
505    /// let _y = x.clone();
506    /// let n = Sc::get_mut(&mut x);
507    /// assert!(n.is_none());
508    /// ```
509    pub fn get_mut(this: &mut Self) -> Option<&mut T> {
510        if Self::count(this) == 1 {
511            Some(unsafe { &mut *this.ptr })
512        } else {
513            None
514        }
515    }
516
517    /// Returns `true` if the two `Sc` instances point to the same address, or `false` .
518    ///
519    /// # Examples
520    ///
521    /// ```
522    /// use counting_pointer::Sc;
523    ///
524    /// let five: Sc<i32> = Sc::from(5);
525    /// let same_five = five.clone();
526    /// let other_five: Sc<i32> = Sc::from(5);
527    ///
528    /// assert_eq!(true, Sc::ptr_eq(&five, &same_five));
529    /// assert_eq!(false, Sc::ptr_eq(&five, &other_five));
530    /// ```
531    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
532        Sc::as_ptr(this) == Sc::as_ptr(other)
533    }
534
535    /// Consumes `this` , returning the wrapped pointer and the allocator.
536    ///
537    /// To avoid memory leak, the returned pointer must be converted back to an `Sc` using
538    /// [`from_raw_alloc`] .
539    ///
540    /// Using this function and [`from_raw_alloc`] , user can create an `Sc<T: ?Sized>` instance.
541    ///
542    /// [`from_raw_alloc`]: #method.from_raw_alloc
543    ///
544    /// # Examples
545    ///
546    /// ```
547    /// use counting_pointer::Sc;
548    ///
549    /// let sc: Sc<String> = Sc::from("Foo".to_string());
550    /// let (ptr, alloc) = Sc::into_raw_alloc(sc);
551    /// let _sc: Sc<dyn AsRef<str>> = unsafe { Sc::from_raw_alloc(ptr, alloc) };
552    /// ```
553    pub fn into_raw_alloc(this: Self) -> (*const T, A) {
554        let (ptr, alloc) = Self::decouple(this);
555        (ptr, alloc)
556    }
557
558    /// Constructs a new instance from a raw pointer and allocator.
559    ///
560    /// The raw pointer must have been previously returned by a call to [`into_raw_alloc`] .
561    ///
562    /// Using this function and [`into_raw_alloc`] , user can create an `Sc<T: ?Sized>` instance.
563    ///
564    /// # Safety
565    ///
566    /// It may lead to memory unsafety to use improperly, even if the returned value will never be
567    /// accessed.
568    ///
569    /// [`into_raw_alloc`]: #method.into_raw_alloc
570    ///
571    /// # Examples
572    ///
573    /// ```
574    /// use counting_pointer::Sc;
575    ///
576    /// let sc: Sc<String> = Sc::from("Foo".to_string());
577    /// let (ptr, alloc) = Sc::into_raw_alloc(sc);
578    /// let _sc: Sc<dyn AsRef<str>> = unsafe { Sc::from_raw_alloc(ptr, alloc) };
579    /// ```
580    pub unsafe fn from_raw_alloc(ptr: *const T, alloc: A) -> Self {
581        Self {
582            ptr: ptr as *mut T,
583            alloc,
584        }
585    }
586
587    fn decouple(this: Self) -> (*mut T, A) {
588        let alloc = unsafe {
589            let mut alloc = MaybeUninit::<A>::uninit();
590            let ptr = alloc.as_mut_ptr();
591            ptr.copy_from_nonoverlapping(&this.alloc, 1);
592            alloc.assume_init()
593        };
594
595        let ret = (this.ptr, alloc);
596        mem::forget(this);
597        ret
598    }
599}
600
601impl<T: Clone, A: Clone> Sc<T, A>
602where
603    A: GlobalAlloc,
604{
605    /// Makes a mutable reference into the given `Sc` .
606    ///
607    /// If another `Sc` instance is pointing to the same address, `make_mut` will `clone` the inner
608    /// value to a new allocation to ensure unique ownership.
609    ///
610    /// See also [`get_mut`] , which will fail rather than cloning.
611    ///
612    /// [`get_mut`]: #method.get_mut
613    ///
614    /// # Examples
615    ///
616    /// ```
617    /// use counting_pointer::Sc;
618    ///
619    /// let mut data: Sc<i32> = Sc::from(5);
620    /// assert_eq!(5, *data);
621    ///
622    /// *Sc::make_mut(&mut data) += 1; // Won't clone anything.
623    /// assert_eq!(6, *data);
624    ///
625    /// let mut data2 = data.clone();  // Won't clone the inner data.
626    /// *Sc::make_mut(&mut data) += 1; // Clones inner data.
627    /// assert_eq!(7, *data);
628    /// assert_eq!(6, *data2);
629    /// ```
630    pub fn make_mut(this: &mut Self) -> &mut T {
631        if Self::count(this) != 1 {
632            let val: &T = this.deref();
633            *this = Sc::new(val.clone(), this.alloc.clone());
634        }
635
636        unsafe { &mut *this.ptr }
637    }
638}
639
640impl<A> Sc<dyn Any, A>
641where
642    A: GlobalAlloc,
643{
644    /// Attempts to downcast the `Sc<dyn Any, A>` to a concrete type.
645    ///
646    /// # Examples
647    ///
648    /// ```
649    /// use std::alloc::System;
650    /// use std::any::Any;
651    /// use counting_pointer::Sc;
652    ///
653    /// let sc = Sc::new_any(8 as i32, System);
654    ///
655    /// let success = Sc::downcast::<i32>(sc.clone()).unwrap();
656    /// assert_eq!(8, *success);
657    ///
658    /// let fail = Sc::downcast::<String>(sc.clone());
659    /// assert_eq!(true, fail.is_err());
660    /// ```
661    pub fn downcast<T: Any>(self) -> Result<Sc<T, A>, Self> {
662        let val: &mut dyn Any = unsafe { &mut *self.ptr };
663        match val.downcast_mut() {
664            None => Err(self),
665            Some(t) => {
666                let (_, alloc) = Self::decouple(self);
667                Ok(Sc::<T, A> {
668                    ptr: t as *mut T,
669                    alloc,
670                })
671            }
672        }
673    }
674}
675
676#[cfg(test)]
677mod tests {
678    use super::*;
679    use gharial::{GAlloc, GBox};
680
681    #[test]
682    fn new() {
683        let five = GBox::from(5);
684        let _five = Sc::new(five, GAlloc::default());
685    }
686
687    #[test]
688    fn clone() {
689        let five = GBox::from(5);
690
691        let five = Sc::new(five, GAlloc::default());
692        let _cloned = five.clone();
693    }
694
695    #[test]
696    fn make_mut() {
697        let inner = GBox::from(5);
698
699        let mut data = Sc::new(inner, GAlloc::default());
700        {
701            let _mr = Sc::make_mut(&mut data);
702        }
703
704        let _data2 = data.clone();
705        {
706            let _mr = Sc::make_mut(&mut data);
707        }
708    }
709
710    #[test]
711    fn downcast() {
712        let inner = GBox::from(8);
713
714        let sc = Sc::new_any(inner, GAlloc::default());
715
716        let ok = Sc::downcast::<GBox<i32>>(sc.clone());
717        assert_eq!(true, ok.is_ok());
718
719        let fail = Sc::downcast::<String>(sc.clone());
720        assert_eq!(true, fail.is_err());
721    }
722
723    #[test]
724    fn to_any() {
725        let inner = GBox::from(6);
726
727        let sc = Sc::new(inner, GAlloc::default());
728        let _any = Sc::to_any(sc);
729    }
730
731    #[test]
732    fn from_slice_alloc() {
733        let inners: [GBox<i32>; 2] = [GBox::from(6), GBox::from(4)];
734
735        let _sc = Sc::from_slice_alloc(&inners, GAlloc::default());
736    }
737
738    #[test]
739    fn raw_alloc() {
740        let sc: Sc<GBox<i32>> = Sc::from(GBox::from(0));
741        let (ptr, alloc) = Sc::into_raw_alloc(sc);
742        let _sc = unsafe { Sc::from_raw_alloc(ptr, alloc) };
743    }
744}