@@ -1351,6 +1351,58 @@ impl Bump {
1351
1351
}
1352
1352
}
1353
1353
1354
+ /// Allocates a new slice of size `len` into this `Bump` and returns an
1355
+ /// exclusive reference to the copy, failing if the closure return an Err.
1356
+ ///
1357
+ /// The elements of the slice are initialized using the supplied closure.
1358
+ /// The closure argument is the position in the slice.
1359
+ ///
1360
+ /// ## Panics
1361
+ ///
1362
+ /// Panics if reserving space for the slice fails.
1363
+ ///
1364
+ /// ## Example
1365
+ ///
1366
+ /// ```
1367
+ /// let bump = bumpalo::Bump::new();
1368
+ /// let x: Result<&mut [usize], ()> = bump.alloc_slice_try_fill_with(5, |i| Ok(5 * i));
1369
+ /// assert_eq!(x, Ok(bump.alloc_slice_copy(&[0, 5, 10, 15, 20])));
1370
+ /// ```
1371
+ ///
1372
+ /// ```
1373
+ /// let bump = bumpalo::Bump::new();
1374
+ /// let x: Result<&mut [usize], ()> = bump.alloc_slice_try_fill_with(
1375
+ /// 5,
1376
+ /// |n| if n == 2 { Err(()) } else { Ok(n) }
1377
+ /// );
1378
+ /// assert_eq!(x, Err(()));
1379
+ /// ```
1380
+ #[ inline( always) ]
1381
+ pub fn alloc_slice_try_fill_with < T , F , E > ( & self , len : usize , mut f : F ) -> Result < & mut [ T ] , E >
1382
+ where
1383
+ F : FnMut ( usize ) -> Result < T , E > ,
1384
+ {
1385
+ let layout = Layout :: array :: < T > ( len) . unwrap_or_else ( |_| oom ( ) ) ;
1386
+ let base_ptr = self . alloc_layout ( layout) ;
1387
+ let dst = base_ptr. cast :: < T > ( ) ;
1388
+
1389
+ unsafe {
1390
+ for i in 0 ..len {
1391
+ match f ( i) {
1392
+ Ok ( el) => ptr:: write ( dst. as_ptr ( ) . add ( i) , el) ,
1393
+ Err ( e) => {
1394
+ self . dealloc ( base_ptr, layout) ;
1395
+ return Err ( e) ;
1396
+ }
1397
+ }
1398
+ }
1399
+
1400
+ let result = slice:: from_raw_parts_mut ( dst. as_ptr ( ) , len) ;
1401
+ debug_assert_eq ! ( Layout :: for_value( result) , layout) ;
1402
+ Ok ( result)
1403
+ }
1404
+ }
1405
+
1354
1406
/// Allocates a new slice of size `len` into this `Bump` and returns an
1355
1407
/// exclusive reference to the copy.
1356
1408
///
@@ -1487,6 +1539,45 @@ impl Bump {
1487
1539
} )
1488
1540
}
1489
1541
1542
+ /// Allocates a new slice of size `len` slice into this `Bump` and return an
1543
+ /// exclusive reference to the copy, failing if the iterator returns an Err.
1544
+ ///
1545
+ /// The elements are initialized using the supplied iterator.
1546
+ ///
1547
+ /// ## Panics
1548
+ ///
1549
+ /// Panics if reserving space for the slice fails, or if the supplied
1550
+ /// iterator returns fewer elements than it promised.
1551
+ ///
1552
+ /// ## Examples
1553
+ ///
1554
+ /// ```
1555
+ /// let bump = bumpalo::Bump::new();
1556
+ /// let x: Result<&mut [i32], ()> = bump.alloc_slice_try_fill_iter(
1557
+ /// [2, 3, 5].iter().cloned().map(|i| Ok(i * i))
1558
+ /// );
1559
+ /// assert_eq!(x, Ok(bump.alloc_slice_copy(&[4, 9, 25])));
1560
+ /// ```
1561
+ ///
1562
+ /// ```
1563
+ /// let bump = bumpalo::Bump::new();
1564
+ /// let x: Result<&mut [i32], ()> = bump.alloc_slice_try_fill_iter(
1565
+ /// [Ok(2), Err(()), Ok(5)].iter().cloned()
1566
+ /// );
1567
+ /// assert_eq!(x, Err(()));
1568
+ /// ```
1569
+ #[ inline( always) ]
1570
+ pub fn alloc_slice_try_fill_iter < T , I , E > ( & self , iter : I ) -> Result < & mut [ T ] , E >
1571
+ where
1572
+ I : IntoIterator < Item = Result < T , E > > ,
1573
+ I :: IntoIter : ExactSizeIterator ,
1574
+ {
1575
+ let mut iter = iter. into_iter ( ) ;
1576
+ self . alloc_slice_try_fill_with ( iter. len ( ) , |_| {
1577
+ iter. next ( ) . expect ( "Iterator supplied too few elements" )
1578
+ } )
1579
+ }
1580
+
1490
1581
/// Allocates a new slice of size `iter.len()` slice into this `Bump` and return an
1491
1582
/// exclusive reference to the copy. Does not panic on failure.
1492
1583
///
0 commit comments