size_of/support/
arcstr.rs1#![cfg(feature = "arcstr")]
2
3use crate::{Context, SizeOf};
4use arcstr::{ArcStr, Substr};
5use core::mem::size_of;
6
7#[repr(C, align(8))]
9struct FakeThinInner {
10 len_flags: usize,
11 strong: usize,
12 data: [u8; 0],
13}
14
15impl SizeOf for ArcStr {
16 fn size_of_children(&self, context: &mut Context) {
17 if context.insert_ptr(self.as_ptr()) {
19 let bytes = size_of::<FakeThinInner>() + self.len();
20 context.add(bytes).add_shared(bytes);
21
22 if !ArcStr::is_static(self) {
24 context.add_distinct_allocation();
25 }
26 }
27 }
28}
29
30impl SizeOf for Substr {
31 #[inline]
32 fn size_of_children(&self, context: &mut Context) {
33 self.parent().size_of_children(context);
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::FakeThinInner;
40 use crate::{SizeOf, TotalSize};
41 use arcstr::{ArcStr, Substr};
42 use core::mem::size_of;
43
44 #[test]
45 fn arcstr_smoke() {
46 let empty = ArcStr::new();
47 assert_eq!(
48 empty.size_of(),
49 TotalSize::new(
50 size_of::<ArcStr>() + size_of::<FakeThinInner>(),
51 0,
52 size_of::<FakeThinInner>(),
53 0,
54 ),
55 );
56
57 let shared = size_of::<FakeThinInner>() + 4;
58 let total = size_of::<ArcStr>() + shared;
59
60 let static_string = arcstr::literal!("whee");
61 assert_eq!(static_string.size_of(), TotalSize::new(total, 0, shared, 0));
62
63 let allocated_string = ArcStr::from("whee");
64 assert_eq!(
65 allocated_string.size_of(),
66 TotalSize::new(total, 0, shared, 1),
67 );
68 }
69
70 #[test]
71 fn shared_arcstr() {
72 let string1 = ArcStr::from("whee");
73 let string2 = string1.clone();
74 let string3 = string1.clone();
75 let string4 = string1.clone();
76
77 let size =
78 crate::size_of_values([&string1 as _, &string2 as _, &string3 as _, &string4 as _]);
79
80 let shared = size_of::<FakeThinInner>() + 4;
81 let total = size_of::<ArcStr>() * 4 + shared;
82 assert_eq!(size, TotalSize::new(total, 0, shared, 1));
83 }
84
85 #[test]
86 fn substr_smoke() {
87 let empty = Substr::new();
88 assert_eq!(
89 empty.size_of(),
90 TotalSize::new(
91 size_of::<Substr>() + size_of::<FakeThinInner>(),
92 0,
93 size_of::<FakeThinInner>(),
94 0,
95 ),
96 );
97
98 let shared = size_of::<FakeThinInner>() + 4;
99 let total = size_of::<Substr>() + shared;
100
101 let static_substr = Substr::full(arcstr::literal!("whee"));
102 assert_eq!(static_substr.size_of(), TotalSize::new(total, 0, shared, 0));
103
104 let allocated_substr = Substr::full(ArcStr::from("whee"));
105 assert_eq!(
106 allocated_substr.size_of(),
107 TotalSize::new(total, 0, shared, 1),
108 );
109
110 let sliced_allocated_substr = ArcStr::from("whee").substr(..2);
111 assert_eq!(
112 sliced_allocated_substr.size_of(),
113 TotalSize::new(total, 0, shared, 1),
114 );
115 }
116}