mem_tools/
mem.rs

1/// Define a private namespace for all its items.
2mod private
3{
4  // use crate::own::*;
5
6  ///
7  /// Are two pointers points on the same data.
8  ///
9  /// Does not require arguments to have the same type.
10  #[ allow( unsafe_code ) ]
11  pub fn same_data< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool
12  {
13    extern "C" { fn memcmp( s1 : *const u8, s2 : *const u8, n : usize ) -> i32; }
14
15    let mem1 = core::ptr::from_ref::<T1>(src1).cast::<u8>();
16    let mem2 = core::ptr::from_ref::<T2>(src2).cast::<u8>();
17
18    if !same_size( src1, src2 )
19    {
20      return false;
21    }
22
23    // Safety:
24    // The `unsafe` block is required because we're calling a foreign function (`memcmp`)
25    // and manually managing memory addresses.
26    // `mem1` and `mem2` are obtained from valid references `src1` and `src2` using `core::ptr::from_ref`
27    // and then cast to `*const u8`. This ensures they are valid, non-null, and properly aligned
28    // pointers to the start of the data.
29    // The size `n` is obtained from `core::mem::size_of_val(src1)`, which is the correct
30    // size of the data pointed to by `src1`.
31    // The `same_size` check (which compares `core::mem::size_of_val(src1)` and `core::mem::size_of_val(src2)`)
32    // ensures that both memory regions have the same length. This guarantees that `memcmp`
33    // will not read out of bounds for `src2` when comparing `n` bytes, as both `mem1` and `mem2`
34    // are guaranteed to point to at least `n` bytes of valid memory.
35    unsafe { memcmp( mem1, mem2, core::mem::size_of_val( src1 ) ) == 0 }
36  }
37
38  /* zzz : qqq : implement mem::same_data, comparing data. discuss */
39
40  ///
41  /// Are two pointers are the same, not taking into accoint type.
42  ///
43  /// Unlike `std::ptr::eq()` does not require arguments to have the same type.
44  pub fn same_ptr< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool
45  {
46    let mem1 = core::ptr::from_ref::<T1>(src1).cast::<()>();
47    let mem2 = core::ptr::from_ref::<T2>(src2).cast::<()>();
48    mem1 == mem2
49  }
50
51  ///
52  /// Are two pointers points on data of the same size.
53  pub fn same_size< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool
54  {
55    core::mem::size_of_val( src1 ) == core::mem::size_of_val( src2 )
56  }
57
58  ///
59  /// Are two pointers points on the same region, ie same size and same pointer.
60  ///
61  /// Does not require arguments to have the same type.
62  pub fn same_region< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool
63  {
64    same_ptr( src1, src2 ) && same_size( src1, src2 )
65  }
66
67}
68
69#[ doc( inline ) ]
70#[ allow( unused_imports ) ]
71pub use own::*;
72
73/// Own namespace of the module.
74#[ allow( unused_imports ) ]
75pub mod own
76{
77  use super::*;
78  #[ doc( inline ) ]
79  pub use super::
80  {
81    orphan::*,
82  };
83}
84
85/// Orphan namespace of the module.
86#[ allow( unused_imports ) ]
87pub mod orphan
88{
89  use super::*;
90  #[ doc( inline ) ]
91  pub use super::
92  {
93    exposed::*,
94    private::same_data,
95    private::same_ptr,
96    private::same_size,
97    private::same_region,
98  };
99}
100
101/// Exposed namespace of the module.
102#[ allow( unused_imports ) ]
103pub mod exposed
104{
105  use super::*;
106  // Expose itself.
107  pub use super::super::mem;
108
109  #[ doc( inline ) ]
110  pub use prelude::*;
111}
112
113/// Prelude to use essentials: `use my_module::prelude::*`.
114#[ allow( unused_imports ) ]
115pub mod prelude
116{
117  use super::*;
118}