1 // Copyright 2021 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Support for the `alloc` crate, when available. 16 17 use core::mem::MaybeUninit; 18 use core::pin::Pin; 19 20 use alloc::boxed::Box; 21 22 use crate::move_ref::MoveRef; 23 use crate::move_ref::{AsMove, DerefMove}; 24 use crate::slot::DroppingSlot; 25 26 impl<T> AsMove for Box<T> { 27 type Storage = Box<MaybeUninit<T>>; 28 29 #[inline] as_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> Pin<MoveRef<'frame, Self::Target>> where Self: 'frame,30 fn as_move<'frame>( 31 self, 32 storage: DroppingSlot<'frame, Self::Storage>, 33 ) -> Pin<MoveRef<'frame, Self::Target>> 34 where 35 Self: 'frame, 36 { 37 MoveRef::into_pin(self.deref_move(storage)) 38 } 39 } 40 41 unsafe impl<T> DerefMove for Box<T> { 42 #[inline] deref_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> MoveRef<'frame, Self::Target> where Self: 'frame,43 fn deref_move<'frame>( 44 self, 45 storage: DroppingSlot<'frame, Self::Storage>, 46 ) -> MoveRef<'frame, Self::Target> 47 where 48 Self: 'frame, 49 { 50 let cast = 51 unsafe { Box::from_raw(Box::into_raw(self).cast::<MaybeUninit<T>>()) }; 52 53 let (storage, drop_flag) = storage.put(cast); 54 unsafe { MoveRef::new_unchecked(storage.assume_init_mut(), drop_flag) } 55 } 56 } 57 58 #[cfg(test)] 59 mod tests { 60 use crate::move_ref::test::Immovable; 61 use crate::moveit; 62 use crate::new::mov; 63 use crate::Emplace; 64 65 #[test] test_mov_box()66 fn test_mov_box() { 67 let foo = Box::emplace(Immovable::new()); 68 moveit!(let _foo = mov(foo)); 69 } 70 } 71