@@ -960,6 +960,89 @@ impl<T, LenT: LenType, S: VecStorage<T> + ?Sized> VecInner<T, LenT, S> {
960960 value
961961 }
962962
963+ /// This is the same as calling [`Vec::remove`] with `remove_index`
964+ /// followed by calling [`Vec::insert`] with `insert_index` and `element`.
965+ ///
966+ /// The returned value is the removed element.
967+ ///
968+ /// This is more efficient than removing then inserting since it only shifts
969+ /// `remove_index.abs_diff(insert_index)` values.
970+ ///
971+ /// [`remove`]: Vec::remove
972+ /// [`insert`]: Vec::insert
973+ ///
974+ /// # Panics
975+ ///
976+ /// Panics if `remove_index` or `insert_index` are out of bounds.
977+ ///
978+ /// # Examples
979+ ///
980+ /// ```
981+ /// use heapless::Vec;
982+ ///
983+ /// let mut v: Vec<_, 8> = Vec::from_slice(&[0, 1, 2, 3]).unwrap();
984+ /// assert_eq!(v.remove_insert(1, 2, 4), 1);
985+ /// // only one element (2) is shifted back
986+ /// assert_eq!(v, [0, 2, 4, 3]);
987+ /// ```
988+ pub fn remove_insert ( & mut self , remove_index : usize , insert_index : usize , element : T ) -> T {
989+ let length = self . len ( ) ;
990+
991+ assert ! ( remove_index < length) ;
992+ assert ! ( insert_index < length) ;
993+
994+ // SAFETY: `remove_index < length` assertion guarantees the pointer is within bounds.
995+ let to_remove = unsafe { ptr:: read ( self . as_ptr ( ) . add ( remove_index) ) } ;
996+
997+ match remove_index. cmp ( & insert_index) {
998+ Ordering :: Equal => ( ) ,
999+ Ordering :: Less => {
1000+ // SAFETY: `remove_index < length` assertion guarantees the pointer is within
1001+ // bounds.
1002+ let remove_at = unsafe { self . as_mut_ptr ( ) . add ( remove_index) } ;
1003+
1004+ // SAFETY:
1005+ // Copies from
1006+ // (remove_index + 1)..(insert_index + 1)
1007+ // to
1008+ // remove_index..insert_index
1009+ //
1010+ // remove_index < insert_index (this match)
1011+ // remove_index + 1 < insert_index + 1 (can't saturate because <= length)
1012+ // remove_index + 1 <= insert_index < length
1013+ // insert_index + 1 <= length
1014+ //
1015+ // If `remove_index == 0`, and `insert_index + 1 == length`, then we copy from
1016+ // 1..length to 0..(length-1).
1017+ unsafe { ptr:: copy ( remove_at. add ( 1 ) , remove_at, insert_index - remove_index) } ;
1018+ }
1019+ Ordering :: Greater => {
1020+ // SAFETY: `insert_index < length` assertion guarantees the pointer is within
1021+ // bounds.
1022+ let insert_at = unsafe { self . as_mut_ptr ( ) . add ( insert_index) } ;
1023+
1024+ // SAFETY:
1025+ // Copies from
1026+ // insert_index..remove_index
1027+ // to
1028+ // (insert_index + 1)..(remove_index + 1)
1029+ //
1030+ // insert_index < remove_index (this match)
1031+ // insert_index + 1 < remove_index + 1 (can't saturate because <= length)
1032+ // insert_index + 1 <= remove_index < length
1033+ // remove_index + 1 <= length
1034+ //
1035+ // If `insert_index == 0`, and `remove_index + 1 == length`, then we copy from
1036+ // 0..(length-1) to 1..(length).
1037+ unsafe { ptr:: copy ( insert_at, insert_at. add ( 1 ) , remove_index - insert_index) } ;
1038+ }
1039+ }
1040+
1041+ // SAFETY: `insert_index < length` assertion guarantees the pointer is within bounds.
1042+ unsafe { ptr:: write ( self . as_mut_ptr ( ) . add ( insert_index) , element) } ;
1043+ to_remove
1044+ }
1045+
9631046 /// Returns true if the vec is full
9641047 pub fn is_full ( & self ) -> bool {
9651048 self . len ( ) == self . capacity ( )
@@ -2119,6 +2202,92 @@ mod tests {
21192202 assert_eq ! ( v. len( ) , 0 ) ;
21202203 }
21212204
2205+ #[ test]
2206+ fn remove_insert ( ) {
2207+ let arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
2208+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2209+ let mut v2: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2210+
2211+ // insert_index == remove_index
2212+ let n = v. remove_insert ( 2 , 2 , 10 ) ;
2213+ assert_eq ! ( n, 2 ) ;
2214+ assert_eq ! ( v, [ 0 , 1 , 10 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ) ;
2215+
2216+ let n2 = v2. remove ( 2 ) ;
2217+ v2. insert ( 2 , 10 ) . unwrap ( ) ;
2218+ assert_eq ! ( n, n2) ;
2219+ assert_eq ! ( v, v2) ;
2220+
2221+ // reset
2222+ v. copy_from_slice ( & arr) ;
2223+ v2. copy_from_slice ( & arr) ;
2224+
2225+ // insert_index > remove_index
2226+ let n = v. remove_insert ( 3 , 5 , 10 ) ;
2227+ assert_eq ! ( n, 3 ) ;
2228+ assert_eq ! ( v, [ 0 , 1 , 2 , 4 , 5 , 10 , 6 , 7 , 8 , 9 ] ) ;
2229+
2230+ let n2 = v2. remove ( 3 ) ;
2231+ v2. insert ( 5 , 10 ) . unwrap ( ) ;
2232+ assert_eq ! ( n, n2) ;
2233+ assert_eq ! ( v, v2) ;
2234+
2235+ v. copy_from_slice ( & arr) ;
2236+ v2. copy_from_slice ( & arr) ;
2237+
2238+ // insert_index < remove_index
2239+ let n = v. remove_insert ( 5 , 3 , 10 ) ;
2240+ assert_eq ! ( n, 5 ) ;
2241+ assert_eq ! ( v, [ 0 , 1 , 2 , 10 , 3 , 4 , 6 , 7 , 8 , 9 ] ) ;
2242+
2243+ let n2 = v2. remove ( 5 ) ;
2244+ v2. insert ( 3 , 10 ) . unwrap ( ) ;
2245+
2246+ assert_eq ! ( n, n2) ;
2247+ assert_eq ! ( v, v2) ;
2248+
2249+ // at boundaries
2250+
2251+ v. copy_from_slice ( & arr) ;
2252+ v2. copy_from_slice ( & arr) ;
2253+
2254+ let n = v. remove_insert ( 0 , 9 , 10 ) ;
2255+ assert_eq ! ( n, 0 ) ;
2256+ assert_eq ! ( v, [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ) ;
2257+
2258+ let n2 = v2. remove ( 0 ) ;
2259+ v2. insert ( 9 , 10 ) . unwrap ( ) ;
2260+ assert_eq ! ( n, n2) ;
2261+ assert_eq ! ( v, v2) ;
2262+
2263+ v. copy_from_slice ( & arr) ;
2264+ v2. copy_from_slice ( & arr) ;
2265+
2266+ let n = v. remove_insert ( 9 , 0 , 10 ) ;
2267+ assert_eq ! ( n, 9 ) ;
2268+ assert_eq ! ( v, [ 10 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ;
2269+
2270+ let n2 = v2. remove ( 9 ) ;
2271+ v2. insert ( 0 , 10 ) . unwrap ( ) ;
2272+ assert_eq ! ( n, n2) ;
2273+ assert_eq ! ( v, v2) ;
2274+ }
2275+
2276+ #[ test]
2277+ #[ should_panic]
2278+ fn remove_insert_out_of_bounds ( ) {
2279+ let arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
2280+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2281+ let _ = v. remove_insert ( 0 , 10 , 10 ) ;
2282+ }
2283+
2284+ #[ test]
2285+ #[ should_panic]
2286+ fn remove_insert_empty ( ) {
2287+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( [ ] ) ;
2288+ let _ = v. remove_insert ( 0 , 0 , 10 ) ;
2289+ }
2290+
21222291 #[ test]
21232292 fn resize_size_limit ( ) {
21242293 let mut v: Vec < u8 , 4 > = Vec :: new ( ) ;
0 commit comments