44
55use  super :: { AllocError ,  Flags } ; 
66use  alloc:: boxed:: Box ; 
7- use  core:: mem:: MaybeUninit ; 
7+ use  core:: { mem:: MaybeUninit ,  ptr ,  result :: Result } ; 
88
99/// Extensions to [`Box`]. 
1010pub  trait  BoxExt < T > :  Sized  { 
@@ -17,6 +17,22 @@ pub trait BoxExt<T>: Sized {
1717     /// 
1818     /// The allocation may fail, in which case an error is returned. 
1919     fn  new_uninit ( flags :  Flags )  -> Result < Box < MaybeUninit < T > > ,  AllocError > ; 
20+ 
21+     /// Drops the contents, but keeps the allocation. 
22+      /// 
23+      /// # Examples 
24+      /// 
25+      /// ``` 
26+      /// use kernel::alloc::{flags, box_ext::BoxExt}; 
27+      /// let value = Box::new([0; 32], flags::GFP_KERNEL)?; 
28+      /// assert_eq!(*value, [0; 32]); 
29+      /// let value = Box::drop_contents(value); 
30+      /// // Now we can re-use `value`: 
31+      /// let value = Box::write(value, [1; 32]); 
32+      /// assert_eq!(*value, [1; 32]); 
33+      /// # Ok::<(), Error>(()) 
34+      /// ``` 
35+      fn  drop_contents ( this :  Self )  -> Box < MaybeUninit < T > > ; 
2036} 
2137
2238impl < T >  BoxExt < T >  for  Box < T >  { 
@@ -53,4 +69,17 @@ impl<T> BoxExt<T> for Box<T> {
5369        // zero-sized types, we use `NonNull::dangling`. 
5470        Ok ( unsafe  {  Box :: from_raw ( ptr)  } ) 
5571    } 
72+ 
73+     fn  drop_contents ( this :  Self )  -> Box < MaybeUninit < T > >  { 
74+         let  ptr = Box :: into_raw ( this) ; 
75+         // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 
76+         unsafe  {  ptr:: drop_in_place ( ptr)  } ; 
77+ 
78+         // CAST: `MaybeUninit<T>` is a transparent wrapper of `T`. 
79+         let  ptr = ptr. cast :: < MaybeUninit < T > > ( ) ; 
80+ 
81+         // SAFETY: `ptr` is valid for writes, because it came from `Box::into_raw` and it is valid for 
82+         // reads, since the pointer came from `Box::into_raw` and the type is `MaybeUninit<T>`. 
83+         unsafe  {  Box :: from_raw ( ptr)  } 
84+     } 
5685} 
0 commit comments