5
5
use super :: { AllocError , Flags } ;
6
6
use alloc:: boxed:: Box ;
7
7
use core:: mem:: MaybeUninit ;
8
+ use core:: ptr;
8
9
9
10
/// Extensions to [`Box`].
10
11
pub trait BoxExt < T > : Sized {
@@ -17,6 +18,22 @@ pub trait BoxExt<T>: Sized {
17
18
///
18
19
/// The allocation may fail, in which case an error is returned.
19
20
fn new_uninit ( flags : Flags ) -> Result < Box < MaybeUninit < T > > , AllocError > ;
21
+
22
+ /// Drops the contents, but keeps the allocation.
23
+ ///
24
+ /// # Examples
25
+ ///
26
+ /// ```
27
+ /// use kernel::alloc::{flags, box_ext::BoxExt};
28
+ ///
29
+ /// let value = Box::new([0; 32], flags::GFP_KERNEL)?;
30
+ /// let value = value.drop_contents();
31
+ /// // Now we can re-use `value`:
32
+ /// Box::write(value, [1; 32]);
33
+ ///
34
+ /// # Ok::<(), Error>(())
35
+ /// ```
36
+ fn drop_contents ( self ) -> Box < MaybeUninit < T > > ;
20
37
}
21
38
22
39
impl < T > BoxExt < T > for Box < T > {
@@ -53,4 +70,12 @@ impl<T> BoxExt<T> for Box<T> {
53
70
// zero-sized types, we use `NonNull::dangling`.
54
71
Ok ( unsafe { Box :: from_raw ( ptr) } )
55
72
}
73
+
74
+ fn drop_contents ( self ) -> Box < MaybeUninit < T > > {
75
+ let ptr = Box :: into_raw ( self ) ;
76
+ // SAFETY: `ptr` is valid, because it came from `Box::into_raw`.
77
+ unsafe { ptr:: drop_in_place ( ptr) } ;
78
+ // SAFETY: `ptr` is valid, because it came from `Box::into_raw`.
79
+ unsafe { Box :: from_raw ( ptr. cast ( ) ) }
80
+ }
56
81
}
0 commit comments