@@ -952,38 +952,19 @@ impl<T, const N: usize> Vec<T, N> {
952952 where
953953 T : Clone ,
954954 {
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)
966956 }
967957
968958 /// Removes the last element from a vector and returns it, or `None` if it's empty
969959 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 ( )
975961 }
976962
977963 /// Appends an `item` to the back of the collection
978964 ///
979965 /// Returns back the `item` if the vector is full
980966 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)
987968 }
988969
989970 /// Removes the last element from a vector and returns it
@@ -992,10 +973,7 @@ impl<T, const N: usize> Vec<T, N> {
992973 ///
993974 /// This assumes the vec to have at least one element.
994975 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 ( )
999977 }
1000978
1001979 /// Appends an `item` to the back of the collection
@@ -1004,36 +982,12 @@ impl<T, const N: usize> Vec<T, N> {
1004982 ///
1005983 /// This assumes the vec is not full.
1006984 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)
1014986 }
1015987
1016988 /// Shortens the vector, keeping the first `len` elements and dropping the rest.
1017989 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)
1037991 }
1038992
1039993 /// 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> {
10481002 where
10491003 T : Clone ,
10501004 {
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)
10641006 }
10651007
10661008 /// 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> {
10751017 where
10761018 T : Clone + Default ,
10771019 {
1078- self . resize ( new_len , T :: default ( ) )
1020+ self . as_mut_view ( ) . resize_default ( new_len )
10791021 }
10801022
10811023 /// Forces the length of the vector to `new_len`.
@@ -1202,8 +1144,7 @@ impl<T, const N: usize> Vec<T, N> {
12021144 /// assert_eq!(&*v, ["baz", "qux"]);
12031145 /// ```
12041146 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)
12071148 }
12081149
12091150 /// Removes an element from the vector and returns it.
@@ -1234,13 +1175,7 @@ impl<T, const N: usize> Vec<T, N> {
12341175 /// assert_eq!(&*v, ["baz", "qux"]);
12351176 /// ```
12361177 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)
12441179 }
12451180
12461181 /// Returns true if the vec is full
@@ -1322,35 +1257,7 @@ impl<T, const N: usize> Vec<T, N> {
13221257 /// assert_eq!(vec, [1, 4, 2, 3, 5]);
13231258 /// ```
13241259 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)
13541261 }
13551262
13561263 /// Removes and returns the element at position `index` within the vector,
@@ -1379,26 +1286,7 @@ impl<T, const N: usize> Vec<T, N> {
13791286 /// assert_eq!(v, [1, 3]);
13801287 /// ```
13811288 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)
14021290 }
14031291
14041292 /// Retains only the elements specified by the predicate.
@@ -1429,11 +1317,11 @@ impl<T, const N: usize> Vec<T, N> {
14291317 /// vec.retain(|_| *iter.next().unwrap());
14301318 /// assert_eq!(vec, [2, 3, 5]);
14311319 /// ```
1432- pub fn retain < F > ( & mut self , mut f : F )
1320+ pub fn retain < F > ( & mut self , f : F )
14331321 where
14341322 F : FnMut ( & T ) -> bool ,
14351323 {
1436- self . retain_mut ( |elem| f ( elem ) ) ;
1324+ self . as_mut_view ( ) . retain ( f )
14371325 }
14381326
14391327 /// 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> {
14581346 /// });
14591347 /// assert_eq!(vec, [2, 3, 4]);
14601348 /// ```
1461- pub fn retain_mut < F > ( & mut self , mut f : F )
1349+ pub fn retain_mut < F > ( & mut self , f : F )
14621350 where
14631351 F : FnMut ( & mut T ) -> bool ,
14641352 {
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)
15601354 }
15611355}
15621356
0 commit comments