1#[cfg(all(feature = "alloc", not(feature = "std")))]
4use alloc::{boxed::Box, sync::Arc};
5#[cfg(feature = "alloc")]
6use core::alloc::AllocError;
7use core::{mem::MaybeUninit, pin::Pin};
8#[cfg(feature = "std")]
9use std::sync::Arc;
10
11#[cfg(not(feature = "alloc"))]
12type AllocError = core::convert::Infallible;
13
14use crate::{
15 init_from_closure, pin_init_from_closure, InPlaceWrite, Init, PinInit, ZeroableOption,
16};
17
18pub extern crate alloc;
19
20unsafe impl<T: ?Sized> ZeroableOption for Box<T> {}
25
26pub trait InPlaceInit<T>: Sized {
28 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
33 where
34 E: From<AllocError>;
35
36 fn pin_init(init: impl PinInit<T>) -> Result<Pin<Self>, AllocError> {
41 let init = unsafe {
43 pin_init_from_closure(|slot| match init.__pinned_init(slot) {
44 Ok(()) => Ok(()),
45 Err(i) => match i {},
46 })
47 };
48 Self::try_pin_init(init)
49 }
50
51 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
53 where
54 E: From<AllocError>;
55
56 fn init(init: impl Init<T>) -> Result<Self, AllocError> {
58 let init = unsafe {
60 init_from_closure(|slot| match init.__init(slot) {
61 Ok(()) => Ok(()),
62 Err(i) => match i {},
63 })
64 };
65 Self::try_init(init)
66 }
67}
68
69#[cfg(feature = "alloc")]
70macro_rules! try_new_uninit {
71 ($type:ident) => {
72 $type::try_new_uninit()?
73 };
74}
75#[cfg(all(feature = "std", not(feature = "alloc")))]
76macro_rules! try_new_uninit {
77 ($type:ident) => {
78 $type::new_uninit()
79 };
80}
81
82impl<T> InPlaceInit<T> for Box<T> {
83 #[inline]
84 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
85 where
86 E: From<AllocError>,
87 {
88 try_new_uninit!(Box).write_pin_init(init)
89 }
90
91 #[inline]
92 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
93 where
94 E: From<AllocError>,
95 {
96 try_new_uninit!(Box).write_init(init)
97 }
98}
99
100impl<T> InPlaceInit<T> for Arc<T> {
101 #[inline]
102 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
103 where
104 E: From<AllocError>,
105 {
106 let mut this = try_new_uninit!(Arc);
107 let Some(slot) = Arc::get_mut(&mut this) else {
108 unsafe { core::hint::unreachable_unchecked() }
110 };
111 let slot = slot.as_mut_ptr();
112 unsafe { init.__pinned_init(slot)? };
115 Ok(unsafe { Pin::new_unchecked(this.assume_init()) })
117 }
118
119 #[inline]
120 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
121 where
122 E: From<AllocError>,
123 {
124 let mut this = try_new_uninit!(Arc);
125 let Some(slot) = Arc::get_mut(&mut this) else {
126 unsafe { core::hint::unreachable_unchecked() }
128 };
129 let slot = slot.as_mut_ptr();
130 unsafe { init.__init(slot)? };
133 Ok(unsafe { this.assume_init() })
135 }
136}
137
138impl<T> InPlaceWrite<T> for Box<MaybeUninit<T>> {
139 type Initialized = Box<T>;
140
141 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
142 let slot = self.as_mut_ptr();
143 unsafe { init.__init(slot)? };
146 Ok(unsafe { self.assume_init() })
148 }
149
150 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
151 let slot = self.as_mut_ptr();
152 unsafe { init.__pinned_init(slot)? };
155 Ok(unsafe { self.assume_init() }.into())
157 }
158}