allocative/impls/std/
unsorted.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under both the MIT license found in the
5 * LICENSE-MIT file in the root directory of this source tree and the Apache
6 * License, Version 2.0 found in the LICENSE-APACHE file in the root directory
7 * of this source tree.
8 */
9
10use std::collections::VecDeque;
11use std::convert::Infallible;
12use std::ffi::OsStr;
13use std::marker::PhantomData;
14use std::mem;
15use std::num::NonZeroI16;
16use std::num::NonZeroI32;
17use std::num::NonZeroI64;
18use std::num::NonZeroI8;
19use std::num::NonZeroIsize;
20use std::num::NonZeroU16;
21use std::num::NonZeroU32;
22use std::num::NonZeroU64;
23use std::num::NonZeroU8;
24use std::num::NonZeroUsize;
25use std::path::PathBuf;
26
27use crate::allocative_trait::Allocative;
28use crate::impls::common::DATA_NAME;
29use crate::impls::common::PTR_NAME;
30use crate::impls::common::UNUSED_CAPACITY_NAME;
31use crate::key::Key;
32use crate::visitor::Visitor;
33
34impl<T: Allocative + ?Sized> Allocative for &'static T {
35    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
36        let _ = visitor;
37    }
38}
39
40impl Allocative for str {
41    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
42        visitor.visit_simple(Key::new("str"), self.len());
43    }
44}
45
46impl Allocative for OsStr {
47    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
48        visitor.visit_simple(Key::new("OsStr"), self.len());
49    }
50}
51
52impl<T: Allocative + ?Sized> Allocative for Box<T> {
53    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
54        let mut visitor = visitor.enter_self_sized::<Self>();
55        {
56            let mut visitor = visitor.enter_unique(PTR_NAME, mem::size_of::<*const T>());
57            (**self).visit(&mut visitor);
58        }
59        visitor.exit();
60    }
61}
62
63impl<T: Allocative, E: Allocative> Allocative for Result<T, E> {
64    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
65        let mut visitor = visitor.enter_self_sized::<Self>();
66        match self {
67            Ok(v) => visitor.visit_field(Key::new("Ok"), v),
68            Err(e) => visitor.visit_field(Key::new("Err"), e),
69        }
70    }
71}
72
73impl<T: Allocative> Allocative for Option<T> {
74    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
75        let mut visitor = visitor.enter_self_sized::<Self>();
76        if let Some(value) = self {
77            visitor.visit_field(Key::new("Some"), value);
78        }
79    }
80}
81
82impl<T: Allocative> Allocative for Vec<T> {
83    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
84        let mut visitor = visitor.enter_self_sized::<Self>();
85        if self.capacity() != 0 && mem::size_of::<T>() != 0 {
86            let mut visitor = visitor.enter_unique(PTR_NAME, mem::size_of::<*const T>());
87            visitor.visit_slice(self.as_slice());
88            visitor.visit_simple(
89                UNUSED_CAPACITY_NAME,
90                (self.capacity() - self.len()) * mem::size_of::<T>(),
91            );
92        }
93        visitor.exit();
94    }
95}
96
97impl<T: Allocative> Allocative for VecDeque<T> {
98    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
99        let mut visitor = visitor.enter_self_sized::<Self>();
100        if self.capacity() != 0 && mem::size_of::<T>() != 0 {
101            let mut visitor = visitor.enter_unique(PTR_NAME, mem::size_of::<*const T>());
102            visitor.visit_slice(self.as_slices().0);
103            visitor.visit_slice(self.as_slices().1);
104            visitor.visit_simple(
105                UNUSED_CAPACITY_NAME,
106                (self.capacity() - self.len()) * mem::size_of::<T>(),
107            );
108        }
109        visitor.exit();
110    }
111}
112
113impl Allocative for String {
114    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
115        let mut visitor = visitor.enter_self_sized::<Self>();
116        {
117            let mut visitor = visitor.enter_unique(PTR_NAME, mem::size_of::<*const u8>());
118            visitor.visit_vec_like_body(self.as_bytes(), self.capacity());
119            visitor.exit();
120        }
121        visitor.exit();
122    }
123}
124
125impl Allocative for PathBuf {
126    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
127        let mut visitor = visitor.enter_self_sized::<Self>();
128        if self.capacity() != 0 {
129            let mut visitor = visitor.enter_unique(PTR_NAME, mem::size_of::<*const u8>());
130            visitor.visit_simple(Key::new("path"), self.as_os_str().len());
131            visitor.visit_simple(
132                UNUSED_CAPACITY_NAME,
133                self.capacity() - self.as_os_str().len(),
134            );
135        }
136        visitor.exit();
137    }
138}
139
140impl Allocative for NonZeroU64 {
141    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
142        visitor.visit_simple_sized::<Self>();
143    }
144}
145
146impl Allocative for NonZeroU32 {
147    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
148        visitor.visit_simple_sized::<Self>();
149    }
150}
151
152impl Allocative for NonZeroU16 {
153    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
154        visitor.visit_simple_sized::<Self>();
155    }
156}
157
158impl Allocative for NonZeroU8 {
159    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
160        visitor.visit_simple_sized::<Self>();
161    }
162}
163
164impl Allocative for NonZeroI64 {
165    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
166        visitor.visit_simple_sized::<Self>();
167    }
168}
169
170impl Allocative for NonZeroI32 {
171    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
172        visitor.visit_simple_sized::<Self>();
173    }
174}
175
176impl Allocative for NonZeroI16 {
177    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
178        visitor.visit_simple_sized::<Self>();
179    }
180}
181
182impl Allocative for NonZeroI8 {
183    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
184        visitor.visit_simple_sized::<Self>();
185    }
186}
187
188impl Allocative for NonZeroUsize {
189    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
190        visitor.visit_simple_sized::<Self>();
191    }
192}
193
194impl Allocative for NonZeroIsize {
195    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
196        visitor.visit_simple_sized::<Self>();
197    }
198}
199
200impl<T: ?Sized> Allocative for PhantomData<T> {
201    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
202        let _ = visitor;
203    }
204}
205
206impl Allocative for Infallible {
207    fn visit<'a, 'b: 'a>(&self, _visitor: &'a mut Visitor<'b>) {
208        match *self {}
209    }
210}
211
212#[cfg(rust_nightly)]
213impl Allocative for ! {
214    fn visit<'a, 'b: 'a>(&self, _visitor: &'a mut Visitor<'b>) {
215        match *self {}
216    }
217}
218
219impl<T: Allocative> Allocative for [T] {
220    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
221        let mut visitor = visitor.enter(Key::for_type_name::<T>(), mem::size_of_val::<[T]>(self));
222        for item in self {
223            // TODO(nga): faster for primitive.
224            visitor.visit_field(DATA_NAME, item);
225        }
226        visitor.exit();
227    }
228}
229
230impl<T: Allocative, const N: usize> Allocative for [T; N] {
231    fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
232        self.as_slice().visit(visitor);
233    }
234}