@@ -1421,6 +1421,53 @@ impl<T> ThinVec<T> {
14211421 }
14221422 }
14231423
1424+ /// Creates a splicing iterator that replaces the specified range in the vector
1425+ /// with the given `replace_with` iterator and yields the removed items.
1426+ /// `replace_with` does not need to be the same length as `range`.
1427+ ///
1428+ /// `range` is removed even if the iterator is not consumed until the end.
1429+ ///
1430+ /// It is unspecified how many elements are removed from the vector
1431+ /// if the `Splice` value is leaked.
1432+ ///
1433+ /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
1434+ ///
1435+ /// This is optimal if:
1436+ ///
1437+ /// * The tail (elements in the vector after `range`) is empty,
1438+ /// * or `replace_with` yields fewer or equal elements than `range`’s length
1439+ /// * or the lower bound of its `size_hint()` is exact.
1440+ ///
1441+ /// Otherwise, a temporary vector is allocated and the tail is moved twice.
1442+ ///
1443+ /// # Panics
1444+ ///
1445+ /// Panics if the starting point is greater than the end point or if
1446+ /// the end point is greater than the length of the vector.
1447+ ///
1448+ /// # Examples
1449+ ///
1450+ /// ```
1451+ /// use thin_vec::{ThinVec, thin_vec};
1452+ ///
1453+ /// let mut v = thin_vec![1, 2, 3, 4];
1454+ /// let new = [7, 8, 9];
1455+ /// let u: ThinVec<_> = v.splice(1..3, new).collect();
1456+ /// assert_eq!(v, &[1, 7, 8, 9, 4]);
1457+ /// assert_eq!(u, &[2, 3]);
1458+ /// ```
1459+ #[ inline]
1460+ pub fn splice < R , I > ( & mut self , range : R , replace_with : I ) -> Splice < ' _ , I :: IntoIter >
1461+ where
1462+ R : RangeBounds < usize > ,
1463+ I : IntoIterator < Item = T > ,
1464+ {
1465+ Splice {
1466+ drain : self . drain ( range) ,
1467+ replace_with : replace_with. into_iter ( ) ,
1468+ }
1469+ }
1470+
14241471 /// Resize the buffer and update its capacity, without changing the length.
14251472 /// Unsafe because it can cause length to be greater than capacity.
14261473 unsafe fn reallocate ( & mut self , new_cap : usize ) {
@@ -2397,6 +2444,133 @@ impl<'a, T> AsRef<[T]> for Drain<'a, T> {
23972444 }
23982445}
23992446
2447+ /// A splicing iterator for `ThinVec`.
2448+ ///
2449+ /// This struct is created by [`ThinVec::splice`][].
2450+ /// See its documentation for more.
2451+ ///
2452+ /// # Example
2453+ ///
2454+ /// ```
2455+ /// use thin_vec::thin_vec;
2456+ ///
2457+ /// let mut v = thin_vec![0, 1, 2];
2458+ /// let new = [7, 8];
2459+ /// let iter: thin_vec::Splice<_> = v.splice(1.., new);
2460+ /// ```
2461+ #[ derive( Debug ) ]
2462+ pub struct Splice < ' a , I : Iterator + ' a > {
2463+ drain : Drain < ' a , I :: Item > ,
2464+ replace_with : I ,
2465+ }
2466+
2467+ impl < I : Iterator > Iterator for Splice < ' _ , I > {
2468+ type Item = I :: Item ;
2469+
2470+ fn next ( & mut self ) -> Option < Self :: Item > {
2471+ self . drain . next ( )
2472+ }
2473+
2474+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2475+ self . drain . size_hint ( )
2476+ }
2477+ }
2478+
2479+ impl < I : Iterator > DoubleEndedIterator for Splice < ' _ , I > {
2480+ fn next_back ( & mut self ) -> Option < Self :: Item > {
2481+ self . drain . next_back ( )
2482+ }
2483+ }
2484+
2485+ impl < I : Iterator > ExactSizeIterator for Splice < ' _ , I > { }
2486+
2487+ impl < I : Iterator > Drop for Splice < ' _ , I > {
2488+ fn drop ( & mut self ) {
2489+ // Ensure we've fully drained out the range
2490+ self . drain . by_ref ( ) . for_each ( drop) ;
2491+
2492+ unsafe {
2493+ // If there's no tail elements, then the inner ThinVec is already
2494+ // correct and we can just extend it like normal.
2495+ if self . drain . tail == 0 {
2496+ ( * self . drain . vec ) . extend ( self . replace_with . by_ref ( ) ) ;
2497+ return ;
2498+ }
2499+
2500+ // First fill the range left by drain().
2501+ if !self . drain . fill ( & mut self . replace_with ) {
2502+ return ;
2503+ }
2504+
2505+ // There may be more elements. Use the lower bound as an estimate.
2506+ let ( lower_bound, _upper_bound) = self . replace_with . size_hint ( ) ;
2507+ if lower_bound > 0 {
2508+ self . drain . move_tail ( lower_bound) ;
2509+ if !self . drain . fill ( & mut self . replace_with ) {
2510+ return ;
2511+ }
2512+ }
2513+
2514+ // Collect any remaining elements.
2515+ // This is a zero-length vector which does not allocate if `lower_bound` was exact.
2516+ let mut collected = self
2517+ . replace_with
2518+ . by_ref ( )
2519+ . collect :: < Vec < I :: Item > > ( )
2520+ . into_iter ( ) ;
2521+ // Now we have an exact count.
2522+ if collected. len ( ) > 0 {
2523+ self . drain . move_tail ( collected. len ( ) ) ;
2524+ let filled = self . drain . fill ( & mut collected) ;
2525+ debug_assert ! ( filled) ;
2526+ debug_assert_eq ! ( collected. len( ) , 0 ) ;
2527+ }
2528+ }
2529+ // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
2530+ }
2531+ }
2532+
2533+ /// Private helper methods for `Splice::drop`
2534+ impl < T > Drain < ' _ , T > {
2535+ /// The range from `self.vec.len` to `self.tail_start` contains elements
2536+ /// that have been moved out.
2537+ /// Fill that range as much as possible with new elements from the `replace_with` iterator.
2538+ /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
2539+ unsafe fn fill < I : Iterator < Item = T > > ( & mut self , replace_with : & mut I ) -> bool {
2540+ let vec = unsafe { & mut * self . vec } ;
2541+ let range_start = vec. len ( ) ;
2542+ let range_end = self . end ;
2543+ let range_slice = unsafe {
2544+ slice:: from_raw_parts_mut ( vec. data_raw ( ) . add ( range_start) , range_end - range_start)
2545+ } ;
2546+
2547+ for place in range_slice {
2548+ if let Some ( new_item) = replace_with. next ( ) {
2549+ unsafe { ptr:: write ( place, new_item) } ;
2550+ vec. set_len ( vec. len ( ) + 1 ) ;
2551+ } else {
2552+ return false ;
2553+ }
2554+ }
2555+ true
2556+ }
2557+
2558+ /// Makes room for inserting more elements before the tail.
2559+ unsafe fn move_tail ( & mut self , additional : usize ) {
2560+ let vec = unsafe { & mut * self . vec } ;
2561+ let len = self . end + self . tail ;
2562+ vec. reserve ( len. checked_add ( additional) . expect ( "capacity overflow" ) ) ;
2563+
2564+ let new_tail_start = self . end + additional;
2565+ unsafe {
2566+ let src = vec. data_raw ( ) . add ( self . end ) ;
2567+ let dst = vec. data_raw ( ) . add ( new_tail_start) ;
2568+ ptr:: copy ( src, dst, self . tail ) ;
2569+ }
2570+ self . end = new_tail_start;
2571+ }
2572+ }
2573+
24002574/// Write is implemented for `ThinVec<u8>` by appending to the vector.
24012575/// The vector will grow as needed.
24022576/// This implementation is identical to the one for `Vec<u8>`.
@@ -2633,6 +2807,19 @@ mod tests {
26332807 assert_eq ! ( & v[ ..] , & [ ] ) ;
26342808 }
26352809
2810+ {
2811+ let mut v = ThinVec :: < i32 > :: new ( ) ;
2812+ assert_eq ! ( v. splice( .., [ ] ) . len( ) , 0 ) ;
2813+
2814+ for _ in v. splice ( .., [ ] ) {
2815+ unreachable ! ( )
2816+ }
2817+
2818+ assert_eq ! ( v. len( ) , 0 ) ;
2819+ assert_eq ! ( v. capacity( ) , 0 ) ;
2820+ assert_eq ! ( & v[ ..] , & [ ] ) ;
2821+ }
2822+
26362823 {
26372824 let mut v = ThinVec :: < i32 > :: new ( ) ;
26382825 v. truncate ( 1 ) ;
@@ -3387,70 +3574,76 @@ mod std_tests {
33873574 v. drain ( 5 ..=5 ) ;
33883575 }
33893576
3390- /* TODO: implement splice?
3391- #[test]
3392- fn test_splice() {
3393- let mut v = thin_vec![1, 2, 3, 4, 5];
3394- let a = [10, 11, 12];
3395- v.splice(2..4, a.iter().cloned());
3396- assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
3397- v.splice(1..3, Some(20));
3398- assert_eq!(v, &[1, 20, 11, 12, 5]);
3399- }
3577+ #[ test]
3578+ fn test_splice ( ) {
3579+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3580+ let a = [ 10 , 11 , 12 ] ;
3581+ v. splice ( 2 ..4 , a. iter ( ) . cloned ( ) ) ;
3582+ assert_eq ! ( v, & [ 1 , 2 , 10 , 11 , 12 , 5 ] ) ;
3583+ v. splice ( 1 ..3 , Some ( 20 ) ) ;
3584+ assert_eq ! ( v, & [ 1 , 20 , 11 , 12 , 5 ] ) ;
3585+ }
34003586
3401- #[test]
3402- fn test_splice_inclusive_range() {
3403- let mut v = thin_vec![1, 2, 3, 4, 5];
3404- let a = [10, 11, 12];
3405- let t1: ThinVec<_> = v.splice(2..=3, a.iter().cloned()).collect();
3406- assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
3407- assert_eq!(t1, &[3, 4]);
3408- let t2: ThinVec<_> = v.splice(1..=2, Some(20)).collect();
3409- assert_eq!(v, &[1, 20, 11, 12, 5]);
3410- assert_eq!(t2, &[2, 10]);
3411- }
3587+ #[ test]
3588+ fn test_splice_inclusive_range ( ) {
3589+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3590+ let a = [ 10 , 11 , 12 ] ;
3591+ let t1: ThinVec < _ > = v. splice ( 2 ..=3 , a. iter ( ) . cloned ( ) ) . collect ( ) ;
3592+ assert_eq ! ( v, & [ 1 , 2 , 10 , 11 , 12 , 5 ] ) ;
3593+ assert_eq ! ( t1, & [ 3 , 4 ] ) ;
3594+ let t2: ThinVec < _ > = v. splice ( 1 ..=2 , Some ( 20 ) ) . collect ( ) ;
3595+ assert_eq ! ( v, & [ 1 , 20 , 11 , 12 , 5 ] ) ;
3596+ assert_eq ! ( t2, & [ 2 , 10 ] ) ;
3597+ }
34123598
3413- #[test]
3414- #[should_panic]
3415- fn test_splice_out_of_bounds() {
3416- let mut v = thin_vec![1, 2, 3, 4, 5];
3417- let a = [10, 11, 12];
3418- v.splice(5..6, a.iter().cloned());
3419- }
3599+ #[ test]
3600+ #[ should_panic]
3601+ fn test_splice_out_of_bounds ( ) {
3602+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3603+ let a = [ 10 , 11 , 12 ] ;
3604+ v. splice ( 5 ..6 , a. iter ( ) . cloned ( ) ) ;
3605+ }
34203606
3421- #[test]
3422- #[should_panic]
3423- fn test_splice_inclusive_out_of_bounds() {
3424- let mut v = thin_vec![1, 2, 3, 4, 5];
3425- let a = [10, 11, 12];
3426- v.splice(5..=5, a.iter().cloned());
3427- }
3607+ #[ test]
3608+ #[ should_panic]
3609+ fn test_splice_inclusive_out_of_bounds ( ) {
3610+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3611+ let a = [ 10 , 11 , 12 ] ;
3612+ v. splice ( 5 ..=5 , a. iter ( ) . cloned ( ) ) ;
3613+ }
34283614
3429- #[test]
3430- fn test_splice_items_zero_sized() {
3431- let mut vec = thin_vec![(), (), ()];
3432- let vec2 = thin_vec![];
3433- let t: ThinVec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
3434- assert_eq!(vec, &[(), ()]);
3435- assert_eq!(t, &[()]);
3436- }
3615+ #[ test]
3616+ fn test_splice_items_zero_sized ( ) {
3617+ let mut vec = thin_vec ! [ ( ) , ( ) , ( ) ] ;
3618+ let vec2 = thin_vec ! [ ] ;
3619+ let t: ThinVec < _ > = vec. splice ( 1 ..2 , vec2. iter ( ) . cloned ( ) ) . collect ( ) ;
3620+ assert_eq ! ( vec, & [ ( ) , ( ) ] ) ;
3621+ assert_eq ! ( t, & [ ( ) ] ) ;
3622+ }
34373623
3438- #[test]
3439- fn test_splice_unbounded() {
3440- let mut vec = thin_vec![1, 2, 3, 4, 5];
3441- let t: ThinVec<_> = vec.splice(.., None).collect();
3442- assert_eq!(vec, &[]);
3443- assert_eq!(t, &[1, 2, 3, 4, 5]);
3444- }
3624+ #[ test]
3625+ fn test_splice_unbounded ( ) {
3626+ let mut vec = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3627+ let t: ThinVec < _ > = vec. splice ( .., None ) . collect ( ) ;
3628+ assert_eq ! ( vec, & [ ] ) ;
3629+ assert_eq ! ( t, & [ 1 , 2 , 3 , 4 , 5 ] ) ;
3630+ }
34453631
3446- #[test]
3447- fn test_splice_forget() {
3448- let mut v = thin_vec![1, 2, 3, 4, 5];
3449- let a = [10, 11, 12];
3450- ::std::mem::forget(v.splice(2..4, a.iter().cloned()));
3451- assert_eq!(v, &[1, 2]);
3452- }
3453- */
3632+ #[ test]
3633+ fn test_splice_forget ( ) {
3634+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3635+ let a = [ 10 , 11 , 12 ] ;
3636+ :: std:: mem:: forget ( v. splice ( 2 ..4 , a. iter ( ) . cloned ( ) ) ) ;
3637+ assert_eq ! ( v, & [ 1 , 2 ] ) ;
3638+ }
3639+
3640+ #[ test]
3641+ fn test_splice_from_empty ( ) {
3642+ let mut v = thin_vec ! [ ] ;
3643+ let a = [ 10 , 11 , 12 ] ;
3644+ v. splice ( .., a. iter ( ) . cloned ( ) ) ;
3645+ assert_eq ! ( v, & [ 10 , 11 , 12 ] ) ;
3646+ }
34543647
34553648 /* probs won't ever impl this
34563649 #[test]
0 commit comments