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