@@ -998,38 +998,19 @@ impl<T, const N: usize> Vec<T, N> {
998
998
where
999
999
T : Clone ,
1000
1000
{
1001
- if self . len + other. len ( ) > self . capacity ( ) {
1002
- // won't fit in the `Vec`; don't modify anything and return an error
1003
- Err ( ( ) )
1004
- } else {
1005
- for elem in other {
1006
- unsafe {
1007
- self . push_unchecked ( elem. clone ( ) ) ;
1008
- }
1009
- }
1010
- Ok ( ( ) )
1011
- }
1001
+ self . as_mut_view ( ) . extend_from_slice ( other)
1012
1002
}
1013
1003
1014
1004
/// Removes the last element from a vector and returns it, or `None` if it's empty
1015
1005
pub fn pop ( & mut self ) -> Option < T > {
1016
- if self . len != 0 {
1017
- Some ( unsafe { self . pop_unchecked ( ) } )
1018
- } else {
1019
- None
1020
- }
1006
+ self . as_mut_view ( ) . pop ( )
1021
1007
}
1022
1008
1023
1009
/// Appends an `item` to the back of the collection
1024
1010
///
1025
1011
/// Returns back the `item` if the vector is full
1026
1012
pub fn push ( & mut self , item : T ) -> Result < ( ) , T > {
1027
- if self . len < self . capacity ( ) {
1028
- unsafe { self . push_unchecked ( item) }
1029
- Ok ( ( ) )
1030
- } else {
1031
- Err ( item)
1032
- }
1013
+ self . as_mut_view ( ) . push ( item)
1033
1014
}
1034
1015
1035
1016
/// Removes the last element from a vector and returns it
@@ -1038,10 +1019,7 @@ impl<T, const N: usize> Vec<T, N> {
1038
1019
///
1039
1020
/// This assumes the vec to have at least one element.
1040
1021
pub unsafe fn pop_unchecked ( & mut self ) -> T {
1041
- debug_assert ! ( !self . is_empty( ) ) ;
1042
-
1043
- self . len -= 1 ;
1044
- self . buffer . get_unchecked_mut ( self . len ) . as_ptr ( ) . read ( )
1022
+ self . as_mut_view ( ) . pop_unchecked ( )
1045
1023
}
1046
1024
1047
1025
/// Appends an `item` to the back of the collection
@@ -1050,36 +1028,12 @@ impl<T, const N: usize> Vec<T, N> {
1050
1028
///
1051
1029
/// This assumes the vec is not full.
1052
1030
pub unsafe fn push_unchecked ( & mut self , item : T ) {
1053
- // NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
1054
- // use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
1055
- debug_assert ! ( !self . is_full( ) ) ;
1056
-
1057
- * self . buffer . get_unchecked_mut ( self . len ) = MaybeUninit :: new ( item) ;
1058
-
1059
- self . len += 1 ;
1031
+ self . as_mut_view ( ) . push_unchecked ( item)
1060
1032
}
1061
1033
1062
1034
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
1063
1035
pub fn truncate ( & mut self , len : usize ) {
1064
- // This is safe because:
1065
- //
1066
- // * the slice passed to `drop_in_place` is valid; the `len > self.len`
1067
- // case avoids creating an invalid slice, and
1068
- // * the `len` of the vector is shrunk before calling `drop_in_place`,
1069
- // such that no value will be dropped twice in case `drop_in_place`
1070
- // were to panic once (if it panics twice, the program aborts).
1071
- unsafe {
1072
- // Note: It's intentional that this is `>` and not `>=`.
1073
- // Changing it to `>=` has negative performance
1074
- // implications in some cases. See rust-lang/rust#78884 for more.
1075
- if len > self . len {
1076
- return ;
1077
- }
1078
- let remaining_len = self . len - len;
1079
- let s = ptr:: slice_from_raw_parts_mut ( self . as_mut_ptr ( ) . add ( len) , remaining_len) ;
1080
- self . len = len;
1081
- ptr:: drop_in_place ( s) ;
1082
- }
1036
+ self . as_mut_view ( ) . truncate ( len)
1083
1037
}
1084
1038
1085
1039
/// Resizes the Vec in-place so that len is equal to new_len.
@@ -1094,19 +1048,7 @@ impl<T, const N: usize> Vec<T, N> {
1094
1048
where
1095
1049
T : Clone ,
1096
1050
{
1097
- if new_len > self . capacity ( ) {
1098
- return Err ( ( ) ) ;
1099
- }
1100
-
1101
- if new_len > self . len {
1102
- while self . len < new_len {
1103
- self . push ( value. clone ( ) ) . ok ( ) ;
1104
- }
1105
- } else {
1106
- self . truncate ( new_len) ;
1107
- }
1108
-
1109
- Ok ( ( ) )
1051
+ self . as_mut_view ( ) . resize ( new_len, value)
1110
1052
}
1111
1053
1112
1054
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
@@ -1121,7 +1063,7 @@ impl<T, const N: usize> Vec<T, N> {
1121
1063
where
1122
1064
T : Clone + Default ,
1123
1065
{
1124
- self . resize ( new_len , T :: default ( ) )
1066
+ self . as_mut_view ( ) . resize_default ( new_len )
1125
1067
}
1126
1068
1127
1069
/// Forces the length of the vector to `new_len`.
@@ -1248,8 +1190,7 @@ impl<T, const N: usize> Vec<T, N> {
1248
1190
/// assert_eq!(&*v, ["baz", "qux"]);
1249
1191
/// ```
1250
1192
pub fn swap_remove ( & mut self , index : usize ) -> T {
1251
- assert ! ( index < self . len) ;
1252
- unsafe { self . swap_remove_unchecked ( index) }
1193
+ self . as_mut_view ( ) . swap_remove ( index)
1253
1194
}
1254
1195
1255
1196
/// Removes an element from the vector and returns it.
@@ -1280,13 +1221,7 @@ impl<T, const N: usize> Vec<T, N> {
1280
1221
/// assert_eq!(&*v, ["baz", "qux"]);
1281
1222
/// ```
1282
1223
pub unsafe fn swap_remove_unchecked ( & mut self , index : usize ) -> T {
1283
- let length = self . len ( ) ;
1284
- debug_assert ! ( index < length) ;
1285
- let value = ptr:: read ( self . as_ptr ( ) . add ( index) ) ;
1286
- let base_ptr = self . as_mut_ptr ( ) ;
1287
- ptr:: copy ( base_ptr. add ( length - 1 ) , base_ptr. add ( index) , 1 ) ;
1288
- self . len -= 1 ;
1289
- value
1224
+ self . as_mut_view ( ) . swap_remove_unchecked ( index)
1290
1225
}
1291
1226
1292
1227
/// Returns true if the vec is full
@@ -1368,35 +1303,7 @@ impl<T, const N: usize> Vec<T, N> {
1368
1303
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
1369
1304
/// ```
1370
1305
pub fn insert ( & mut self , index : usize , element : T ) -> Result < ( ) , T > {
1371
- let len = self . len ( ) ;
1372
- if index > len {
1373
- panic ! (
1374
- "insertion index (is {}) should be <= len (is {})" ,
1375
- index, len
1376
- ) ;
1377
- }
1378
-
1379
- // check there's space for the new element
1380
- if self . is_full ( ) {
1381
- return Err ( element) ;
1382
- }
1383
-
1384
- unsafe {
1385
- // infallible
1386
- // The spot to put the new value
1387
- {
1388
- let p = self . as_mut_ptr ( ) . add ( index) ;
1389
- // Shift everything over to make space. (Duplicating the
1390
- // `index`th element into two consecutive places.)
1391
- ptr:: copy ( p, p. offset ( 1 ) , len - index) ;
1392
- // Write it in, overwriting the first copy of the `index`th
1393
- // element.
1394
- ptr:: write ( p, element) ;
1395
- }
1396
- self . set_len ( len + 1 ) ;
1397
- }
1398
-
1399
- Ok ( ( ) )
1306
+ self . as_mut_view ( ) . insert ( index, element)
1400
1307
}
1401
1308
1402
1309
/// Removes and returns the element at position `index` within the vector,
@@ -1425,26 +1332,7 @@ impl<T, const N: usize> Vec<T, N> {
1425
1332
/// assert_eq!(v, [1, 3]);
1426
1333
/// ```
1427
1334
pub fn remove ( & mut self , index : usize ) -> T {
1428
- let len = self . len ( ) ;
1429
- if index >= len {
1430
- panic ! ( "removal index (is {}) should be < len (is {})" , index, len) ;
1431
- }
1432
- unsafe {
1433
- // infallible
1434
- let ret;
1435
- {
1436
- // the place we are taking from.
1437
- let ptr = self . as_mut_ptr ( ) . add ( index) ;
1438
- // copy it out, unsafely having a copy of the value on
1439
- // the stack and in the vector at the same time.
1440
- ret = ptr:: read ( ptr) ;
1441
-
1442
- // Shift everything down to fill in that spot.
1443
- ptr:: copy ( ptr. offset ( 1 ) , ptr, len - index - 1 ) ;
1444
- }
1445
- self . set_len ( len - 1 ) ;
1446
- ret
1447
- }
1335
+ self . as_mut_view ( ) . remove ( index)
1448
1336
}
1449
1337
1450
1338
/// Retains only the elements specified by the predicate.
@@ -1475,11 +1363,11 @@ impl<T, const N: usize> Vec<T, N> {
1475
1363
/// vec.retain(|_| *iter.next().unwrap());
1476
1364
/// assert_eq!(vec, [2, 3, 5]);
1477
1365
/// ```
1478
- pub fn retain < F > ( & mut self , mut f : F )
1366
+ pub fn retain < F > ( & mut self , f : F )
1479
1367
where
1480
1368
F : FnMut ( & T ) -> bool ,
1481
1369
{
1482
- self . retain_mut ( |elem| f ( elem ) ) ;
1370
+ self . as_mut_view ( ) . retain ( f )
1483
1371
}
1484
1372
1485
1373
/// Retains only the elements specified by the predicate, passing a mutable reference to it.
@@ -1504,105 +1392,11 @@ impl<T, const N: usize> Vec<T, N> {
1504
1392
/// });
1505
1393
/// assert_eq!(vec, [2, 3, 4]);
1506
1394
/// ```
1507
- pub fn retain_mut < F > ( & mut self , mut f : F )
1395
+ pub fn retain_mut < F > ( & mut self , f : F )
1508
1396
where
1509
1397
F : FnMut ( & mut T ) -> bool ,
1510
1398
{
1511
- let original_len = self . len ( ) ;
1512
- // Avoid double drop if the drop guard is not executed,
1513
- // since we may make some holes during the process.
1514
- unsafe { self . set_len ( 0 ) } ;
1515
-
1516
- // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
1517
- // |<- processed len ->| ^- next to check
1518
- // |<- deleted cnt ->|
1519
- // |<- original_len ->|
1520
- // Kept: Elements which predicate returns true on.
1521
- // Hole: Moved or dropped element slot.
1522
- // Unchecked: Unchecked valid elements.
1523
- //
1524
- // This drop guard will be invoked when predicate or `drop` of element panicked.
1525
- // It shifts unchecked elements to cover holes and `set_len` to the correct length.
1526
- // In cases when predicate and `drop` never panick, it will be optimized out.
1527
- struct BackshiftOnDrop < ' a , T , const N : usize > {
1528
- v : & ' a mut Vec < T , N > ,
1529
- processed_len : usize ,
1530
- deleted_cnt : usize ,
1531
- original_len : usize ,
1532
- }
1533
-
1534
- impl < T , const N : usize > Drop for BackshiftOnDrop < ' _ , T , N > {
1535
- fn drop ( & mut self ) {
1536
- if self . deleted_cnt > 0 {
1537
- // SAFETY: Trailing unchecked items must be valid since we never touch them.
1538
- unsafe {
1539
- ptr:: copy (
1540
- self . v . as_ptr ( ) . add ( self . processed_len ) ,
1541
- self . v
1542
- . as_mut_ptr ( )
1543
- . add ( self . processed_len - self . deleted_cnt ) ,
1544
- self . original_len - self . processed_len ,
1545
- ) ;
1546
- }
1547
- }
1548
- // SAFETY: After filling holes, all items are in contiguous memory.
1549
- unsafe {
1550
- self . v . set_len ( self . original_len - self . deleted_cnt ) ;
1551
- }
1552
- }
1553
- }
1554
-
1555
- let mut g = BackshiftOnDrop {
1556
- v : self ,
1557
- processed_len : 0 ,
1558
- deleted_cnt : 0 ,
1559
- original_len,
1560
- } ;
1561
-
1562
- fn process_loop < F , T , const N : usize , const DELETED : bool > (
1563
- original_len : usize ,
1564
- f : & mut F ,
1565
- g : & mut BackshiftOnDrop < ' _ , T , N > ,
1566
- ) where
1567
- F : FnMut ( & mut T ) -> bool ,
1568
- {
1569
- while g. processed_len != original_len {
1570
- let p = g. v . as_mut_ptr ( ) ;
1571
- // SAFETY: Unchecked element must be valid.
1572
- let cur = unsafe { & mut * p. add ( g. processed_len ) } ;
1573
- if !f ( cur) {
1574
- // Advance early to avoid double drop if `drop_in_place` panicked.
1575
- g. processed_len += 1 ;
1576
- g. deleted_cnt += 1 ;
1577
- // SAFETY: We never touch this element again after dropped.
1578
- unsafe { ptr:: drop_in_place ( cur) } ;
1579
- // We already advanced the counter.
1580
- if DELETED {
1581
- continue ;
1582
- } else {
1583
- break ;
1584
- }
1585
- }
1586
- if DELETED {
1587
- // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1588
- // We use copy for move, and never touch this element again.
1589
- unsafe {
1590
- let hole_slot = p. add ( g. processed_len - g. deleted_cnt ) ;
1591
- ptr:: copy_nonoverlapping ( cur, hole_slot, 1 ) ;
1592
- }
1593
- }
1594
- g. processed_len += 1 ;
1595
- }
1596
- }
1597
-
1598
- // Stage 1: Nothing was deleted.
1599
- process_loop :: < F , T , N , false > ( original_len, & mut f, & mut g) ;
1600
-
1601
- // Stage 2: Some elements were deleted.
1602
- process_loop :: < F , T , N , true > ( original_len, & mut f, & mut g) ;
1603
-
1604
- // All item are processed. This can be optimized to `set_len` by LLVM.
1605
- drop ( g) ;
1399
+ self . as_mut_view ( ) . retain_mut ( f)
1606
1400
}
1607
1401
1608
1402
/// Returns the remaining spare capacity of the vector as a slice of `MaybeUninit<T>`.
0 commit comments