@@ -153,7 +153,7 @@ use core::pin::Pin;
153153use core:: ptr:: { self , Unique } ;
154154use core:: task:: { Context , Poll } ;
155155
156- use crate :: alloc:: { handle_alloc_error, Allocator , Global , Layout } ;
156+ use crate :: alloc:: { handle_alloc_error, AllocError , Allocator , Global , Layout } ;
157157use crate :: borrow:: Cow ;
158158use crate :: raw_vec:: RawVec ;
159159use crate :: str:: from_boxed_utf8_unchecked;
@@ -267,6 +267,31 @@ impl<T, A: Allocator> Box<T, A> {
267267 }
268268 }
269269
270+ /// Allocates memory in the given allocator then places `x` into it,
271+ /// returning an error if the allocation fails
272+ ///
273+ /// This doesn't actually allocate if `T` is zero-sized.
274+ ///
275+ /// # Examples
276+ ///
277+ /// ```
278+ /// #![feature(allocator_api)]
279+ ///
280+ /// use std::alloc::System;
281+ ///
282+ /// let five = Box::try_new_in(5, System)?;
283+ /// # Ok::<(), std::alloc::AllocError>(())
284+ /// ```
285+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
286+ #[ inline]
287+ pub fn try_new_in ( x : T , alloc : A ) -> Result < Self , AllocError > {
288+ let mut boxed = Self :: try_new_uninit_in ( alloc) ?;
289+ unsafe {
290+ boxed. as_mut_ptr ( ) . write ( x) ;
291+ Ok ( boxed. assume_init ( ) )
292+ }
293+ }
294+
270295 /// Constructs a new box with uninitialized contents in the provided allocator.
271296 ///
272297 /// # Examples
@@ -295,6 +320,36 @@ impl<T, A: Allocator> Box<T, A> {
295320 unsafe { Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) }
296321 }
297322
323+ /// Constructs a new box with uninitialized contents in the provided allocator,
324+ /// returning an error if the allocation fails
325+ ///
326+ /// # Examples
327+ ///
328+ /// ```
329+ /// #![feature(allocator_api, new_uninit)]
330+ ///
331+ /// use std::alloc::System;
332+ ///
333+ /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?;
334+ ///
335+ /// let five = unsafe {
336+ /// // Deferred initialization:
337+ /// five.as_mut_ptr().write(5);
338+ ///
339+ /// five.assume_init()
340+ /// };
341+ ///
342+ /// assert_eq!(*five, 5);
343+ /// # Ok::<(), std::alloc::AllocError>(())
344+ /// ```
345+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
346+ // #[unstable(feature = "new_uninit", issue = "63291")]
347+ pub fn try_new_uninit_in ( alloc : A ) -> Result < Box < mem:: MaybeUninit < T > , A > , AllocError > {
348+ let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
349+ let ptr = alloc. allocate ( layout) ?. cast ( ) ;
350+ unsafe { Ok ( Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) ) }
351+ }
352+
298353 /// Constructs a new `Box` with uninitialized contents, with the memory
299354 /// being filled with `0` bytes in the provided allocator.
300355 ///
@@ -324,6 +379,35 @@ impl<T, A: Allocator> Box<T, A> {
324379 unsafe { Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) }
325380 }
326381
382+ /// Constructs a new `Box` with uninitialized contents, with the memory
383+ /// being filled with `0` bytes in the provided allocator.
384+ ///
385+ /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
386+ /// of this method.
387+ ///
388+ /// # Examples
389+ ///
390+ /// ```
391+ /// #![feature(allocator_api, new_uninit)]
392+ ///
393+ /// use std::alloc::System;
394+ ///
395+ /// let zero = Box::<u32, _>::try_new_zeroed_in(System)?;
396+ /// let zero = unsafe { zero.assume_init() };
397+ ///
398+ /// assert_eq!(*zero, 0);
399+ /// # Ok::<(), std::alloc::AllocError>(())
400+ /// ```
401+ ///
402+ /// [zeroed]: mem::MaybeUninit::zeroed
403+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
404+ // #[unstable(feature = "new_uninit", issue = "63291")]
405+ pub fn try_new_zeroed_in ( alloc : A ) -> Result < Box < mem:: MaybeUninit < T > , A > , AllocError > {
406+ let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
407+ let ptr = alloc. allocate_zeroed ( layout) ?. cast ( ) ;
408+ unsafe { Ok ( Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) ) }
409+ }
410+
327411 /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
328412 /// `x` will be pinned in memory and unable to be moved.
329413 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
0 commit comments