@@ -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;
@@ -241,6 +241,78 @@ impl<T> Box<T> {
241241 pub fn pin ( x : T ) -> Pin < Box < T > > {
242242 ( box x) . into ( )
243243 }
244+
245+ /// Allocates memory on the heap then places `x` into it,
246+ /// returning an error if the allocation fails
247+ ///
248+ /// This doesn't actually allocate if `T` is zero-sized.
249+ ///
250+ /// # Examples
251+ ///
252+ /// ```
253+ /// #![feature(allocator_api)]
254+ ///
255+ /// let five = Box::try_new(5)?;
256+ /// # Ok::<(), std::alloc::AllocError>(())
257+ /// ```
258+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
259+ #[ inline]
260+ pub fn try_new ( x : T ) -> Result < Self , AllocError > {
261+ Self :: try_new_in ( x, Global )
262+ }
263+
264+ /// Constructs a new box with uninitialized contents on the heap,
265+ /// returning an error if the allocation fails
266+ ///
267+ /// # Examples
268+ ///
269+ /// ```
270+ /// #![feature(allocator_api, new_uninit)]
271+ ///
272+ /// let mut five = Box::<u32>::try_new_uninit()?;
273+ ///
274+ /// let five = unsafe {
275+ /// // Deferred initialization:
276+ /// five.as_mut_ptr().write(5);
277+ ///
278+ /// five.assume_init()
279+ /// };
280+ ///
281+ /// assert_eq!(*five, 5);
282+ /// # Ok::<(), std::alloc::AllocError>(())
283+ /// ```
284+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
285+ // #[unstable(feature = "new_uninit", issue = "63291")]
286+ #[ inline]
287+ pub fn try_new_uninit ( ) -> Result < Box < mem:: MaybeUninit < T > > , AllocError > {
288+ Box :: try_new_uninit_in ( Global )
289+ }
290+
291+ /// Constructs a new `Box` with uninitialized contents, with the memory
292+ /// being filled with `0` bytes on the heap
293+ ///
294+ /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
295+ /// of this method.
296+ ///
297+ /// # Examples
298+ ///
299+ /// ```
300+ /// #![feature(allocator_api, new_uninit)]
301+ ///
302+ /// let zero = Box::<u32>::try_new_zeroed()?;
303+ /// let zero = unsafe { zero.assume_init() };
304+ ///
305+ /// assert_eq!(*zero, 0);
306+ /// # Ok::<(), std::alloc::AllocError>(())
307+ /// ```
308+ ///
309+ /// [zeroed]: mem::MaybeUninit::zeroed
310+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
311+ // #[unstable(feature = "new_uninit", issue = "63291")]
312+ #[ inline]
313+ pub fn try_new_zeroed ( ) -> Result < Box < mem:: MaybeUninit < T > > , AllocError > {
314+ Box :: try_new_zeroed_in ( Global )
315+ }
244316}
245317
246318impl < T , A : Allocator > Box < T , A > {
@@ -267,6 +339,31 @@ impl<T, A: Allocator> Box<T, A> {
267339 }
268340 }
269341
342+ /// Allocates memory in the given allocator then places `x` into it,
343+ /// returning an error if the allocation fails
344+ ///
345+ /// This doesn't actually allocate if `T` is zero-sized.
346+ ///
347+ /// # Examples
348+ ///
349+ /// ```
350+ /// #![feature(allocator_api)]
351+ ///
352+ /// use std::alloc::System;
353+ ///
354+ /// let five = Box::try_new_in(5, System)?;
355+ /// # Ok::<(), std::alloc::AllocError>(())
356+ /// ```
357+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
358+ #[ inline]
359+ pub fn try_new_in ( x : T , alloc : A ) -> Result < Self , AllocError > {
360+ let mut boxed = Self :: try_new_uninit_in ( alloc) ?;
361+ unsafe {
362+ boxed. as_mut_ptr ( ) . write ( x) ;
363+ Ok ( boxed. assume_init ( ) )
364+ }
365+ }
366+
270367 /// Constructs a new box with uninitialized contents in the provided allocator.
271368 ///
272369 /// # Examples
@@ -291,8 +388,37 @@ impl<T, A: Allocator> Box<T, A> {
291388 // #[unstable(feature = "new_uninit", issue = "63291")]
292389 pub fn new_uninit_in ( alloc : A ) -> Box < mem:: MaybeUninit < T > , A > {
293390 let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
294- let ptr = alloc. allocate ( layout) . unwrap_or_else ( |_| handle_alloc_error ( layout) ) . cast ( ) ;
295- unsafe { Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) }
391+ Box :: try_new_uninit_in ( alloc) . unwrap_or_else ( |_| handle_alloc_error ( layout) )
392+ }
393+
394+ /// Constructs a new box with uninitialized contents in the provided allocator,
395+ /// returning an error if the allocation fails
396+ ///
397+ /// # Examples
398+ ///
399+ /// ```
400+ /// #![feature(allocator_api, new_uninit)]
401+ ///
402+ /// use std::alloc::System;
403+ ///
404+ /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?;
405+ ///
406+ /// let five = unsafe {
407+ /// // Deferred initialization:
408+ /// five.as_mut_ptr().write(5);
409+ ///
410+ /// five.assume_init()
411+ /// };
412+ ///
413+ /// assert_eq!(*five, 5);
414+ /// # Ok::<(), std::alloc::AllocError>(())
415+ /// ```
416+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
417+ // #[unstable(feature = "new_uninit", issue = "63291")]
418+ pub fn try_new_uninit_in ( alloc : A ) -> Result < Box < mem:: MaybeUninit < T > , A > , AllocError > {
419+ let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
420+ let ptr = alloc. allocate ( layout) ?. cast ( ) ;
421+ unsafe { Ok ( Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) ) }
296422 }
297423
298424 /// Constructs a new `Box` with uninitialized contents, with the memory
@@ -319,9 +445,37 @@ impl<T, A: Allocator> Box<T, A> {
319445 // #[unstable(feature = "new_uninit", issue = "63291")]
320446 pub fn new_zeroed_in ( alloc : A ) -> Box < mem:: MaybeUninit < T > , A > {
321447 let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
322- let ptr =
323- alloc. allocate_zeroed ( layout) . unwrap_or_else ( |_| handle_alloc_error ( layout) ) . cast ( ) ;
324- unsafe { Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) }
448+ Box :: try_new_zeroed_in ( alloc) . unwrap_or_else ( |_| handle_alloc_error ( layout) )
449+ }
450+
451+ /// Constructs a new `Box` with uninitialized contents, with the memory
452+ /// being filled with `0` bytes in the provided allocator,
453+ /// returning an error if the allocation fails,
454+ ///
455+ /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
456+ /// of this method.
457+ ///
458+ /// # Examples
459+ ///
460+ /// ```
461+ /// #![feature(allocator_api, new_uninit)]
462+ ///
463+ /// use std::alloc::System;
464+ ///
465+ /// let zero = Box::<u32, _>::try_new_zeroed_in(System)?;
466+ /// let zero = unsafe { zero.assume_init() };
467+ ///
468+ /// assert_eq!(*zero, 0);
469+ /// # Ok::<(), std::alloc::AllocError>(())
470+ /// ```
471+ ///
472+ /// [zeroed]: mem::MaybeUninit::zeroed
473+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
474+ // #[unstable(feature = "new_uninit", issue = "63291")]
475+ pub fn try_new_zeroed_in ( alloc : A ) -> Result < Box < mem:: MaybeUninit < T > , A > , AllocError > {
476+ let layout = Layout :: new :: < mem:: MaybeUninit < T > > ( ) ;
477+ let ptr = alloc. allocate_zeroed ( layout) ?. cast ( ) ;
478+ unsafe { Ok ( Box :: from_raw_in ( ptr. as_ptr ( ) , alloc) ) }
325479 }
326480
327481 /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
0 commit comments