@@ -1180,6 +1180,35 @@ impl Bump {
1180
1180
}
1181
1181
}
1182
1182
1183
+ /// Like `alloc_slice_copy`, but does not panic in case of allocation failure.
1184
+ ///
1185
+ /// ## Example
1186
+ ///
1187
+ /// ```
1188
+ /// let bump = bumpalo::Bump::new();
1189
+ /// let x = bump.try_alloc_slice_copy(&[1, 2, 3]);
1190
+ /// assert_eq!(x, Ok(&mut[1, 2, 3] as &mut [_]));
1191
+ ///
1192
+ ///
1193
+ /// let bump = bumpalo::Bump::new();
1194
+ /// bump.set_allocation_limit(Some(4));
1195
+ /// let x = bump.try_alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
1196
+ /// assert_eq!(x, Err(bumpalo::AllocErr)); // too big
1197
+ /// ```
1198
+ #[ inline( always) ]
1199
+ pub fn try_alloc_slice_copy < T > ( & self , src : & [ T ] ) -> Result < & mut [ T ] , AllocErr >
1200
+ where
1201
+ T : Copy ,
1202
+ {
1203
+ let layout = Layout :: for_value ( src) ;
1204
+ let dst = self . try_alloc_layout ( layout) ?. cast :: < T > ( ) ;
1205
+ let result = unsafe {
1206
+ core:: ptr:: copy_nonoverlapping ( src. as_ptr ( ) , dst. as_ptr ( ) , src. len ( ) ) ;
1207
+ slice:: from_raw_parts_mut ( dst. as_ptr ( ) , src. len ( ) )
1208
+ } ;
1209
+ Ok ( result)
1210
+ }
1211
+
1183
1212
/// `Clone` a slice into this `Bump` and return an exclusive reference to
1184
1213
/// the clone. Prefer [`alloc_slice_copy`](#method.alloc_slice_copy) if `T` is `Copy`.
1185
1214
///
@@ -1222,6 +1251,24 @@ impl Bump {
1222
1251
}
1223
1252
}
1224
1253
1254
+ /// Like `alloc_slice_clone` but does not panic on failure.
1255
+ #[ inline( always) ]
1256
+ pub fn try_alloc_slice_clone < T > ( & self , src : & [ T ] ) -> Result < & mut [ T ] , AllocErr >
1257
+ where
1258
+ T : Clone ,
1259
+ {
1260
+ let layout = Layout :: for_value ( src) ;
1261
+ let dst = self . try_alloc_layout ( layout) ?. cast :: < T > ( ) ;
1262
+
1263
+ unsafe {
1264
+ for ( i, val) in src. iter ( ) . cloned ( ) . enumerate ( ) {
1265
+ ptr:: write ( dst. as_ptr ( ) . add ( i) , val) ;
1266
+ }
1267
+
1268
+ Ok ( slice:: from_raw_parts_mut ( dst. as_ptr ( ) , src. len ( ) ) )
1269
+ }
1270
+ }
1271
+
1225
1272
/// `Copy` a string slice into this `Bump` and return an exclusive reference to it.
1226
1273
///
1227
1274
/// ## Panics
@@ -1244,6 +1291,30 @@ impl Bump {
1244
1291
}
1245
1292
}
1246
1293
1294
+ /// Same as `alloc_str` but does not panic on failure.
1295
+ ///
1296
+ /// ## Example
1297
+ ///
1298
+ /// ```
1299
+ /// let bump = bumpalo::Bump::new();
1300
+ /// let hello = bump.try_alloc_str("hello world").unwrap();
1301
+ /// assert_eq!("hello world", hello);
1302
+ ///
1303
+ ///
1304
+ /// let bump = bumpalo::Bump::new();
1305
+ /// bump.set_allocation_limit(Some(5));
1306
+ /// let hello = bump.try_alloc_str("hello world");
1307
+ /// assert_eq!(Err(bumpalo::AllocErr), hello);
1308
+ /// ```
1309
+ #[ inline( always) ]
1310
+ pub fn try_alloc_str ( & self , src : & str ) -> Result < & mut str , AllocErr > {
1311
+ let buffer = self . try_alloc_slice_copy ( src. as_bytes ( ) ) ?;
1312
+ unsafe {
1313
+ // This is OK, because it already came in as str, so it is guaranteed to be utf8
1314
+ Ok ( str:: from_utf8_unchecked_mut ( buffer) )
1315
+ }
1316
+ }
1317
+
1247
1318
/// Allocates a new slice of size `len` into this `Bump` and returns an
1248
1319
/// exclusive reference to the copy.
1249
1320
///
@@ -1280,6 +1351,48 @@ impl Bump {
1280
1351
}
1281
1352
}
1282
1353
1354
+ /// Allocates a new slice of size `len` into this `Bump` and returns an
1355
+ /// exclusive reference to the copy.
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
+ /// ## Example
1361
+ ///
1362
+ /// ```
1363
+ /// let bump = bumpalo::Bump::new();
1364
+ /// let x = bump.try_alloc_slice_fill_with(5, |i| 5 * (i + 1));
1365
+ /// assert_eq!(x, Ok(&mut[5usize, 10, 15, 20, 25] as &mut [_]));
1366
+ ///
1367
+ ///
1368
+ /// let bump = bumpalo::Bump::new();
1369
+ /// bump.set_allocation_limit(Some(4));
1370
+ /// let x = bump.try_alloc_slice_fill_with(10, |i| 5 * (i + 1));
1371
+ /// assert_eq!(x, Err(bumpalo::AllocErr));
1372
+ /// ```
1373
+ #[ inline( always) ]
1374
+ pub fn try_alloc_slice_fill_with < T , F > (
1375
+ & self ,
1376
+ len : usize ,
1377
+ mut f : F ,
1378
+ ) -> Result < & mut [ T ] , AllocErr >
1379
+ where
1380
+ F : FnMut ( usize ) -> T ,
1381
+ {
1382
+ let layout = Layout :: array :: < T > ( len) . map_err ( |_| AllocErr ) ?;
1383
+ let dst = self . try_alloc_layout ( layout) ?. cast :: < T > ( ) ;
1384
+
1385
+ unsafe {
1386
+ for i in 0 ..len {
1387
+ ptr:: write ( dst. as_ptr ( ) . add ( i) , f ( i) ) ;
1388
+ }
1389
+
1390
+ let result = slice:: from_raw_parts_mut ( dst. as_ptr ( ) , len) ;
1391
+ debug_assert_eq ! ( Layout :: for_value( result) , layout) ;
1392
+ Ok ( result)
1393
+ }
1394
+ }
1395
+
1283
1396
/// Allocates a new slice of size `len` into this `Bump` and returns an
1284
1397
/// exclusive reference to the copy.
1285
1398
///
@@ -1301,6 +1414,16 @@ impl Bump {
1301
1414
self . alloc_slice_fill_with ( len, |_| value)
1302
1415
}
1303
1416
1417
+ /// Same as `alloc_slice_fill_copy` but does not panic on failure.
1418
+ #[ inline( always) ]
1419
+ pub fn try_alloc_slice_fill_copy < T : Copy > (
1420
+ & self ,
1421
+ len : usize ,
1422
+ value : T ,
1423
+ ) -> Result < & mut [ T ] , AllocErr > {
1424
+ self . try_alloc_slice_fill_with ( len, |_| value)
1425
+ }
1426
+
1304
1427
/// Allocates a new slice of size `len` slice into this `Bump` and return an
1305
1428
/// exclusive reference to the copy.
1306
1429
///
@@ -1325,6 +1448,16 @@ impl Bump {
1325
1448
self . alloc_slice_fill_with ( len, |_| value. clone ( ) )
1326
1449
}
1327
1450
1451
+ /// Like `alloc_slice_fill_clone` but does not panic on failure.
1452
+ #[ inline( always) ]
1453
+ pub fn try_alloc_slice_fill_clone < T : Clone > (
1454
+ & self ,
1455
+ len : usize ,
1456
+ value : & T ,
1457
+ ) -> Result < & mut [ T ] , AllocErr > {
1458
+ self . try_alloc_slice_fill_with ( len, |_| value. clone ( ) )
1459
+ }
1460
+
1328
1461
/// Allocates a new slice of size `len` slice into this `Bump` and return an
1329
1462
/// exclusive reference to the copy.
1330
1463
///
@@ -1354,6 +1487,31 @@ impl Bump {
1354
1487
} )
1355
1488
}
1356
1489
1490
+ /// Allocates a new slice of size `iter.len()` slice into this `Bump` and return an
1491
+ /// exclusive reference to the copy. Does not panic on failure.
1492
+ ///
1493
+ /// The elements are initialized using the supplied iterator.
1494
+ ///
1495
+ /// ## Example
1496
+ ///
1497
+ /// ```
1498
+ /// let bump = bumpalo::Bump::new();
1499
+ /// let x: &[i32] = bump.try_alloc_slice_fill_iter([2, 3, 5]
1500
+ /// .iter().cloned().map(|i| i * i)).unwrap();
1501
+ /// assert_eq!(x, [4, 9, 25]);
1502
+ /// ```
1503
+ #[ inline( always) ]
1504
+ pub fn try_alloc_slice_fill_iter < T , I > ( & self , iter : I ) -> Result < & mut [ T ] , AllocErr >
1505
+ where
1506
+ I : IntoIterator < Item = T > ,
1507
+ I :: IntoIter : ExactSizeIterator ,
1508
+ {
1509
+ let mut iter = iter. into_iter ( ) ;
1510
+ self . try_alloc_slice_fill_with ( iter. len ( ) , |_| {
1511
+ iter. next ( ) . expect ( "Iterator supplied too few elements" )
1512
+ } )
1513
+ }
1514
+
1357
1515
/// Allocates a new slice of size `len` slice into this `Bump` and return an
1358
1516
/// exclusive reference to the copy.
1359
1517
///
@@ -1377,6 +1535,15 @@ impl Bump {
1377
1535
self . alloc_slice_fill_with ( len, |_| T :: default ( ) )
1378
1536
}
1379
1537
1538
+ /// Like `alloc_slice_fill_default` but does not panic on failure.
1539
+ #[ inline( always) ]
1540
+ pub fn try_alloc_slice_fill_default < T : Default > (
1541
+ & self ,
1542
+ len : usize ,
1543
+ ) -> Result < & mut [ T ] , AllocErr > {
1544
+ self . try_alloc_slice_fill_with ( len, |_| T :: default ( ) )
1545
+ }
1546
+
1380
1547
/// Allocate space for an object with the given `Layout`.
1381
1548
///
1382
1549
/// The returned pointer points at uninitialized memory, and should be
0 commit comments