@@ -960,6 +960,57 @@ 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+ unsafe {
995+ let remove_at = self . as_mut_ptr ( ) . add ( remove_index) ;
996+ let insert_at = self . as_mut_ptr ( ) . add ( insert_index) ;
997+
998+ let to_remove = ptr:: read ( remove_at) ;
999+
1000+ match remove_index. cmp ( & insert_index) {
1001+ Ordering :: Equal => ( ) ,
1002+ Ordering :: Less => {
1003+ ptr:: copy ( remove_at. add ( 1 ) , remove_at, insert_index - remove_index) ;
1004+ }
1005+ Ordering :: Greater => {
1006+ ptr:: copy ( insert_at, insert_at. add ( 1 ) , remove_index - insert_index) ;
1007+ }
1008+ }
1009+ ptr:: write ( insert_at, element) ;
1010+ to_remove
1011+ }
1012+ }
1013+
9631014 /// Returns true if the vec is full
9641015 pub fn is_full ( & self ) -> bool {
9651016 self . len ( ) == self . capacity ( )
@@ -2119,6 +2170,92 @@ mod tests {
21192170 assert_eq ! ( v. len( ) , 0 ) ;
21202171 }
21212172
2173+ #[ test]
2174+ fn remove_insert ( ) {
2175+ let arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
2176+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2177+ let mut v2: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2178+
2179+ // insert_index == remove_index
2180+ let n = v. remove_insert ( 2 , 2 , 10 ) ;
2181+ assert_eq ! ( n, 2 ) ;
2182+ assert_eq ! ( v, [ 0 , 1 , 10 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ) ;
2183+
2184+ let n2 = v2. remove ( 2 ) ;
2185+ v2. insert ( 2 , 10 ) . unwrap ( ) ;
2186+ assert_eq ! ( n, n2) ;
2187+ assert_eq ! ( v, v2) ;
2188+
2189+ // reset
2190+ v. copy_from_slice ( & arr) ;
2191+ v2. copy_from_slice ( & arr) ;
2192+
2193+ // insert_index > remove_index
2194+ let n = v. remove_insert ( 3 , 5 , 10 ) ;
2195+ assert_eq ! ( n, 3 ) ;
2196+ assert_eq ! ( v, [ 0 , 1 , 2 , 4 , 5 , 10 , 6 , 7 , 8 , 9 ] ) ;
2197+
2198+ let n2 = v2. remove ( 3 ) ;
2199+ v2. insert ( 5 , 10 ) . unwrap ( ) ;
2200+ assert_eq ! ( n, n2) ;
2201+ assert_eq ! ( v, v2) ;
2202+
2203+ v. copy_from_slice ( & arr) ;
2204+ v2. copy_from_slice ( & arr) ;
2205+
2206+ // insert_index < remove_index
2207+ let n = v. remove_insert ( 5 , 3 , 10 ) ;
2208+ assert_eq ! ( n, 5 ) ;
2209+ assert_eq ! ( v, [ 0 , 1 , 2 , 10 , 3 , 4 , 6 , 7 , 8 , 9 ] ) ;
2210+
2211+ let n2 = v2. remove ( 5 ) ;
2212+ v2. insert ( 3 , 10 ) . unwrap ( ) ;
2213+
2214+ assert_eq ! ( n, n2) ;
2215+ assert_eq ! ( v, v2) ;
2216+
2217+ // at boundaries
2218+
2219+ v. copy_from_slice ( & arr) ;
2220+ v2. copy_from_slice ( & arr) ;
2221+
2222+ let n = v. remove_insert ( 0 , 9 , 10 ) ;
2223+ assert_eq ! ( n, 0 ) ;
2224+ assert_eq ! ( v, [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ) ;
2225+
2226+ let n2 = v2. remove ( 0 ) ;
2227+ v2. insert ( 9 , 10 ) . unwrap ( ) ;
2228+ assert_eq ! ( n, n2) ;
2229+ assert_eq ! ( v, v2) ;
2230+
2231+ v. copy_from_slice ( & arr) ;
2232+ v2. copy_from_slice ( & arr) ;
2233+
2234+ let n = v. remove_insert ( 9 , 0 , 10 ) ;
2235+ assert_eq ! ( n, 9 ) ;
2236+ assert_eq ! ( v, [ 10 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ;
2237+
2238+ let n2 = v2. remove ( 9 ) ;
2239+ v2. insert ( 0 , 10 ) . unwrap ( ) ;
2240+ assert_eq ! ( n, n2) ;
2241+ assert_eq ! ( v, v2) ;
2242+ }
2243+
2244+ #[ test]
2245+ #[ should_panic]
2246+ fn remove_insert_out_of_bounds ( ) {
2247+ let arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ;
2248+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( arr) ;
2249+ let _ = v. remove_insert ( 0 , 10 , 10 ) ;
2250+ }
2251+
2252+ #[ test]
2253+ #[ should_panic]
2254+ fn remove_insert_empty ( ) {
2255+ let mut v: Vec < u8 , 10 > = Vec :: from_array ( [ ] ) ;
2256+ let _ = v. remove_insert ( 0 , 0 , 10 ) ;
2257+ }
2258+
21222259 #[ test]
21232260 fn resize_size_limit ( ) {
21242261 let mut v: Vec < u8 , 4 > = Vec :: new ( ) ;
0 commit comments