@@ -1057,7 +1057,7 @@ impl<T> Vec<T> {
10571057 self . len += count;
10581058 }
10591059
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
10611061 /// and yields the removed items.
10621062 ///
10631063 /// Note 1: The element range is removed even if the iterator is only
@@ -1845,6 +1845,54 @@ impl<T> Vec<T> {
18451845 }
18461846 }
18471847 }
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+
18481896}
18491897
18501898#[ stable( feature = "extend_ref" , since = "1.2.0" ) ]
@@ -2344,3 +2392,118 @@ impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
23442392 & mut * ptr
23452393 }
23462394}
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