@@ -952,38 +952,19 @@ impl<T, const N: usize> Vec<T, N> {
952
952
where
953
953
T : Clone ,
954
954
{
955
- if self . len + other. len ( ) > self . capacity ( ) {
956
- // won't fit in the `Vec`; don't modify anything and return an error
957
- Err ( ( ) )
958
- } else {
959
- for elem in other {
960
- unsafe {
961
- self . push_unchecked ( elem. clone ( ) ) ;
962
- }
963
- }
964
- Ok ( ( ) )
965
- }
955
+ self . as_mut_view ( ) . extend_from_slice ( other)
966
956
}
967
957
968
958
/// Removes the last element from a vector and returns it, or `None` if it's empty
969
959
pub fn pop ( & mut self ) -> Option < T > {
970
- if self . len != 0 {
971
- Some ( unsafe { self . pop_unchecked ( ) } )
972
- } else {
973
- None
974
- }
960
+ self . as_mut_view ( ) . pop ( )
975
961
}
976
962
977
963
/// Appends an `item` to the back of the collection
978
964
///
979
965
/// Returns back the `item` if the vector is full
980
966
pub fn push ( & mut self , item : T ) -> Result < ( ) , T > {
981
- if self . len < self . capacity ( ) {
982
- unsafe { self . push_unchecked ( item) }
983
- Ok ( ( ) )
984
- } else {
985
- Err ( item)
986
- }
967
+ self . as_mut_view ( ) . push ( item)
987
968
}
988
969
989
970
/// Removes the last element from a vector and returns it
@@ -992,10 +973,7 @@ impl<T, const N: usize> Vec<T, N> {
992
973
///
993
974
/// This assumes the vec to have at least one element.
994
975
pub unsafe fn pop_unchecked ( & mut self ) -> T {
995
- debug_assert ! ( !self . is_empty( ) ) ;
996
-
997
- self . len -= 1 ;
998
- self . buffer . get_unchecked_mut ( self . len ) . as_ptr ( ) . read ( )
976
+ self . as_mut_view ( ) . pop_unchecked ( )
999
977
}
1000
978
1001
979
/// Appends an `item` to the back of the collection
@@ -1004,36 +982,12 @@ impl<T, const N: usize> Vec<T, N> {
1004
982
///
1005
983
/// This assumes the vec is not full.
1006
984
pub unsafe fn push_unchecked ( & mut self , item : T ) {
1007
- // NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
1008
- // use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
1009
- debug_assert ! ( !self . is_full( ) ) ;
1010
-
1011
- * self . buffer . get_unchecked_mut ( self . len ) = MaybeUninit :: new ( item) ;
1012
-
1013
- self . len += 1 ;
985
+ self . as_mut_view ( ) . push_unchecked ( item)
1014
986
}
1015
987
1016
988
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
1017
989
pub fn truncate ( & mut self , len : usize ) {
1018
- // This is safe because:
1019
- //
1020
- // * the slice passed to `drop_in_place` is valid; the `len > self.len`
1021
- // case avoids creating an invalid slice, and
1022
- // * the `len` of the vector is shrunk before calling `drop_in_place`,
1023
- // such that no value will be dropped twice in case `drop_in_place`
1024
- // were to panic once (if it panics twice, the program aborts).
1025
- unsafe {
1026
- // Note: It's intentional that this is `>` and not `>=`.
1027
- // Changing it to `>=` has negative performance
1028
- // implications in some cases. See rust-lang/rust#78884 for more.
1029
- if len > self . len {
1030
- return ;
1031
- }
1032
- let remaining_len = self . len - len;
1033
- let s = ptr:: slice_from_raw_parts_mut ( self . as_mut_ptr ( ) . add ( len) , remaining_len) ;
1034
- self . len = len;
1035
- ptr:: drop_in_place ( s) ;
1036
- }
990
+ self . as_mut_view ( ) . truncate ( len)
1037
991
}
1038
992
1039
993
/// Resizes the Vec in-place so that len is equal to new_len.
@@ -1048,19 +1002,7 @@ impl<T, const N: usize> Vec<T, N> {
1048
1002
where
1049
1003
T : Clone ,
1050
1004
{
1051
- if new_len > self . capacity ( ) {
1052
- return Err ( ( ) ) ;
1053
- }
1054
-
1055
- if new_len > self . len {
1056
- while self . len < new_len {
1057
- self . push ( value. clone ( ) ) . ok ( ) ;
1058
- }
1059
- } else {
1060
- self . truncate ( new_len) ;
1061
- }
1062
-
1063
- Ok ( ( ) )
1005
+ self . as_mut_view ( ) . resize ( new_len, value)
1064
1006
}
1065
1007
1066
1008
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
@@ -1075,7 +1017,7 @@ impl<T, const N: usize> Vec<T, N> {
1075
1017
where
1076
1018
T : Clone + Default ,
1077
1019
{
1078
- self . resize ( new_len , T :: default ( ) )
1020
+ self . as_mut_view ( ) . resize_default ( new_len )
1079
1021
}
1080
1022
1081
1023
/// Forces the length of the vector to `new_len`.
@@ -1202,8 +1144,7 @@ impl<T, const N: usize> Vec<T, N> {
1202
1144
/// assert_eq!(&*v, ["baz", "qux"]);
1203
1145
/// ```
1204
1146
pub fn swap_remove ( & mut self , index : usize ) -> T {
1205
- assert ! ( index < self . len) ;
1206
- unsafe { self . swap_remove_unchecked ( index) }
1147
+ self . as_mut_view ( ) . swap_remove ( index)
1207
1148
}
1208
1149
1209
1150
/// Removes an element from the vector and returns it.
@@ -1234,13 +1175,7 @@ impl<T, const N: usize> Vec<T, N> {
1234
1175
/// assert_eq!(&*v, ["baz", "qux"]);
1235
1176
/// ```
1236
1177
pub unsafe fn swap_remove_unchecked ( & mut self , index : usize ) -> T {
1237
- let length = self . len ( ) ;
1238
- debug_assert ! ( index < length) ;
1239
- let value = ptr:: read ( self . as_ptr ( ) . add ( index) ) ;
1240
- let base_ptr = self . as_mut_ptr ( ) ;
1241
- ptr:: copy ( base_ptr. add ( length - 1 ) , base_ptr. add ( index) , 1 ) ;
1242
- self . len -= 1 ;
1243
- value
1178
+ self . as_mut_view ( ) . swap_remove_unchecked ( index)
1244
1179
}
1245
1180
1246
1181
/// Returns true if the vec is full
@@ -1322,35 +1257,7 @@ impl<T, const N: usize> Vec<T, N> {
1322
1257
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
1323
1258
/// ```
1324
1259
pub fn insert ( & mut self , index : usize , element : T ) -> Result < ( ) , T > {
1325
- let len = self . len ( ) ;
1326
- if index > len {
1327
- panic ! (
1328
- "insertion index (is {}) should be <= len (is {})" ,
1329
- index, len
1330
- ) ;
1331
- }
1332
-
1333
- // check there's space for the new element
1334
- if self . is_full ( ) {
1335
- return Err ( element) ;
1336
- }
1337
-
1338
- unsafe {
1339
- // infallible
1340
- // The spot to put the new value
1341
- {
1342
- let p = self . as_mut_ptr ( ) . add ( index) ;
1343
- // Shift everything over to make space. (Duplicating the
1344
- // `index`th element into two consecutive places.)
1345
- ptr:: copy ( p, p. offset ( 1 ) , len - index) ;
1346
- // Write it in, overwriting the first copy of the `index`th
1347
- // element.
1348
- ptr:: write ( p, element) ;
1349
- }
1350
- self . set_len ( len + 1 ) ;
1351
- }
1352
-
1353
- Ok ( ( ) )
1260
+ self . as_mut_view ( ) . insert ( index, element)
1354
1261
}
1355
1262
1356
1263
/// Removes and returns the element at position `index` within the vector,
@@ -1379,26 +1286,7 @@ impl<T, const N: usize> Vec<T, N> {
1379
1286
/// assert_eq!(v, [1, 3]);
1380
1287
/// ```
1381
1288
pub fn remove ( & mut self , index : usize ) -> T {
1382
- let len = self . len ( ) ;
1383
- if index >= len {
1384
- panic ! ( "removal index (is {}) should be < len (is {})" , index, len) ;
1385
- }
1386
- unsafe {
1387
- // infallible
1388
- let ret;
1389
- {
1390
- // the place we are taking from.
1391
- let ptr = self . as_mut_ptr ( ) . add ( index) ;
1392
- // copy it out, unsafely having a copy of the value on
1393
- // the stack and in the vector at the same time.
1394
- ret = ptr:: read ( ptr) ;
1395
-
1396
- // Shift everything down to fill in that spot.
1397
- ptr:: copy ( ptr. offset ( 1 ) , ptr, len - index - 1 ) ;
1398
- }
1399
- self . set_len ( len - 1 ) ;
1400
- ret
1401
- }
1289
+ self . as_mut_view ( ) . remove ( index)
1402
1290
}
1403
1291
1404
1292
/// Retains only the elements specified by the predicate.
@@ -1429,11 +1317,11 @@ impl<T, const N: usize> Vec<T, N> {
1429
1317
/// vec.retain(|_| *iter.next().unwrap());
1430
1318
/// assert_eq!(vec, [2, 3, 5]);
1431
1319
/// ```
1432
- pub fn retain < F > ( & mut self , mut f : F )
1320
+ pub fn retain < F > ( & mut self , f : F )
1433
1321
where
1434
1322
F : FnMut ( & T ) -> bool ,
1435
1323
{
1436
- self . retain_mut ( |elem| f ( elem ) ) ;
1324
+ self . as_mut_view ( ) . retain ( f )
1437
1325
}
1438
1326
1439
1327
/// Retains only the elements specified by the predicate, passing a mutable reference to it.
@@ -1458,105 +1346,11 @@ impl<T, const N: usize> Vec<T, N> {
1458
1346
/// });
1459
1347
/// assert_eq!(vec, [2, 3, 4]);
1460
1348
/// ```
1461
- pub fn retain_mut < F > ( & mut self , mut f : F )
1349
+ pub fn retain_mut < F > ( & mut self , f : F )
1462
1350
where
1463
1351
F : FnMut ( & mut T ) -> bool ,
1464
1352
{
1465
- let original_len = self . len ( ) ;
1466
- // Avoid double drop if the drop guard is not executed,
1467
- // since we may make some holes during the process.
1468
- unsafe { self . set_len ( 0 ) } ;
1469
-
1470
- // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
1471
- // |<- processed len ->| ^- next to check
1472
- // |<- deleted cnt ->|
1473
- // |<- original_len ->|
1474
- // Kept: Elements which predicate returns true on.
1475
- // Hole: Moved or dropped element slot.
1476
- // Unchecked: Unchecked valid elements.
1477
- //
1478
- // This drop guard will be invoked when predicate or `drop` of element panicked.
1479
- // It shifts unchecked elements to cover holes and `set_len` to the correct length.
1480
- // In cases when predicate and `drop` never panick, it will be optimized out.
1481
- struct BackshiftOnDrop < ' a , T , const N : usize > {
1482
- v : & ' a mut Vec < T , N > ,
1483
- processed_len : usize ,
1484
- deleted_cnt : usize ,
1485
- original_len : usize ,
1486
- }
1487
-
1488
- impl < T , const N : usize > Drop for BackshiftOnDrop < ' _ , T , N > {
1489
- fn drop ( & mut self ) {
1490
- if self . deleted_cnt > 0 {
1491
- // SAFETY: Trailing unchecked items must be valid since we never touch them.
1492
- unsafe {
1493
- ptr:: copy (
1494
- self . v . as_ptr ( ) . add ( self . processed_len ) ,
1495
- self . v
1496
- . as_mut_ptr ( )
1497
- . add ( self . processed_len - self . deleted_cnt ) ,
1498
- self . original_len - self . processed_len ,
1499
- ) ;
1500
- }
1501
- }
1502
- // SAFETY: After filling holes, all items are in contiguous memory.
1503
- unsafe {
1504
- self . v . set_len ( self . original_len - self . deleted_cnt ) ;
1505
- }
1506
- }
1507
- }
1508
-
1509
- let mut g = BackshiftOnDrop {
1510
- v : self ,
1511
- processed_len : 0 ,
1512
- deleted_cnt : 0 ,
1513
- original_len,
1514
- } ;
1515
-
1516
- fn process_loop < F , T , const N : usize , const DELETED : bool > (
1517
- original_len : usize ,
1518
- f : & mut F ,
1519
- g : & mut BackshiftOnDrop < ' _ , T , N > ,
1520
- ) where
1521
- F : FnMut ( & mut T ) -> bool ,
1522
- {
1523
- while g. processed_len != original_len {
1524
- let p = g. v . as_mut_ptr ( ) ;
1525
- // SAFETY: Unchecked element must be valid.
1526
- let cur = unsafe { & mut * p. add ( g. processed_len ) } ;
1527
- if !f ( cur) {
1528
- // Advance early to avoid double drop if `drop_in_place` panicked.
1529
- g. processed_len += 1 ;
1530
- g. deleted_cnt += 1 ;
1531
- // SAFETY: We never touch this element again after dropped.
1532
- unsafe { ptr:: drop_in_place ( cur) } ;
1533
- // We already advanced the counter.
1534
- if DELETED {
1535
- continue ;
1536
- } else {
1537
- break ;
1538
- }
1539
- }
1540
- if DELETED {
1541
- // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1542
- // We use copy for move, and never touch this element again.
1543
- unsafe {
1544
- let hole_slot = p. add ( g. processed_len - g. deleted_cnt ) ;
1545
- ptr:: copy_nonoverlapping ( cur, hole_slot, 1 ) ;
1546
- }
1547
- }
1548
- g. processed_len += 1 ;
1549
- }
1550
- }
1551
-
1552
- // Stage 1: Nothing was deleted.
1553
- process_loop :: < F , T , N , false > ( original_len, & mut f, & mut g) ;
1554
-
1555
- // Stage 2: Some elements were deleted.
1556
- process_loop :: < F , T , N , true > ( original_len, & mut f, & mut g) ;
1557
-
1558
- // All item are processed. This can be optimized to `set_len` by LLVM.
1559
- drop ( g) ;
1353
+ self . as_mut_view ( ) . retain_mut ( f)
1560
1354
}
1561
1355
}
1562
1356
0 commit comments