Skip to main content

wiwi_memory_usage/impls/
pointer.rs

1use crate::macros::impl_memory_usage_static;
2use core::ptr::NonNull;
3
4// we cannot trust that the pointer is safe to dereference, so we can only take
5// size of the pointer itself. Abstractions built on top of pointers probably
6// shouldn't rely on these implementations for data and can calculate their own
7// with more accurate info on the contents the pointers point to
8
9impl_memory_usage_static! {
10	{ T: ?Sized }
11	*const T
12	=> size_of::<*const T>();
13}
14
15impl_memory_usage_static! {
16	{ T: ?Sized }
17	*mut T
18	=> size_of::<*mut T>();
19}
20
21impl_memory_usage_static! {
22	{ T: ?Sized }
23	NonNull<T>
24	=> size_of::<NonNull<T>>();
25}
26
27#[cfg(test)]
28mod tests {
29	use super::*;
30	use crate::{
31		MemoryUsage as _,
32		MemoryUsageStatic as _
33	};
34
35	trait Trait {}
36	impl Trait for () {}
37
38	#[test]
39	fn const_ptr_usage() {
40		let expected = cfg_select! {
41			target_pointer_width = "16" => { 2 }
42			target_pointer_width = "32" => { 4 }
43			target_pointer_width = "64" => { 8 }
44		};
45
46		let val = ();
47		let ptr = &raw const val;
48
49		assert_eq!(ptr.memory_usage(), expected);
50		assert_eq!(<*const ()>::MEMORY_USAGE, expected);
51
52		let val = [1, 2, 3, 4, 5];
53		let ptr = &raw const val;
54
55		assert_eq!(ptr.memory_usage(), expected);
56		assert_eq!(<*const [i32; 5]>::MEMORY_USAGE, expected);
57	}
58
59	#[test]
60	fn const_ptr_dst_usage() {
61		let expected = cfg_select! {
62			target_pointer_width = "16" => { 4 }
63			target_pointer_width = "32" => { 8 }
64			target_pointer_width = "64" => { 16 }
65		};
66
67		let val = &[1, 2, 3, 4, 5] as &[_];
68		let ptr = &raw const *val;
69
70		assert_eq!(ptr.memory_usage(), expected);
71		assert_eq!(<*const [i32]>::MEMORY_USAGE, expected);
72
73		let val = &() as &dyn Trait;
74		let ptr = &raw const *val;
75
76		assert_eq!(ptr.memory_usage(), expected);
77		assert_eq!(<*const dyn Trait>::MEMORY_USAGE, expected);
78	}
79
80	#[test]
81	fn mut_ptr_usage() {
82		let expected = cfg_select! {
83			target_pointer_width = "16" => { 2 }
84			target_pointer_width = "32" => { 4 }
85			target_pointer_width = "64" => { 8 }
86		};
87
88		let mut val = ();
89		let ptr = &raw mut val;
90
91		assert_eq!(ptr.memory_usage(), expected);
92		assert_eq!(<*mut ()>::MEMORY_USAGE, expected);
93
94		let mut val = [1, 2, 3, 4, 5];
95		let ptr = &raw mut val;
96
97		assert_eq!(ptr.memory_usage(), expected);
98		assert_eq!(<*mut [i32; 5]>::MEMORY_USAGE, expected);
99	}
100
101	#[test]
102	fn mut_ptr_dst_usage() {
103		let expected = cfg_select! {
104			target_pointer_width = "16" => { 4 }
105			target_pointer_width = "32" => { 8 }
106			target_pointer_width = "64" => { 16 }
107		};
108
109		let val = &mut [1, 2, 3, 4, 5] as &mut [_];
110		let ptr = &raw mut *val;
111
112		assert_eq!(ptr.memory_usage(), expected);
113		assert_eq!(<*mut [i32]>::MEMORY_USAGE, expected);
114
115		let val = &mut () as &mut dyn Trait;
116		let ptr = &raw mut *val;
117
118		assert_eq!(ptr.memory_usage(), expected);
119		assert_eq!(<*mut dyn Trait>::MEMORY_USAGE, expected);
120	}
121
122	#[test]
123	fn non_null_ptr_usage() {
124		let expected = <*const ()>::MEMORY_USAGE;
125
126		let val = ();
127		let ptr = NonNull::from_ref(&val);
128
129		assert_eq!(ptr.memory_usage(), expected);
130		assert_eq!(<NonNull<()>>::MEMORY_USAGE, expected);
131
132		let mut val = [1, 2, 3, 4, 5];
133		let ptr = NonNull::from_mut(&mut val);
134
135		assert_eq!(ptr.memory_usage(), expected);
136		assert_eq!(<NonNull<[i32; 5]>>::MEMORY_USAGE, expected);
137	}
138
139	#[test]
140	fn non_null_ptr_dst_usage() {
141		let expected = <*const [u8]>::MEMORY_USAGE;
142
143		let val = &[1, 2, 3, 4, 5] as &[_];
144		let ptr = NonNull::from_ref(val);
145
146		assert_eq!(ptr.memory_usage(), expected);
147		assert_eq!(<NonNull<[i32]>>::MEMORY_USAGE, expected);
148
149		let val = &mut () as &mut dyn Trait;
150		let ptr = NonNull::from_mut(val);
151
152		assert_eq!(ptr.memory_usage(), expected);
153		assert_eq!(<NonNull<dyn Trait>>::MEMORY_USAGE, expected);
154	}
155}