size_of/
core_impls.rs

1use crate::{Context, SizeOf};
2use alloc::{
3    alloc::Layout,
4    borrow::{Cow, ToOwned},
5};
6use core::{
7    any::TypeId,
8    cell::{Cell, RefCell},
9    cmp::{self, Reverse},
10    convert::Infallible,
11    ffi::CStr,
12    fmt::Arguments,
13    future::Pending,
14    hash::BuildHasherDefault,
15    marker::{PhantomData, PhantomPinned},
16    mem::{ManuallyDrop, MaybeUninit},
17    num::{
18        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
19        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
20    },
21    ops::{ControlFlow, Deref},
22    panic::{AssertUnwindSafe, Location},
23    pin::Pin,
24    sync::atomic::{
25        self, AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16,
26        AtomicU32, AtomicU64, AtomicU8, AtomicUsize,
27    },
28    task::Poll,
29    time::Duration,
30};
31
32impl<const N: usize, T> SizeOf for [T; N]
33where
34    T: SizeOf,
35{
36    #[inline]
37    fn size_of_children(&self, context: &mut Context) {
38        self.as_slice().size_of_children(context);
39    }
40}
41
42impl<T> SizeOf for [T]
43where
44    T: SizeOf,
45{
46    #[inline]
47    fn size_of_children(&self, context: &mut Context) {
48        self.iter()
49            .for_each(|element| element.size_of_children(context));
50    }
51}
52
53impl<T> SizeOf for ManuallyDrop<T>
54where
55    T: SizeOf,
56{
57    #[inline]
58    fn size_of_children(&self, context: &mut Context) {
59        self.deref().size_of_children(context);
60    }
61}
62
63impl<T> SizeOf for Option<T>
64where
65    T: SizeOf,
66{
67    #[inline]
68    fn size_of_children(&self, context: &mut Context) {
69        if let Some(inner) = self {
70            inner.size_of_children(context);
71        }
72    }
73}
74
75impl<T, E> SizeOf for Result<T, E>
76where
77    T: SizeOf,
78    E: SizeOf,
79{
80    #[inline]
81    fn size_of_children(&self, context: &mut Context) {
82        match self {
83            Ok(ok) => ok.size_of_children(context),
84            Err(err) => err.size_of_children(context),
85        }
86    }
87}
88
89impl<T> SizeOf for Reverse<T>
90where
91    T: SizeOf,
92{
93    #[inline]
94    fn size_of_children(&self, context: &mut Context) {
95        self.0.size_of_children(context);
96    }
97}
98
99// TODO: Is there a better impl for this?
100impl<T> SizeOf for Pin<T>
101where
102    T: Deref,
103    T::Target: SizeOf,
104{
105    #[inline]
106    fn size_of_children(&self, context: &mut Context) {
107        self.deref().size_of_children(context);
108    }
109}
110
111impl<T> SizeOf for Cell<T>
112where
113    T: Copy + SizeOf,
114{
115    #[inline]
116    fn size_of_children(&self, context: &mut Context) {
117        self.get().size_of_children(context);
118    }
119}
120
121impl<T> SizeOf for RefCell<T>
122where
123    T: SizeOf,
124{
125    #[inline]
126    fn size_of_children(&self, context: &mut Context) {
127        // Ignore any errors that occur while trying to borrow a RefCell
128        if let Ok(cell) = self.try_borrow() {
129            cell.deref().size_of_children(context);
130        }
131    }
132}
133
134impl SizeOf for Location<'_> {
135    #[inline]
136    fn size_of_children(&self, context: &mut Context) {
137        self.file().size_of_children(context);
138    }
139}
140
141// TODO: Saturating<T> once it's stable
142impl<T> SizeOf for Wrapping<T>
143where
144    T: SizeOf,
145{
146    #[inline]
147    fn size_of_children(&self, context: &mut Context) {
148        self.0.size_of_children(context);
149    }
150}
151
152impl<C, B> SizeOf for ControlFlow<C, B>
153where
154    C: SizeOf,
155    B: SizeOf,
156{
157    #[inline]
158    fn size_of_children(&self, context: &mut Context) {
159        match self {
160            Self::Continue(cont) => cont.size_of_children(context),
161            Self::Break(brk) => brk.size_of_children(context),
162        }
163    }
164}
165
166impl<'a, T> SizeOf for Cow<'a, T>
167where
168    T: ToOwned + ?Sized + 'a,
169    T::Owned: SizeOf,
170{
171    #[inline]
172    fn size_of_children(&self, context: &mut Context) {
173        if let Self::Owned(owned) = self {
174            owned.size_of_children(context);
175        }
176    }
177}
178
179// TODO: `core::future::Ready<T>`, the problem is that currently there's no way
180// to access the inner value
181
182impl<T> SizeOf for Poll<T>
183where
184    T: SizeOf,
185{
186    #[inline]
187    fn size_of_children(&self, context: &mut Context) {
188        if let Self::Ready(ready) = self {
189            ready.size_of_children(context);
190        }
191    }
192}
193
194impl<T> SizeOf for AssertUnwindSafe<T>
195where
196    T: SizeOf,
197{
198    #[inline]
199    fn size_of_children(&self, context: &mut Context) {
200        self.0.size_of_children(context);
201    }
202}
203
204impl SizeOf for Arguments<'_> {
205    #[inline]
206    fn size_of_children(&self, _context: &mut Context) {}
207}
208
209impl_total_size_childless! {
210    str,
211    bool,
212    char,
213
214    u8,
215    i8,
216    u16,
217    i16,
218    u32,
219    i32,
220    u64,
221    i64,
222    u128,
223    i128,
224    usize,
225    isize,
226
227    f32,
228    f64,
229
230    AtomicBool,
231    AtomicU8,
232    AtomicI8,
233    AtomicU16,
234    AtomicI16,
235    AtomicU32,
236    AtomicI32,
237    AtomicU64,
238    AtomicI64,
239    AtomicUsize,
240    AtomicIsize,
241
242    NonZeroU8,
243    NonZeroI8,
244    NonZeroU16,
245    NonZeroI16,
246    NonZeroU32,
247    NonZeroI32,
248    NonZeroU64,
249    NonZeroI64,
250    NonZeroU128,
251    NonZeroI128,
252    NonZeroUsize,
253    NonZeroIsize,
254
255    CStr,
256    Layout,
257    TypeId,
258    Duration,
259    // `Pending<T>` is a zst
260    Pending<T>,
261    Infallible,
262    cmp::Ordering,
263    PhantomPinned,
264    MaybeUninit<T>,
265    PhantomData<T>,
266    atomic::Ordering,
267    // BuildHasherDefault is a zst
268    BuildHasherDefault<T>,
269}
270
271// Implement SizeOf for up to 16-tuples
272impl_tuple! {
273    (),
274    (A),
275    (A, B),
276    (A, B, C),
277    (A, B, C, D),
278    (A, B, C, D, E),
279    (A, B, C, D, E, F),
280    (A, B, C, D, E, F, G),
281    (A, B, C, D, E, F, G, H),
282    (A, B, C, D, E, F, G, H, I),
283    (A, B, C, D, E, F, G, H, I, J),
284    (A, B, C, D, E, F, G, H, I, J, K),
285    (A, B, C, D, E, F, G, H, I, J, K, L),
286    (A, B, C, D, E, F, G, H, I, J, K, L, M),
287    (A, B, C, D, E, F, G, H, I, J, K, L, M, N),
288    (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O),
289    (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P),
290}
291
292// Implement SizeOf for different calling conventions for functions with up to
293// 16 arguments
294impl_function_ptrs! {
295    "C",
296    "Rust",
297    "aapcs",
298    "cdecl",
299    "win64",
300    "sysv64",
301    "system",
302    "stdcall",
303    "fastcall",
304}