moveit/
alloc_support.rs

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
17use core::mem::MaybeUninit;
18use core::pin::Pin;
19
20use alloc::boxed::Box;
21
22use crate::move_ref::MoveRef;
23use crate::move_ref::{AsMove, DerefMove};
24use crate::slot::DroppingSlot;
25
26impl<T> AsMove for Box<T> {
27  type Storage = Box<MaybeUninit<T>>;
28
29  #[inline]
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
41unsafe impl<T> DerefMove for Box<T> {
42  #[inline]
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)]
59mod tests {
60  use crate::move_ref::test::Immovable;
61  use crate::moveit;
62  use crate::new::mov;
63  use crate::Emplace;
64
65  #[test]
66  fn test_mov_box() {
67    let foo = Box::emplace(Immovable::new());
68    moveit!(let _foo = mov(foo));
69  }
70}