@@ -153,7 +153,7 @@ use core::pin::Pin;
153
153
use core:: ptr:: { self , Unique } ;
154
154
use core:: task:: { Context , Poll } ;
155
155
156
- use crate :: alloc:: { handle_alloc_error, Allocator , Global , Layout } ;
156
+ use crate :: alloc:: { handle_alloc_error, AllocError , Allocator , Global , Layout } ;
157
157
use crate :: borrow:: Cow ;
158
158
use crate :: raw_vec:: RawVec ;
159
159
use crate :: str:: from_boxed_utf8_unchecked;
@@ -241,6 +241,78 @@ impl<T> Box<T> {
241
241
pub fn pin ( x : T ) -> Pin < Box < T > > {
242
242
( box x) . into ( )
243
243
}
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
+ }
244
316
}
245
317
246
318
impl < T , A : Allocator > Box < T , A > {
@@ -267,6 +339,31 @@ impl<T, A: Allocator> Box<T, A> {
267
339
}
268
340
}
269
341
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
+
270
367
/// Constructs a new box with uninitialized contents in the provided allocator.
271
368
///
272
369
/// # Examples
@@ -291,8 +388,37 @@ impl<T, A: Allocator> Box<T, A> {
291
388
// #[unstable(feature = "new_uninit", issue = "63291")]
292
389
pub fn new_uninit_in ( alloc : A ) -> Box < mem:: MaybeUninit < T > , A > {
293
390
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) ) }
296
422
}
297
423
298
424
/// Constructs a new `Box` with uninitialized contents, with the memory
@@ -319,9 +445,37 @@ impl<T, A: Allocator> Box<T, A> {
319
445
// #[unstable(feature = "new_uninit", issue = "63291")]
320
446
pub fn new_zeroed_in ( alloc : A ) -> Box < mem:: MaybeUninit < T > , A > {
321
447
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) ) }
325
479
}
326
480
327
481
/// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
0 commit comments