@@ -1438,6 +1438,53 @@ impl<T> ThinVec<T> {
14381438 }
14391439 }
14401440
1441+ /// Creates a splicing iterator that replaces the specified range in the vector
1442+ /// with the given `replace_with` iterator and yields the removed items.
1443+ /// `replace_with` does not need to be the same length as `range`.
1444+ ///
1445+ /// `range` is removed even if the iterator is not consumed until the end.
1446+ ///
1447+ /// It is unspecified how many elements are removed from the vector
1448+ /// if the `Splice` value is leaked.
1449+ ///
1450+ /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
1451+ ///
1452+ /// This is optimal if:
1453+ ///
1454+ /// * The tail (elements in the vector after `range`) is empty,
1455+ /// * or `replace_with` yields fewer or equal elements than `range`’s length
1456+ /// * or the lower bound of its `size_hint()` is exact.
1457+ ///
1458+ /// Otherwise, a temporary vector is allocated and the tail is moved twice.
1459+ ///
1460+ /// # Panics
1461+ ///
1462+ /// Panics if the starting point is greater than the end point or if
1463+ /// the end point is greater than the length of the vector.
1464+ ///
1465+ /// # Examples
1466+ ///
1467+ /// ```
1468+ /// use thin_vec::{ThinVec, thin_vec};
1469+ ///
1470+ /// let mut v = thin_vec![1, 2, 3, 4];
1471+ /// let new = [7, 8, 9];
1472+ /// let u: ThinVec<_> = v.splice(1..3, new).collect();
1473+ /// assert_eq!(v, &[1, 7, 8, 9, 4]);
1474+ /// assert_eq!(u, &[2, 3]);
1475+ /// ```
1476+ #[ inline]
1477+ pub fn splice < R , I > ( & mut self , range : R , replace_with : I ) -> Splice < ' _ , I :: IntoIter >
1478+ where
1479+ R : RangeBounds < usize > ,
1480+ I : IntoIterator < Item = T > ,
1481+ {
1482+ Splice {
1483+ drain : self . drain ( range) ,
1484+ replace_with : replace_with. into_iter ( ) ,
1485+ }
1486+ }
1487+
14411488 /// Resize the buffer and update its capacity, without changing the length.
14421489 /// Unsafe because it can cause length to be greater than capacity.
14431490 unsafe fn reallocate ( & mut self , new_cap : usize ) {
@@ -2412,6 +2459,133 @@ impl<'a, T> AsRef<[T]> for Drain<'a, T> {
24122459 }
24132460}
24142461
2462+ /// A splicing iterator for `ThinVec`.
2463+ ///
2464+ /// This struct is created by [`ThinVec::splice`][].
2465+ /// See its documentation for more.
2466+ ///
2467+ /// # Example
2468+ ///
2469+ /// ```
2470+ /// use thin_vec::thin_vec;
2471+ ///
2472+ /// let mut v = thin_vec![0, 1, 2];
2473+ /// let new = [7, 8];
2474+ /// let iter: thin_vec::Splice<_> = v.splice(1.., new);
2475+ /// ```
2476+ #[ derive( Debug ) ]
2477+ pub struct Splice < ' a , I : Iterator + ' a > {
2478+ drain : Drain < ' a , I :: Item > ,
2479+ replace_with : I ,
2480+ }
2481+
2482+ impl < I : Iterator > Iterator for Splice < ' _ , I > {
2483+ type Item = I :: Item ;
2484+
2485+ fn next ( & mut self ) -> Option < Self :: Item > {
2486+ self . drain . next ( )
2487+ }
2488+
2489+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2490+ self . drain . size_hint ( )
2491+ }
2492+ }
2493+
2494+ impl < I : Iterator > DoubleEndedIterator for Splice < ' _ , I > {
2495+ fn next_back ( & mut self ) -> Option < Self :: Item > {
2496+ self . drain . next_back ( )
2497+ }
2498+ }
2499+
2500+ impl < I : Iterator > ExactSizeIterator for Splice < ' _ , I > { }
2501+
2502+ impl < I : Iterator > Drop for Splice < ' _ , I > {
2503+ fn drop ( & mut self ) {
2504+ // Ensure we've fully drained out the range
2505+ self . drain . by_ref ( ) . for_each ( drop) ;
2506+
2507+ unsafe {
2508+ // If there's no tail elements, then the inner ThinVec is already
2509+ // correct and we can just extend it like normal.
2510+ if self . drain . tail == 0 {
2511+ ( * self . drain . vec ) . extend ( self . replace_with . by_ref ( ) ) ;
2512+ return ;
2513+ }
2514+
2515+ // First fill the range left by drain().
2516+ if !self . drain . fill ( & mut self . replace_with ) {
2517+ return ;
2518+ }
2519+
2520+ // There may be more elements. Use the lower bound as an estimate.
2521+ let ( lower_bound, _upper_bound) = self . replace_with . size_hint ( ) ;
2522+ if lower_bound > 0 {
2523+ self . drain . move_tail ( lower_bound) ;
2524+ if !self . drain . fill ( & mut self . replace_with ) {
2525+ return ;
2526+ }
2527+ }
2528+
2529+ // Collect any remaining elements.
2530+ // This is a zero-length vector which does not allocate if `lower_bound` was exact.
2531+ let mut collected = self
2532+ . replace_with
2533+ . by_ref ( )
2534+ . collect :: < Vec < I :: Item > > ( )
2535+ . into_iter ( ) ;
2536+ // Now we have an exact count.
2537+ if collected. len ( ) > 0 {
2538+ self . drain . move_tail ( collected. len ( ) ) ;
2539+ let filled = self . drain . fill ( & mut collected) ;
2540+ debug_assert ! ( filled) ;
2541+ debug_assert_eq ! ( collected. len( ) , 0 ) ;
2542+ }
2543+ }
2544+ // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
2545+ }
2546+ }
2547+
2548+ /// Private helper methods for `Splice::drop`
2549+ impl < T > Drain < ' _ , T > {
2550+ /// The range from `self.vec.len` to `self.tail_start` contains elements
2551+ /// that have been moved out.
2552+ /// Fill that range as much as possible with new elements from the `replace_with` iterator.
2553+ /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
2554+ unsafe fn fill < I : Iterator < Item = T > > ( & mut self , replace_with : & mut I ) -> bool {
2555+ let vec = unsafe { & mut * self . vec } ;
2556+ let range_start = vec. len ( ) ;
2557+ let range_end = self . end ;
2558+ let range_slice = unsafe {
2559+ slice:: from_raw_parts_mut ( vec. data_raw ( ) . add ( range_start) , range_end - range_start)
2560+ } ;
2561+
2562+ for place in range_slice {
2563+ if let Some ( new_item) = replace_with. next ( ) {
2564+ unsafe { ptr:: write ( place, new_item) } ;
2565+ vec. set_len ( vec. len ( ) + 1 ) ;
2566+ } else {
2567+ return false ;
2568+ }
2569+ }
2570+ true
2571+ }
2572+
2573+ /// Makes room for inserting more elements before the tail.
2574+ unsafe fn move_tail ( & mut self , additional : usize ) {
2575+ let vec = unsafe { & mut * self . vec } ;
2576+ let len = self . end + self . tail ;
2577+ vec. reserve ( len. checked_add ( additional) . expect ( "capacity overflow" ) ) ;
2578+
2579+ let new_tail_start = self . end + additional;
2580+ unsafe {
2581+ let src = vec. data_raw ( ) . add ( self . end ) ;
2582+ let dst = vec. data_raw ( ) . add ( new_tail_start) ;
2583+ ptr:: copy ( src, dst, self . tail ) ;
2584+ }
2585+ self . end = new_tail_start;
2586+ }
2587+ }
2588+
24152589/// Write is implemented for `ThinVec<u8>` by appending to the vector.
24162590/// The vector will grow as needed.
24172591/// This implementation is identical to the one for `Vec<u8>`.
@@ -2648,6 +2822,19 @@ mod tests {
26482822 assert_eq ! ( & v[ ..] , & [ ] ) ;
26492823 }
26502824
2825+ {
2826+ let mut v = ThinVec :: < i32 > :: new ( ) ;
2827+ assert_eq ! ( v. splice( .., [ ] ) . len( ) , 0 ) ;
2828+
2829+ for _ in v. splice ( .., [ ] ) {
2830+ unreachable ! ( )
2831+ }
2832+
2833+ assert_eq ! ( v. len( ) , 0 ) ;
2834+ assert_eq ! ( v. capacity( ) , 0 ) ;
2835+ assert_eq ! ( & v[ ..] , & [ ] ) ;
2836+ }
2837+
26512838 {
26522839 let mut v = ThinVec :: < i32 > :: new ( ) ;
26532840 v. truncate ( 1 ) ;
@@ -3402,70 +3589,76 @@ mod std_tests {
34023589 v. drain ( 5 ..=5 ) ;
34033590 }
34043591
3405- /* TODO: implement splice?
3406- #[test]
3407- fn test_splice() {
3408- let mut v = thin_vec![1, 2, 3, 4, 5];
3409- let a = [10, 11, 12];
3410- v.splice(2..4, a.iter().cloned());
3411- assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
3412- v.splice(1..3, Some(20));
3413- assert_eq!(v, &[1, 20, 11, 12, 5]);
3414- }
3592+ #[ test]
3593+ fn test_splice ( ) {
3594+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3595+ let a = [ 10 , 11 , 12 ] ;
3596+ v. splice ( 2 ..4 , a. iter ( ) . cloned ( ) ) ;
3597+ assert_eq ! ( v, & [ 1 , 2 , 10 , 11 , 12 , 5 ] ) ;
3598+ v. splice ( 1 ..3 , Some ( 20 ) ) ;
3599+ assert_eq ! ( v, & [ 1 , 20 , 11 , 12 , 5 ] ) ;
3600+ }
34153601
3416- #[test]
3417- fn test_splice_inclusive_range() {
3418- let mut v = thin_vec![1, 2, 3, 4, 5];
3419- let a = [10, 11, 12];
3420- let t1: ThinVec<_> = v.splice(2..=3, a.iter().cloned()).collect();
3421- assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
3422- assert_eq!(t1, &[3, 4]);
3423- let t2: ThinVec<_> = v.splice(1..=2, Some(20)).collect();
3424- assert_eq!(v, &[1, 20, 11, 12, 5]);
3425- assert_eq!(t2, &[2, 10]);
3426- }
3602+ #[ test]
3603+ fn test_splice_inclusive_range ( ) {
3604+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3605+ let a = [ 10 , 11 , 12 ] ;
3606+ let t1: ThinVec < _ > = v. splice ( 2 ..=3 , a. iter ( ) . cloned ( ) ) . collect ( ) ;
3607+ assert_eq ! ( v, & [ 1 , 2 , 10 , 11 , 12 , 5 ] ) ;
3608+ assert_eq ! ( t1, & [ 3 , 4 ] ) ;
3609+ let t2: ThinVec < _ > = v. splice ( 1 ..=2 , Some ( 20 ) ) . collect ( ) ;
3610+ assert_eq ! ( v, & [ 1 , 20 , 11 , 12 , 5 ] ) ;
3611+ assert_eq ! ( t2, & [ 2 , 10 ] ) ;
3612+ }
34273613
3428- #[test]
3429- #[should_panic]
3430- fn test_splice_out_of_bounds() {
3431- let mut v = thin_vec![1, 2, 3, 4, 5];
3432- let a = [10, 11, 12];
3433- v.splice(5..6, a.iter().cloned());
3434- }
3614+ #[ test]
3615+ #[ should_panic]
3616+ fn test_splice_out_of_bounds ( ) {
3617+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3618+ let a = [ 10 , 11 , 12 ] ;
3619+ v. splice ( 5 ..6 , a. iter ( ) . cloned ( ) ) ;
3620+ }
34353621
3436- #[test]
3437- #[should_panic]
3438- fn test_splice_inclusive_out_of_bounds() {
3439- let mut v = thin_vec![1, 2, 3, 4, 5];
3440- let a = [10, 11, 12];
3441- v.splice(5..=5, a.iter().cloned());
3442- }
3622+ #[ test]
3623+ #[ should_panic]
3624+ fn test_splice_inclusive_out_of_bounds ( ) {
3625+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3626+ let a = [ 10 , 11 , 12 ] ;
3627+ v. splice ( 5 ..=5 , a. iter ( ) . cloned ( ) ) ;
3628+ }
34433629
3444- #[test]
3445- fn test_splice_items_zero_sized() {
3446- let mut vec = thin_vec![(), (), ()];
3447- let vec2 = thin_vec![];
3448- let t: ThinVec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
3449- assert_eq!(vec, &[(), ()]);
3450- assert_eq!(t, &[()]);
3451- }
3630+ #[ test]
3631+ fn test_splice_items_zero_sized ( ) {
3632+ let mut vec = thin_vec ! [ ( ) , ( ) , ( ) ] ;
3633+ let vec2 = thin_vec ! [ ] ;
3634+ let t: ThinVec < _ > = vec. splice ( 1 ..2 , vec2. iter ( ) . cloned ( ) ) . collect ( ) ;
3635+ assert_eq ! ( vec, & [ ( ) , ( ) ] ) ;
3636+ assert_eq ! ( t, & [ ( ) ] ) ;
3637+ }
34523638
3453- #[test]
3454- fn test_splice_unbounded() {
3455- let mut vec = thin_vec![1, 2, 3, 4, 5];
3456- let t: ThinVec<_> = vec.splice(.., None).collect();
3457- assert_eq!(vec, &[]);
3458- assert_eq!(t, &[1, 2, 3, 4, 5]);
3459- }
3639+ #[ test]
3640+ fn test_splice_unbounded ( ) {
3641+ let mut vec = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3642+ let t: ThinVec < _ > = vec. splice ( .., None ) . collect ( ) ;
3643+ assert_eq ! ( vec, & [ ] ) ;
3644+ assert_eq ! ( t, & [ 1 , 2 , 3 , 4 , 5 ] ) ;
3645+ }
34603646
3461- #[test]
3462- fn test_splice_forget() {
3463- let mut v = thin_vec![1, 2, 3, 4, 5];
3464- let a = [10, 11, 12];
3465- ::std::mem::forget(v.splice(2..4, a.iter().cloned()));
3466- assert_eq!(v, &[1, 2]);
3467- }
3468- */
3647+ #[ test]
3648+ fn test_splice_forget ( ) {
3649+ let mut v = thin_vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
3650+ let a = [ 10 , 11 , 12 ] ;
3651+ :: std:: mem:: forget ( v. splice ( 2 ..4 , a. iter ( ) . cloned ( ) ) ) ;
3652+ assert_eq ! ( v, & [ 1 , 2 ] ) ;
3653+ }
3654+
3655+ #[ test]
3656+ fn test_splice_from_empty ( ) {
3657+ let mut v = thin_vec ! [ ] ;
3658+ let a = [ 10 , 11 , 12 ] ;
3659+ v. splice ( .., a. iter ( ) . cloned ( ) ) ;
3660+ assert_eq ! ( v, & [ 10 , 11 , 12 ] ) ;
3661+ }
34693662
34703663 /* probs won't ever impl this
34713664 #[test]
0 commit comments