@@ -764,7 +764,7 @@ impl<T> Vec<T> {
764
764
}
765
765
}
766
766
767
- /// Create a draining iterator that removes the specified range in the vector
767
+ /// Creates a draining iterator that removes the specified range in the vector
768
768
/// and yields the removed items.
769
769
///
770
770
/// Note 1: The element range is removed even if the iterator is not
@@ -826,6 +826,53 @@ impl<T> Vec<T> {
826
826
}
827
827
}
828
828
829
+ /// Creates a splicing iterator that replaces the specified range in the vector
830
+ /// with the given `replace_with` iterator and yields the removed items.
831
+ /// `replace_with` does not need to be the same length as `range`.
832
+ ///
833
+ /// Note 1: The element range is removed even if the iterator is not
834
+ /// consumed until the end.
835
+ ///
836
+ /// Note 2: It is unspecified how many elements are removed from the vector,
837
+ /// if the `Splice` value is leaked.
838
+ ///
839
+ /// Note 3: The input iterator `replace_with` is only consumed
840
+ /// when the `Splice` value is dropped.
841
+ ///
842
+ /// Note 4: This is optimal if:
843
+ ///
844
+ /// * The tail (elements in the vector after `range`) is empty,
845
+ /// * or `replace_with` yields fewer elements than `range`’s length
846
+ /// * or the lower bound of its `size_hint()` is exact.
847
+ ///
848
+ /// Otherwise, a temporary vector is allocated and the tail is moved twice.
849
+ ///
850
+ /// # Panics
851
+ ///
852
+ /// Panics if the starting point is greater than the end point or if
853
+ /// the end point is greater than the length of the vector.
854
+ ///
855
+ /// # Examples
856
+ ///
857
+ /// ```
858
+ /// #![feature(splice)]
859
+ /// let mut v = vec![1, 2, 3];
860
+ /// let new = [7, 8];
861
+ /// let u: Vec<_> = v.splice(..2, new.iter().cloned()).collect();
862
+ /// assert_eq!(v, &[7, 8, 3]);
863
+ /// assert_eq!(u, &[1, 2]);
864
+ /// ```
865
+ #[ inline]
866
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
867
+ pub fn splice < R , I > ( & mut self , range : R , replace_with : I ) -> Splice < I :: IntoIter >
868
+ where R : RangeArgument < usize > , I : IntoIterator < Item =T >
869
+ {
870
+ Splice {
871
+ drain : self . drain ( range) ,
872
+ replace_with : replace_with. into_iter ( ) ,
873
+ }
874
+ }
875
+
829
876
/// Clears the vector, removing all values.
830
877
///
831
878
/// # Examples
@@ -1696,7 +1743,7 @@ impl<T> Drop for IntoIter<T> {
1696
1743
}
1697
1744
}
1698
1745
1699
- /// A draining iterator for `Vec<T>`.
1746
+ /// A draining iterator for `Vec<T>`. See the [`Vec::drain`](struct.Vec.html#method.drain) method.
1700
1747
#[ stable( feature = "drain" , since = "1.6.0" ) ]
1701
1748
pub struct Drain < ' a , T : ' a > {
1702
1749
/// Index of tail to preserve
@@ -1756,6 +1803,119 @@ impl<'a, T> Drop for Drain<'a, T> {
1756
1803
}
1757
1804
}
1758
1805
1759
-
1760
1806
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1761
1807
impl < ' a , T > ExactSizeIterator for Drain < ' a , T > { }
1808
+
1809
+ /// A splicing iterator for `Vec<T>`. See the [`Vec::splice`](struct.Vec.html#method.splice) method.
1810
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1811
+ pub struct Splice < ' a , I : Iterator + ' a > {
1812
+ drain : Drain < ' a , I :: Item > ,
1813
+ replace_with : I ,
1814
+ }
1815
+
1816
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1817
+ impl < ' a , I : Iterator > Iterator for Splice < ' a , I > {
1818
+ type Item = I :: Item ;
1819
+
1820
+ fn next ( & mut self ) -> Option < Self :: Item > {
1821
+ self . drain . next ( )
1822
+ }
1823
+
1824
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1825
+ self . drain . size_hint ( )
1826
+ }
1827
+ }
1828
+
1829
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1830
+ impl < ' a , I : Iterator > DoubleEndedIterator for Splice < ' a , I > {
1831
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1832
+ self . drain . next_back ( )
1833
+ }
1834
+ }
1835
+
1836
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1837
+ impl < ' a , I : Iterator > ExactSizeIterator for Splice < ' a , I > { }
1838
+
1839
+
1840
+ #[ unstable( feature = "splice" , reason = "recently added" , issue = "32310" ) ]
1841
+ impl < ' a , I : Iterator > Drop for Splice < ' a , I > {
1842
+ fn drop ( & mut self ) {
1843
+ // exhaust drain first
1844
+ while let Some ( _) = self . drain . next ( ) { }
1845
+
1846
+
1847
+ unsafe {
1848
+ if self . drain . tail_len == 0 {
1849
+ let vec = & mut * self . drain . vec ;
1850
+ vec. extend ( self . replace_with . by_ref ( ) ) ;
1851
+ return
1852
+ }
1853
+
1854
+ // First fill the range left by drain().
1855
+ if !self . drain . fill ( & mut self . replace_with ) {
1856
+ return
1857
+ }
1858
+
1859
+ // There may be more elements. Use the lower bound as an estimate.
1860
+ // FIXME: Is the upper bound a better guess? Or something else?
1861
+ let ( lower_bound, _upper_bound) = self . replace_with . size_hint ( ) ;
1862
+ if lower_bound > 0 {
1863
+ self . drain . move_tail ( lower_bound) ;
1864
+ if !self . drain . fill ( & mut self . replace_with ) {
1865
+ return
1866
+ }
1867
+ }
1868
+
1869
+ // Collect any remaining elements.
1870
+ // This is a zero-length vector which does not allocate if `lower_bound` was exact.
1871
+ let mut collected = self . replace_with . by_ref ( ) . collect :: < Vec < I :: Item > > ( ) . into_iter ( ) ;
1872
+ // Now we have an exact count.
1873
+ if collected. len ( ) > 0 {
1874
+ self . drain . move_tail ( collected. len ( ) ) ;
1875
+ let filled = self . drain . fill ( & mut collected) ;
1876
+ debug_assert ! ( filled) ;
1877
+ debug_assert_eq ! ( collected. len( ) , 0 ) ;
1878
+ }
1879
+ }
1880
+ // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
1881
+ }
1882
+ }
1883
+
1884
+ /// Private helper methods for `Splice::drop`
1885
+ impl < ' a , T > Drain < ' a , T > {
1886
+ /// The range from `self.vec.len` to `self.tail_start` contains elements
1887
+ /// that have been moved out.
1888
+ /// Fill that range as much as possible with new elements from the `replace_with` iterator.
1889
+ /// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.)
1890
+ unsafe fn fill < I : Iterator < Item =T > > ( & mut self , replace_with : & mut I ) -> bool {
1891
+ let vec = & mut * self . vec ;
1892
+ let range_start = vec. len ;
1893
+ let range_end = self . tail_start ;
1894
+ let range_slice = slice:: from_raw_parts_mut (
1895
+ vec. as_mut_ptr ( ) . offset ( range_start as isize ) ,
1896
+ range_end - range_start) ;
1897
+
1898
+ for place in range_slice {
1899
+ if let Some ( new_item) = replace_with. next ( ) {
1900
+ ptr:: write ( place, new_item) ;
1901
+ vec. len += 1 ;
1902
+ } else {
1903
+ return false
1904
+ }
1905
+ }
1906
+ true
1907
+ }
1908
+
1909
+ /// Make room for inserting more elements before the tail.
1910
+ unsafe fn move_tail ( & mut self , extra_capacity : usize ) {
1911
+ let vec = & mut * self . vec ;
1912
+ let used_capacity = self . tail_start + self . tail_len ;
1913
+ vec. buf . reserve ( used_capacity, extra_capacity) ;
1914
+
1915
+ let new_tail_start = self . tail_start + extra_capacity;
1916
+ let src = vec. as_ptr ( ) . offset ( self . tail_start as isize ) ;
1917
+ let dst = vec. as_mut_ptr ( ) . offset ( new_tail_start as isize ) ;
1918
+ ptr:: copy ( src, dst, self . tail_len ) ;
1919
+ self . tail_start = new_tail_start;
1920
+ }
1921
+ }
0 commit comments