devela/sys/mem/size/
byte.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// devela::sys::mem::size::byte
//
//! Functionality related to byte sizes.
//

use crate::Ptr;

impl<T> ByteSized for T {}

/// Type size information in bytes.
///
/// This trait is automatically implemented for every `Sized` type.
// (this allows to have associated constants depending on Self)
pub trait ByteSized: Sized {
    /// The alignment of this type in bytes.
    const BYTE_ALIGN: usize = align_of::<Self>();
    /// The size of this type in bytes.
    const BYTE_SIZE: usize = size_of::<Self>();

    /// Returns the alignment of this type in bytes.
    fn byte_align(&self) -> usize {
        align_of_val(self)
    }

    /// Returns the size of this type in bytes.
    ///
    /// Ignores any allocated resources in the heap.
    fn byte_size(&self) -> usize {
        size_of_val(self)
    }

    /// Returns the size ratio between [`Ptr::BYTES`]
    /// and [`BYTE_SIZE`][Self#associatedconstant.BYTE_SIZE].
    ///
    /// For example: the ratio will be (1, 1) if both sizes are the same,
    /// (2, 1) if a pointer is double the byte size, and (1, 2) if a pointer is
    /// half the byte size.
    ///
    /// # Example
    /// ```
    /// use devela::ByteSized;
    ///
    /// assert_eq![().ptr_size_ratio(), [1, 0]];
    /// assert_eq![1_usize.ptr_size_ratio(), [1, 1]];
    /// assert_eq!["slice".ptr_size_ratio(), [1, 2]];
    /// assert_eq![String::from("hello").ptr_size_ratio(), [1, 3]];
    ///
    /// #[cfg(target_pointer_width = "64")]
    /// {
    ///     assert_eq![0_u8.ptr_size_ratio(), [8, 1]];
    ///     assert_eq![0_u16.ptr_size_ratio(), [4, 1]];
    ///     assert_eq![0_u32.ptr_size_ratio(), [2, 1]];
    ///     assert_eq![0_u64.ptr_size_ratio(), [1, 1]];
    ///     assert_eq![0_u128.ptr_size_ratio(), [1, 2]];
    ///     assert_eq!['c'.ptr_size_ratio(), [2, 1]];
    ///     assert_eq!["slice".ptr_size_ratio(), [1, 2]];
    /// }
    /// ```
    ///
    /// For the `const` version see [`Ptr::size_ratio`].
    fn ptr_size_ratio(&self) -> [usize; 2] {
        Ptr::size_ratio(Self::BYTE_SIZE)
    }
}

/// Returns the rounded up size in bytes from a size in bits.
///
/// This is equivalent to `(bit_size + 7) / 8` but handles potential overflow.
#[must_use]
pub const fn bytes_from_bits(bit_size: usize) -> usize {
    if let Some(t) = bit_size.checked_add(8 - 1) {
        t / 8
    } else {
        bytes_from_bits_cold()
    }
}
#[cold] #[rustfmt::skip]
const fn bytes_from_bits_cold() -> usize { usize::MAX / 8 }