@@ -1057,7 +1057,7 @@ impl<T> Vec<T> {
1057
1057
self . len += count;
1058
1058
}
1059
1059
1060
- /// Create a draining iterator that removes the specified range in the vector
1060
+ /// Creates a draining iterator that removes the specified range in the vector
1061
1061
/// and yields the removed items.
1062
1062
///
1063
1063
/// Note 1: The element range is removed even if the iterator is only
@@ -1845,6 +1845,54 @@ impl<T> Vec<T> {
1845
1845
}
1846
1846
}
1847
1847
}
1848
+
1849
+ /// Creates a splicing iterator that replaces the specified range in the vector
1850
+ /// with the given `replace_with` iterator and yields the removed items.
1851
+ /// `replace_with` does not need to be the same length as `range`.
1852
+ ///
1853
+ /// Note 1: The element range is removed even if the iterator is not
1854
+ /// consumed until the end.
1855
+ ///
1856
+ /// Note 2: It is unspecified how many elements are removed from the vector,
1857
+ /// if the `Splice` value is leaked.
1858
+ ///
1859
+ /// Note 3: The input iterator `replace_with` is only consumed
1860
+ /// when the `Splice` value is dropped.
1861
+ ///
1862
+ /// Note 4: This is optimal if:
1863
+ ///
1864
+ /// * The tail (elements in the vector after `range`) is empty,
1865
+ /// * or `replace_with` yields fewer elements than `range`’s length
1866
+ /// * or the lower bound of its `size_hint()` is exact.
1867
+ ///
1868
+ /// Otherwise, a temporary vector is allocated and the tail is moved twice.
1869
+ ///
1870
+ /// # Panics
1871
+ ///
1872
+ /// Panics if the starting point is greater than the end point or if
1873
+ /// the end point is greater than the length of the vector.
1874
+ ///
1875
+ /// # Examples
1876
+ ///
1877
+ /// ```
1878
+ /// #![feature(splice)]
1879
+ /// let mut v = vec![1, 2, 3];
1880
+ /// let new = [7, 8];
1881
+ /// let u: Vec<_> = v.splice(..2, new.iter().cloned()).collect();
1882
+ /// assert_eq!(v, &[7, 8, 3]);
1883
+ /// assert_eq!(u, &[1, 2]);
1884
+ /// ```
1885
+ #[ inline]
1886
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1887
+ pub fn splice < R , I > ( & mut self , range : R , replace_with : I ) -> Splice < I :: IntoIter >
1888
+ where R : RangeArgument < usize > , I : IntoIterator < Item =T >
1889
+ {
1890
+ Splice {
1891
+ drain : self . drain ( range) ,
1892
+ replace_with : replace_with. into_iter ( ) ,
1893
+ }
1894
+ }
1895
+
1848
1896
}
1849
1897
1850
1898
#[ stable( feature = "extend_ref" , since = "1.2.0" ) ]
@@ -2344,3 +2392,118 @@ impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
2344
2392
& mut * ptr
2345
2393
}
2346
2394
}
2395
+
2396
+
2397
+ /// A splicing iterator for `Vec<T>`. See the [`Vec::splice`](struct.Vec.html#method.splice) method.
2398
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
2399
+ pub struct Splice < ' a , I : Iterator + ' a > {
2400
+ drain : Drain < ' a , I :: Item > ,
2401
+ replace_with : I ,
2402
+ }
2403
+
2404
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
2405
+ impl < ' a , I : Iterator > Iterator for Splice < ' a , I > {
2406
+ type Item = I :: Item ;
2407
+
2408
+ fn next ( & mut self ) -> Option < Self :: Item > {
2409
+ self . drain . next ( )
2410
+ }
2411
+
2412
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2413
+ self . drain . size_hint ( )
2414
+ }
2415
+ }
2416
+
2417
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
2418
+ impl < ' a , I : Iterator > DoubleEndedIterator for Splice < ' a , I > {
2419
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
2420
+ self . drain . next_back ( )
2421
+ }
2422
+ }
2423
+
2424
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
2425
+ impl < ' a , I : Iterator > ExactSizeIterator for Splice < ' a , I > { }
2426
+
2427
+
2428
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
2429
+ impl < ' a , I : Iterator > Drop for Splice < ' a , I > {
2430
+ fn drop ( & mut self ) {
2431
+ // exhaust drain first
2432
+ while let Some ( _) = self . drain . next ( ) { }
2433
+
2434
+
2435
+ unsafe {
2436
+ if self . drain . tail_len == 0 {
2437
+ let vec = & mut * self . drain . vec ;
2438
+ vec. extend ( self . replace_with . by_ref ( ) ) ;
2439
+ return
2440
+ }
2441
+
2442
+ // First fill the range left by drain().
2443
+ if !self . drain . fill ( & mut self . replace_with ) {
2444
+ return
2445
+ }
2446
+
2447
+ // There may be more elements. Use the lower bound as an estimate.
2448
+ // FIXME: Is the upper bound a better guess? Or something else?
2449
+ let ( lower_bound, _upper_bound) = self . replace_with . size_hint ( ) ;
2450
+ if lower_bound > 0 {
2451
+ self . drain . move_tail ( lower_bound) ;
2452
+ if !self . drain . fill ( & mut self . replace_with ) {
2453
+ return
2454
+ }
2455
+ }
2456
+
2457
+ // Collect any remaining elements.
2458
+ // This is a zero-length vector which does not allocate if `lower_bound` was exact.
2459
+ let mut collected = self . replace_with . by_ref ( ) . collect :: < Vec < I :: Item > > ( ) . into_iter ( ) ;
2460
+ // Now we have an exact count.
2461
+ if collected. len ( ) > 0 {
2462
+ self . drain . move_tail ( collected. len ( ) ) ;
2463
+ let filled = self . drain . fill ( & mut collected) ;
2464
+ debug_assert ! ( filled) ;
2465
+ debug_assert_eq ! ( collected. len( ) , 0 ) ;
2466
+ }
2467
+ }
2468
+ // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
2469
+ }
2470
+ }
2471
+
2472
+ /// Private helper methods for `Splice::drop`
2473
+ impl < ' a , T > Drain < ' a , T > {
2474
+ /// The range from `self.vec.len` to `self.tail_start` contains elements
2475
+ /// that have been moved out.
2476
+ /// Fill that range as much as possible with new elements from the `replace_with` iterator.
2477
+ /// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.)
2478
+ unsafe fn fill < I : Iterator < Item =T > > ( & mut self , replace_with : & mut I ) -> bool {
2479
+ let vec = & mut * self . vec ;
2480
+ let range_start = vec. len ;
2481
+ let range_end = self . tail_start ;
2482
+ let range_slice = slice:: from_raw_parts_mut (
2483
+ vec. as_mut_ptr ( ) . offset ( range_start as isize ) ,
2484
+ range_end - range_start) ;
2485
+
2486
+ for place in range_slice {
2487
+ if let Some ( new_item) = replace_with. next ( ) {
2488
+ ptr:: write ( place, new_item) ;
2489
+ vec. len += 1 ;
2490
+ } else {
2491
+ return false
2492
+ }
2493
+ }
2494
+ true
2495
+ }
2496
+
2497
+ /// Make room for inserting more elements before the tail.
2498
+ unsafe fn move_tail ( & mut self , extra_capacity : usize ) {
2499
+ let vec = & mut * self . vec ;
2500
+ let used_capacity = self . tail_start + self . tail_len ;
2501
+ vec. buf . reserve ( used_capacity, extra_capacity) ;
2502
+
2503
+ let new_tail_start = self . tail_start + extra_capacity;
2504
+ let src = vec. as_ptr ( ) . offset ( self . tail_start as isize ) ;
2505
+ let dst = vec. as_mut_ptr ( ) . offset ( new_tail_start as isize ) ;
2506
+ ptr:: copy ( src, dst, self . tail_len ) ;
2507
+ self . tail_start = new_tail_start;
2508
+ }
2509
+ }
0 commit comments