ladata/mem/size/mod.rs
1// ladata::mem::size
2//
3//! Traits related to memory size.
4//
5
6use core::mem::{size_of, size_of_val};
7
8mod bit_size;
9pub use bit_size::*;
10
11impl<T> DataSize for T {}
12
13/// Convenience trait for Size related information.
14///
15/// It is automatically implemented for every sized type.
16pub trait DataSize: Sized {
17 /// The size of this type in bytes, rounded up if it's not a multiple of 8.
18 const BYTES: usize = size_of::<Self>();
19
20 /// The pointer size in bits for the current platform.
21 const UBITS: usize = Self::UBYTES * 8;
22
23 /// The pointer size in bytes for the current platform.
24 const UBYTES: usize = size_of::<usize>();
25
26 /// Returns the size ratio between [`UBYTES`][Self#constant.UBYTES] and
27 /// [`BYTES`][Self#constant.BYTES].
28 ///
29 /// For example: the ratio will be (1, 1) if both sizes are the same,
30 /// (2, 1) if a pointer is double the byte size, and (1, 2) if a pointer is
31 /// half the byte size.
32 ///
33 /// # Examples
34 /// ```
35 /// use ladata::all::DataSize;
36 ///
37 /// assert_eq![1_usize.pointer_ratio(), (1, 1)];
38 /// assert_eq!["slice".pointer_ratio(), (1, 2)];
39 /// assert_eq![String::new().pointer_ratio(), (1, 3)];
40 ///
41 /// #[cfg(target_pointer_width = "64")]
42 /// assert_eq!['a'.pointer_ratio(), (2,1)]
43 /// ```
44 fn pointer_ratio(&self) -> (usize, usize) {
45 #[inline]
46 fn gcd(m: usize, n: usize) -> usize {
47 if n == 0 {
48 m
49 } else {
50 gcd(n, m % n)
51 }
52 }
53 let g = gcd(Self::UBYTES, Self::BYTES);
54 (Self::UBYTES / g, Self::BYTES / g)
55 }
56
57 /// Returns the size in bytes of this type, in the stack.
58 ///
59 /// Ignores any allocated resources in the heap.
60 fn stack_byte_size(&self) -> usize {
61 size_of_val(self)
62 }
63
64 // /// Returns the size in bytes of this type, in the heap.
65 // fn heap_byte_size(&self) -> usize {
66 // todo![] // TODO
67 // }
68}