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