Skip to main content

get_size2/impls/alloc_impls/
ownership.rs

1use alloc::borrow::{Cow, ToOwned};
2use alloc::boxed::Box;
3use alloc::rc::{Rc, Weak as RcWeak};
4// `Arc` is only provided by `alloc` on targets with pointer sized atomics.
5#[cfg(target_has_atomic = "ptr")]
6use alloc::sync::{Arc, Weak as ArcWeak};
7
8use crate::{GetSize, GetSizeTracker};
9
10impl<T> GetSize for Cow<'_, T>
11where
12    T: ToOwned + ?Sized,
13    T::Owned: GetSize,
14{
15    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, tracker: Tr) -> (usize, Tr) {
16        match self {
17            Self::Borrowed(_borrowed) => (0, tracker),
18            Self::Owned(owned) => <T::Owned>::get_heap_size_with_tracker(owned, tracker),
19        }
20    }
21}
22
23impl<T> GetSize for Box<T>
24where
25    T: GetSize,
26{
27    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, tracker: Tr) -> (usize, Tr) {
28        T::get_size_with_tracker(&**self, tracker)
29    }
30}
31
32impl<T> GetSize for Box<[T]>
33where
34    T: GetSize,
35{
36    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, tracker: Tr) -> (usize, Tr) {
37        let (size, tracker) = self.iter().fold((0, tracker), |(size, tracker), element| {
38            let (elem_size, tracker) = T::get_heap_size_with_tracker(element, tracker);
39            (size + elem_size, tracker)
40        });
41
42        let allocation_size = self.len() * T::get_stack_size();
43        (size + allocation_size, tracker)
44    }
45}
46
47impl<T> GetSize for Rc<T>
48where
49    T: GetSize,
50{
51    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, mut tracker: Tr) -> (usize, Tr) {
52        if tracker.track(Self::as_ptr(self)) {
53            T::get_size_with_tracker(&**self, tracker)
54        } else {
55            (0, tracker)
56        }
57    }
58}
59
60impl<T> GetSize for Rc<[T]>
61where
62    T: GetSize,
63{
64    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, mut tracker: Tr) -> (usize, Tr) {
65        if !tracker.track(Self::as_ptr(self).cast::<()>()) {
66            return (0, tracker);
67        }
68
69        let (size, tracker) = self.iter().fold((0, tracker), |(size, tracker), element| {
70            let (elem_size, tracker) = T::get_heap_size_with_tracker(element, tracker);
71            (size + elem_size, tracker)
72        });
73
74        let allocation_size = self.len() * T::get_stack_size();
75        (size + allocation_size, tracker)
76    }
77}
78
79impl<T> GetSize for RcWeak<T> {}
80
81#[cfg(target_has_atomic = "ptr")]
82impl<T> GetSize for Arc<T>
83where
84    T: GetSize,
85{
86    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, mut tracker: Tr) -> (usize, Tr) {
87        if tracker.track(Self::as_ptr(self)) {
88            T::get_size_with_tracker(&**self, tracker)
89        } else {
90            (0, tracker)
91        }
92    }
93}
94
95#[cfg(target_has_atomic = "ptr")]
96impl<T> GetSize for Arc<[T]>
97where
98    T: GetSize,
99{
100    fn get_heap_size_with_tracker<Tr: GetSizeTracker>(&self, mut tracker: Tr) -> (usize, Tr) {
101        if !tracker.track(Self::as_ptr(self).cast::<()>()) {
102            return (0, tracker);
103        }
104
105        let (size, tracker) = self.iter().fold((0, tracker), |(size, tracker), element| {
106            let (elem_size, tracker) = T::get_heap_size_with_tracker(element, tracker);
107            (size + elem_size, tracker)
108        });
109
110        let allocation_size = self.len() * T::get_stack_size();
111        (size + allocation_size, tracker)
112    }
113}
114
115#[cfg(target_has_atomic = "ptr")]
116impl<T> GetSize for ArcWeak<T> {}