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	{ T: ?Sized }
12	*const T
13	=> size_of::<*const T>();
14}
15
16impl_memory_usage_static! {
17	{ T: ?Sized }
18	{ T: ?Sized }
19	*mut T
20	=> size_of::<*mut T>();
21}
22
23impl_memory_usage_static! {
24	{ T: ?Sized }
25	{ T: ?Sized }
26	NonNull<T>
27	=> size_of::<NonNull<T>>();
28}
29
30#[cfg(test)]
31mod tests {
32	use super::*;
33	use crate::{
34		MemoryUsage as _,
35		MemoryUsageConst as _,
36		MemoryUsageStatic as _
37	};
38
39	trait Trait {}
40	impl Trait for () {}
41
42	#[test]
43	fn const_ptr_usage() {
44		let expected = cfg_select! {
45			target_pointer_width = "16" => { 2 }
46			target_pointer_width = "32" => { 4 }
47			target_pointer_width = "64" => { 8 }
48		};
49
50		let val = ();
51		let ptr = &raw const val;
52
53		assert_eq!(ptr.memory_usage(), expected);
54		assert_eq!(ptr.memory_usage_const(), expected);
55		assert_eq!(<*const ()>::MEMORY_USAGE, expected);
56
57		let val = [1, 2, 3, 4, 5];
58		let ptr = &raw const val;
59
60		assert_eq!(ptr.memory_usage(), expected);
61		assert_eq!(ptr.memory_usage_const(), expected);
62		assert_eq!(<*const [i32; 5]>::MEMORY_USAGE, expected);
63	}
64
65	#[test]
66	fn const_ptr_dst_usage() {
67		let expected = cfg_select! {
68			target_pointer_width = "16" => { 4 }
69			target_pointer_width = "32" => { 8 }
70			target_pointer_width = "64" => { 16 }
71		};
72
73		let val = &[1, 2, 3, 4, 5] as &[_];
74		let ptr = &raw const *val;
75
76		assert_eq!(ptr.memory_usage(), expected);
77		assert_eq!(ptr.memory_usage_const(), expected);
78		assert_eq!(<*const [i32]>::MEMORY_USAGE, expected);
79
80		let val = &() as &dyn Trait;
81		let ptr = &raw const *val;
82
83		assert_eq!(ptr.memory_usage(), expected);
84		assert_eq!(ptr.memory_usage_const(), expected);
85		assert_eq!(<*const dyn Trait>::MEMORY_USAGE, expected);
86	}
87
88	#[test]
89	fn mut_ptr_usage() {
90		let expected = cfg_select! {
91			target_pointer_width = "16" => { 2 }
92			target_pointer_width = "32" => { 4 }
93			target_pointer_width = "64" => { 8 }
94		};
95
96		let mut val = ();
97		let ptr = &raw mut val;
98
99		assert_eq!(ptr.memory_usage(), expected);
100		assert_eq!(ptr.memory_usage_const(), expected);
101		assert_eq!(<*mut ()>::MEMORY_USAGE, expected);
102
103		let mut val = [1, 2, 3, 4, 5];
104		let ptr = &raw mut val;
105
106		assert_eq!(ptr.memory_usage(), expected);
107		assert_eq!(ptr.memory_usage_const(), expected);
108		assert_eq!(<*mut [i32; 5]>::MEMORY_USAGE, expected);
109	}
110
111	#[test]
112	fn mut_ptr_dst_usage() {
113		let expected = cfg_select! {
114			target_pointer_width = "16" => { 4 }
115			target_pointer_width = "32" => { 8 }
116			target_pointer_width = "64" => { 16 }
117		};
118
119		let val = &mut [1, 2, 3, 4, 5] as &mut [_];
120		let ptr = &raw mut *val;
121
122		assert_eq!(ptr.memory_usage(), expected);
123		assert_eq!(ptr.memory_usage_const(), expected);
124		assert_eq!(<*mut [i32]>::MEMORY_USAGE, expected);
125
126		let val = &mut () as &mut dyn Trait;
127		let ptr = &raw mut *val;
128
129		assert_eq!(ptr.memory_usage(), expected);
130		assert_eq!(ptr.memory_usage_const(), expected);
131		assert_eq!(<*mut dyn Trait>::MEMORY_USAGE, expected);
132	}
133
134	#[test]
135	fn non_null_ptr_usage() {
136		let expected = <*const ()>::MEMORY_USAGE;
137
138		let val = ();
139		let ptr = NonNull::from_ref(&val);
140
141		assert_eq!(ptr.memory_usage(), expected);
142		assert_eq!(ptr.memory_usage_const(), expected);
143		assert_eq!(<NonNull<()>>::MEMORY_USAGE, expected);
144
145		let mut val = [1, 2, 3, 4, 5];
146		let ptr = NonNull::from_mut(&mut val);
147
148		assert_eq!(ptr.memory_usage(), expected);
149		assert_eq!(ptr.memory_usage_const(), expected);
150		assert_eq!(<NonNull<[i32; 5]>>::MEMORY_USAGE, expected);
151	}
152
153	#[test]
154	fn non_null_ptr_dst_usage() {
155		let expected = <*const [u8]>::MEMORY_USAGE;
156
157		let val = &[1, 2, 3, 4, 5] as &[_];
158		let ptr = NonNull::from_ref(val);
159
160		assert_eq!(ptr.memory_usage(), expected);
161		assert_eq!(ptr.memory_usage_const(), expected);
162		assert_eq!(<NonNull<[i32]>>::MEMORY_USAGE, expected);
163
164		let val = &mut () as &mut dyn Trait;
165		let ptr = NonNull::from_mut(val);
166
167		assert_eq!(ptr.memory_usage(), expected);
168		assert_eq!(ptr.memory_usage_const(), expected);
169		assert_eq!(<NonNull<dyn Trait>>::MEMORY_USAGE, expected);
170	}
171}