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 //! In-place constructors.
16 //!
17 //! This module provides a range of helpers such as [`new::by()`] and
18 //! [`new::from()`] for creating constructors. It is preferred style to
19 //! `use moveit::new;` and refer to these helpers with a `new::` prefix.
20 
21 use core::convert::Infallible;
22 use core::mem::MaybeUninit;
23 use core::ops::Deref;
24 use core::pin::Pin;
25 
26 #[cfg(doc)]
27 use {crate::new, core::ops::DerefMut};
28 
29 use alloc::{boxed::Box, rc::Rc, sync::Arc};
30 
31 mod copy_new;
32 mod factories;
33 mod move_new;
34 
35 mod impls;
36 
37 pub use copy_new::*;
38 pub use factories::*;
39 pub use move_new::*;
40 
41 /// An in-place constructor for a particular type.
42 ///
43 /// # Safety
44 ///
45 /// [`New::new()`] must leave its destination argument in a valid, initialized
46 /// state.
47 #[must_use = "`New`s do nothing until emplaced into storage"]
48 pub unsafe trait New: Sized {
49   /// The type to construct.
50   type Output;
51   /// Construct a new value using the arguments stored in `self`.
52   ///
53   /// # Safety
54   ///
55   /// `this` must be freshly-created memory; this function must not
56   /// be used to mutate a previously-pinned pointer that has had `self: Pin`
57   /// functions called on it.
new(self, this: Pin<&mut MaybeUninit<Self::Output>>)58   unsafe fn new(self, this: Pin<&mut MaybeUninit<Self::Output>>);
59 
60   /// Adds a post-construction operation.
61   ///
62   /// This function wraps `self` in an another [`New`] type which will call
63   /// `post` once the main emplacement operation is complete. This is most
64   /// useful for the case where creation of the value itself does not depend
65   /// on the final address, but where some address-sensitive setup may want
66   /// to occur; this can help minimize the scope (or even need for) `unsafe`.
67   ///
68   /// This function is best combined with other helpers:
69   ///
70   /// ```
71   /// # use moveit::{new, moveit, New};
72   /// # use std::pin::Pin;
73   /// pub struct MyType { /* ... */ }
74   ///
75   /// impl MyType {
76   ///   pub fn new() -> impl New<Output = Self> {
77   ///     new::of(MyType { /* ... */ }).with(|this| {
78   ///       // Address-sensitive setup can occur here.
79   ///     })
80   ///   }
81   /// }
82   /// ```
83   ///
84   /// Note: The return value of this function should not be relied upon; a
85   /// future version will replace it with `impl New`.
with<F>(self, post: F) -> With<Self, F> where F: FnOnce(Pin<&mut Self::Output>),86   fn with<F>(self, post: F) -> With<Self, F>
87   where
88     F: FnOnce(Pin<&mut Self::Output>),
89   {
90     With(self, post)
91   }
92 }
93 
94 /// An in-place constructor for a particular type, which can potentially fail.
95 ///
96 /// Emplacing a `TryNew` may allocate even when construction fails; prefer to
97 /// use `Result<impl New>` when possible, instead.
98 ///
99 /// # Safety
100 ///
101 /// [`TryNew::try_new()`] must leave its destination argument in a valid,
102 /// initialized state when it returns `Ok`.
103 #[must_use = "`New`s do nothing until emplaced into storage"]
104 pub unsafe trait TryNew: Sized {
105   /// The type to construct.
106   type Output;
107   /// The error the construction operation may return.
108   type Error;
109   /// Try to construct a new value using the arguments stored in `self`.
110   ///
111   /// # Safety
112   ///
113   /// `this` must be freshly-created memory; this function must not
114   /// be used to mutate a previously-pinned pointer that has had `self: Pin`
115   /// functions called on it.
try_new( self, this: Pin<&mut MaybeUninit<Self::Output>>, ) -> Result<(), Self::Error>116   unsafe fn try_new(
117     self,
118     this: Pin<&mut MaybeUninit<Self::Output>>,
119   ) -> Result<(), Self::Error>;
120 
121   /// Adds a post-construction operation.
122   ///
123   /// This function is analogous to [`New::with()`]; see its documentation for
124   /// more information.
125   ///
126   /// Note: The return value of this function should not be relied upon; a
127   /// future version will replace it with `impl TryNew`.
with<F>(self, post: F) -> TryWith<Self, F>128   fn with<F>(self, post: F) -> TryWith<Self, F> {
129     TryWith(self, post)
130   }
131 }
132 
133 unsafe impl<N: New> TryNew for N {
134   type Output = N::Output;
135   type Error = Infallible;
try_new( self, this: Pin<&mut MaybeUninit<Self::Output>>, ) -> Result<(), Self::Error>136   unsafe fn try_new(
137     self,
138     this: Pin<&mut MaybeUninit<Self::Output>>,
139   ) -> Result<(), Self::Error> {
140     self.new(this);
141     Ok(())
142   }
143 }
144 
145 /// A pointer type that may be "emplaced" as a stable address which a [`New`] may be used to
146 /// construct a value with.
147 ///
148 /// The `Emplace<T>::Output` type is usually either `Self` or `Pin<Self>` depending on the API of
149 /// `Self` with respect to [`DerefMut`].
150 ///
151 /// For example, `Arc<T>`, `Box<T>`, and `Rc<T>` are all `Emplace<T, Output = Pin<Self>>`.
152 ///
153 /// However, `cxx::UniquePtr<T>: Emplace<T, Output = Self>`, since `cxx::UniquePtr<T>` already only
154 /// allows obtaining pinned mutable references to `T` due to its more restrictive API, and hence
155 /// `cxx::UniquePtr<T>` does not need to be pinned itself.
156 pub trait Emplace<T>: Sized + Deref {
157   /// The stable address type within which a value of type `T` is emplaced.
158   type Output: Deref<Target = Self::Target>;
159 
160   /// Constructs a new smart pointer and emplaces `n` into its storage.
emplace<N: New<Output = T>>(n: N) -> Self::Output161   fn emplace<N: New<Output = T>>(n: N) -> Self::Output {
162     match Self::try_emplace(n) {
163       Ok(x) => x,
164       Err(e) => match e {},
165     }
166   }
167 
168   /// Constructs a new smart pointer and tries to emplace `n` into its storage.
try_emplace<N: TryNew<Output = T>>(n: N) -> Result<Self::Output, N::Error>169   fn try_emplace<N: TryNew<Output = T>>(n: N)
170     -> Result<Self::Output, N::Error>;
171 }
172 
173 impl<T> Emplace<T> for Box<T> {
174   type Output = Pin<Self>;
175 
try_emplace<N: TryNew<Output = T>>( n: N, ) -> Result<Self::Output, N::Error>176   fn try_emplace<N: TryNew<Output = T>>(
177     n: N,
178   ) -> Result<Self::Output, N::Error> {
179     let mut uninit = Box::new(MaybeUninit::<T>::uninit());
180     unsafe {
181       let pinned = Pin::new_unchecked(&mut *uninit);
182       n.try_new(pinned)?;
183       Ok(Pin::new_unchecked(Box::from_raw(
184         Box::into_raw(uninit).cast::<T>(),
185       )))
186     }
187   }
188 }
189 
190 impl<T> Emplace<T> for Rc<T> {
191   type Output = Pin<Self>;
192 
try_emplace<N: TryNew<Output = T>>( n: N, ) -> Result<Self::Output, N::Error>193   fn try_emplace<N: TryNew<Output = T>>(
194     n: N,
195   ) -> Result<Self::Output, N::Error> {
196     let uninit = Rc::new(MaybeUninit::<T>::uninit());
197     unsafe {
198       let pinned = Pin::new_unchecked(&mut *(Rc::as_ptr(&uninit) as *mut _));
199       n.try_new(pinned)?;
200       Ok(Pin::new_unchecked(Rc::from_raw(
201         Rc::into_raw(uninit).cast::<T>(),
202       )))
203     }
204   }
205 }
206 
207 impl<T> Emplace<T> for Arc<T> {
208   type Output = Pin<Self>;
209 
try_emplace<N: TryNew<Output = T>>( n: N, ) -> Result<Self::Output, N::Error>210   fn try_emplace<N: TryNew<Output = T>>(
211     n: N,
212   ) -> Result<Self::Output, N::Error> {
213     let uninit = Arc::new(MaybeUninit::<T>::uninit());
214     unsafe {
215       let pinned = Pin::new_unchecked(&mut *(Arc::as_ptr(&uninit) as *mut _));
216       n.try_new(pinned)?;
217       Ok(Pin::new_unchecked(Arc::from_raw(
218         Arc::into_raw(uninit).cast::<T>(),
219       )))
220     }
221   }
222 }
223 
224 #[doc(hidden)]
225 pub struct With<N, F>(N, F);
226 
227 unsafe impl<N: New, F> New for With<N, F>
228 where
229   F: FnOnce(Pin<&mut N::Output>),
230 {
231   type Output = N::Output;
232   #[inline]
new(self, mut this: Pin<&mut MaybeUninit<Self::Output>>)233   unsafe fn new(self, mut this: Pin<&mut MaybeUninit<Self::Output>>) {
234     self.0.new(this.as_mut());
235     // Now that `new()` has returned, we can assume `this` is initialized.
236     let this = this.map_unchecked_mut(|x| x.assume_init_mut());
237     (self.1)(this)
238   }
239 }
240 
241 #[doc(hidden)]
242 pub struct TryWith<N, F>(N, F);
243 
244 unsafe impl<N: TryNew, F> TryNew for TryWith<N, F>
245 where
246   F: FnOnce(Pin<&mut N::Output>) -> Result<(), N::Error>,
247 {
248   type Output = N::Output;
249   type Error = N::Error;
250   #[inline]
try_new( self, mut this: Pin<&mut MaybeUninit<Self::Output>>, ) -> Result<(), Self::Error>251   unsafe fn try_new(
252     self,
253     mut this: Pin<&mut MaybeUninit<Self::Output>>,
254   ) -> Result<(), Self::Error> {
255     self.0.try_new(this.as_mut())?;
256     // Now that `new()` has returned, we can assume `this` is initialized.
257     let this = this.map_unchecked_mut(|x| x.assume_init_mut());
258     (self.1)(this)
259   }
260 }
261 
262 /// A swappable type, which is able to efficiently swap the contents of two of
263 /// its values.
264 ///
265 /// Unlike [`New`], `Swap` is safe, because it does not impose any requirements
266 /// on the swapped pointers.
267 ///
268 /// It is possible to implement swapping with a source type that isn't `Self`.
269 pub trait Swap<Rhs = Self> {
270   /// Swaps the contents of `self` and `src` without running any destructors.
swap_with(self: Pin<&mut Self>, src: Pin<&mut Rhs>)271   fn swap_with(self: Pin<&mut Self>, src: Pin<&mut Rhs>);
272 }
273