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