inplace_box/
impl_new.rs

1use core::marker::Unsize;
2
3use crate::InplaceBox;
4
5impl<T: ?Sized, const SIZE: usize> InplaceBox<T, SIZE> {
6    /// Construct a new object in-place in this object.
7    ///
8    /// The type of the value must be convertible to `dyn T` and its size and
9    /// alignment less than or equal to that of the `InplaceBox` space for
10    /// the object.
11    ///
12    /// Type match, size and alignment are checked statically by the compiler.
13    pub fn new<'a, U: Sized + Unsize<T> + 'a>(value: U) -> Self {
14        ConvertIntoInplaceBox::convert_into_inplace_box(value)
15    }
16}
17
18/// Helper to move the value w/o conversion for `InplaceBox`.
19trait IsInPlaceBox<T: ?Sized, const SIZE: usize> {
20    fn move_out(self) -> InplaceBox<T, SIZE>;
21}
22
23impl<T: ?Sized, const SIZE: usize> IsInPlaceBox<T, SIZE>
24    for InplaceBox<T, SIZE>
25{
26    #[inline]
27    fn move_out(self) -> InplaceBox<T, SIZE> {
28        self
29    }
30}
31
32/// Convert value into `InplaceBox`.
33///
34/// Provides specialized behavior: regular values are placed in-place,
35/// existing `InplaceBox` values are moved without conversion.
36trait ConvertIntoInplaceBox<'a, T, const SIZE: usize>
37where T: ?Sized + 'a
38{
39    fn convert_into_inplace_box(self) -> InplaceBox<T, SIZE>;
40}
41
42impl<'a, T, U, const SIZE: usize> ConvertIntoInplaceBox<'a, T, SIZE> for U
43where
44    T: ?Sized + 'a,
45    U: Sized + Unsize<T> + 'a,
46{
47    #[inline]
48    default fn convert_into_inplace_box(self) -> InplaceBox<T, SIZE> {
49        InplaceBox::new_impl(self)
50    }
51}
52
53impl<'a, T, U, const SIZE: usize> ConvertIntoInplaceBox<'a, T, SIZE> for U
54where
55    T: ?Sized + 'a,
56    U: Sized + Unsize<T> + IsInPlaceBox<T, SIZE> + 'a,
57{
58    #[inline]
59    fn convert_into_inplace_box(self) -> InplaceBox<T, SIZE> {
60        self.move_out()
61    }
62}