bump_scope/
owned_slice.rs1use core::{array, mem};
2
3#[cfg(feature = "alloc")]
4use core::mem::ManuallyDrop;
5
6#[cfg(feature = "alloc")]
7use alloc_crate::{
8 boxed::Box,
9 vec::{self, Vec},
10};
11
12use crate::{BumpAllocatorExt, BumpBox, BumpVec, FixedBumpVec, MutBumpVec, MutBumpVecRev, unsize_bump_box};
13
14mod drain;
15mod extract_if;
16mod into_iter;
17
18pub use drain::Drain;
19pub use extract_if::ExtractIf;
20pub use into_iter::IntoIter;
21
22pub trait OwnedSlice {
34 type Item;
36
37 type Take: TakeOwnedSlice<Item = Self::Item>;
39
40 fn into_take_owned_slice(self) -> Self::Take;
42}
43
44impl<T: TakeOwnedSlice> OwnedSlice for T {
46 type Item = <Self as TakeOwnedSlice>::Item;
47
48 type Take = Self;
49
50 fn into_take_owned_slice(self) -> Self::Take {
51 self
52 }
53}
54
55impl<T, const N: usize> OwnedSlice for [T; N] {
56 type Item = T;
57
58 type Take = array::IntoIter<T, N>;
59
60 fn into_take_owned_slice(self) -> Self::Take {
61 self.into_iter()
62 }
63}
64
65impl<'a, T, const N: usize> OwnedSlice for BumpBox<'a, [T; N]> {
66 type Item = T;
67
68 type Take = BumpBox<'a, [T]>;
69
70 fn into_take_owned_slice(self) -> Self::Take {
71 unsize_bump_box!(self)
72 }
73}
74
75#[cfg(feature = "alloc")]
76impl<T, const N: usize> OwnedSlice for Box<[T; N]> {
77 type Item = T;
78
79 type Take = Box<[T]>;
80
81 fn into_take_owned_slice(self) -> Self::Take {
82 self
83 }
84}
85
86pub unsafe trait TakeOwnedSlice {
138 type Item;
140
141 fn owned_slice_ref(&self) -> &[Self::Item];
143
144 fn take_owned_slice(&mut self);
153}
154
155unsafe impl<T: TakeOwnedSlice + ?Sized> TakeOwnedSlice for &mut T {
156 type Item = T::Item;
157
158 #[inline]
159 fn owned_slice_ref(&self) -> &[Self::Item] {
160 T::owned_slice_ref(self)
161 }
162
163 #[inline]
164 fn take_owned_slice(&mut self) {
165 T::take_owned_slice(self);
166 }
167}
168
169unsafe impl<T, const N: usize> TakeOwnedSlice for array::IntoIter<T, N> {
170 type Item = T;
171
172 #[inline]
173 fn owned_slice_ref(&self) -> &[Self::Item] {
174 self.as_slice()
175 }
176
177 #[inline]
178 fn take_owned_slice(&mut self) {
179 self.for_each(mem::forget);
180 }
181}
182
183unsafe impl<T> TakeOwnedSlice for BumpBox<'_, [T]> {
184 type Item = T;
185
186 #[inline]
187 fn owned_slice_ref(&self) -> &[Self::Item] {
188 self
189 }
190
191 #[inline]
192 fn take_owned_slice(&mut self) {
193 unsafe { self.set_len(0) }
194 }
195}
196
197unsafe impl<T> TakeOwnedSlice for FixedBumpVec<'_, T> {
198 type Item = T;
199
200 #[inline]
201 fn owned_slice_ref(&self) -> &[Self::Item] {
202 self
203 }
204
205 #[inline]
206 fn take_owned_slice(&mut self) {
207 unsafe { self.set_len(0) }
208 }
209}
210
211unsafe impl<T, A: BumpAllocatorExt> TakeOwnedSlice for BumpVec<T, A> {
212 type Item = T;
213
214 #[inline]
215 fn owned_slice_ref(&self) -> &[Self::Item] {
216 self
217 }
218
219 #[inline]
220 fn take_owned_slice(&mut self) {
221 unsafe { self.set_len(0) }
222 }
223}
224
225unsafe impl<T, A> TakeOwnedSlice for MutBumpVec<T, A> {
226 type Item = T;
227
228 #[inline]
229 fn owned_slice_ref(&self) -> &[Self::Item] {
230 self
231 }
232
233 #[inline]
234 fn take_owned_slice(&mut self) {
235 unsafe { self.set_len(0) }
236 }
237}
238
239unsafe impl<T, A> TakeOwnedSlice for MutBumpVecRev<T, A> {
240 type Item = T;
241
242 #[inline]
243 fn owned_slice_ref(&self) -> &[Self::Item] {
244 self
245 }
246
247 #[inline]
248 fn take_owned_slice(&mut self) {
249 unsafe { self.set_len(0) }
250 }
251}
252
253#[cfg(feature = "alloc")]
254unsafe impl<T> TakeOwnedSlice for Box<[T]> {
255 type Item = T;
256
257 #[inline]
258 fn owned_slice_ref(&self) -> &[Self::Item] {
259 self
260 }
261
262 #[inline]
263 fn take_owned_slice(&mut self) {
264 let ptr = Box::into_raw(mem::take(self));
266 let forget_elements_box = unsafe { Box::<[ManuallyDrop<T>]>::from_raw(ptr as *mut [ManuallyDrop<T>]) };
267 drop(forget_elements_box);
268 }
269}
270
271#[cfg(feature = "alloc")]
272unsafe impl<T> TakeOwnedSlice for Vec<T> {
273 type Item = T;
274
275 #[inline]
276 fn owned_slice_ref(&self) -> &[Self::Item] {
277 self
278 }
279
280 #[inline]
281 fn take_owned_slice(&mut self) {
282 unsafe { self.set_len(0) }
283 }
284}
285
286#[cfg(feature = "alloc")]
287unsafe impl<T> TakeOwnedSlice for vec::IntoIter<T> {
288 type Item = T;
289
290 #[inline]
291 fn owned_slice_ref(&self) -> &[Self::Item] {
292 self.as_slice()
293 }
294
295 #[inline]
296 fn take_owned_slice(&mut self) {
297 self.for_each(mem::forget);
298 }
299}
300
301#[cfg(feature = "alloc")]
302unsafe impl<T> TakeOwnedSlice for vec::Drain<'_, T> {
303 type Item = T;
304
305 #[inline]
306 fn owned_slice_ref(&self) -> &[Self::Item] {
307 self.as_slice()
308 }
309
310 #[inline]
311 fn take_owned_slice(&mut self) {
312 self.for_each(mem::forget);
313 }
314}
315
316#[cfg(all(test, feature = "alloc"))]
317mod tests {
318 use crate::tests::Bump;
319
320 use super::*;
321
322 const _: () = {
323 const fn is_dyn_compatible<T: TakeOwnedSlice + ?Sized>() {}
324 is_dyn_compatible::<dyn TakeOwnedSlice<Item = i32>>();
325 is_dyn_compatible::<&mut dyn TakeOwnedSlice<Item = i32>>();
326 };
327
328 macro_rules! assert_implements {
329 ($($ty:ty)*) => {
330 const _: () = {
331 type T = i32;
332 const fn implements<S: OwnedSlice + ?Sized>() {}
333 $(implements::<$ty>();)*
334 };
335 };
336 }
337
338 assert_implements! {
339 &mut dyn TakeOwnedSlice<Item = T>
340
341 [T; 3]
342 BumpBox<[T; 3]>
343
344 BumpBox<[T]>
345 &mut BumpBox<[T]>
346 FixedBumpVec<T>
347 &mut FixedBumpVec<T>
348 BumpVec<T, &Bump>
349 &mut BumpVec<T, &Bump>
350 MutBumpVec<T, &mut Bump>
351 &mut MutBumpVec<T, &mut Bump>
352 MutBumpVecRev<T, &mut Bump>
353 &mut MutBumpVecRev<T, &mut Bump>
354 BumpVec<T, Bump>
355 &mut BumpVec<T, Bump>
356 MutBumpVec<T, Bump>
357 &mut MutBumpVec<T, Bump>
358 MutBumpVecRev<T, Bump>
359 &mut MutBumpVecRev<T, Bump>
360 }
361
362 #[cfg(feature = "alloc")]
363 assert_implements! {
364 Box<[T; 3]>
365
366 Box<[T]>
367 &mut Box<[T]>
368 Vec<T>
369 &mut Vec<T>
370 }
371}