@@ -1834,8 +1834,144 @@ impl<T> VecDeque<T> {
1834
1834
#[ inline]
1835
1835
#[ stable( feature = "append" , since = "1.4.0" ) ]
1836
1836
pub fn append ( & mut self , other : & mut Self ) {
1837
- // naive impl
1838
- self . extend ( other. drain ( ..) ) ;
1837
+ // Copy from src[i1..i1 + len] to dst[i2..i2 + len].
1838
+ // Does not check if the ranges are valid.
1839
+ unsafe fn copy_part < T > ( i1 : usize , i2 : usize , len : usize , src : & [ T ] , dst : & mut [ T ] ) {
1840
+ debug_assert ! ( src. get( i1..i1 + len) . is_some( ) && dst. get( i2..i2 + len) . is_some( ) ) ;
1841
+ ptr:: copy_nonoverlapping ( src. as_ptr ( ) . add ( i1) , dst. as_mut_ptr ( ) . add ( i2) , len) ;
1842
+ }
1843
+
1844
+ let src_total = other. len ( ) ;
1845
+
1846
+ // Guarantees there is space in `self` for `other`.
1847
+ self . reserve ( src_total) ;
1848
+
1849
+ self . head = {
1850
+ let dst_start_1 = self . head ;
1851
+ let src_start_1 = other. tail ;
1852
+ let dst_wrap_point = self . cap ( ) ;
1853
+ let src_wrap_point = other. cap ( ) ;
1854
+
1855
+ let dst = unsafe { self . buffer_as_mut_slice ( ) } ;
1856
+ let src = unsafe { other. buffer_as_slice ( ) } ;
1857
+
1858
+ let src_wraps = other. tail > other. head ;
1859
+ let dst_wraps = dst_start_1 + src_total > dst_wrap_point;
1860
+
1861
+ // When minimizing the amount of calls to `copy_part`, there are
1862
+ // 6 different cases to handle. Whether src and/or dst wrap are 4
1863
+ // combinations and there are 3 distinct cases when they both wrap.
1864
+ // 6 = 3 + 1 + 1 + 1
1865
+ match ( src_wraps, dst_wraps) {
1866
+ ( true , true ) => {
1867
+ let dst_before_wrap = dst_wrap_point - dst_start_1;
1868
+ let src_before_wrap = src_wrap_point - src_start_1;
1869
+
1870
+ if src_before_wrap < dst_before_wrap {
1871
+ // src
1872
+ // [o o o . . . . . . o o o]
1873
+ // 2 3 3 1 1 1
1874
+ //
1875
+ // dst
1876
+ // [. . . . . . o o . . . .]
1877
+ // 3 3 H 1 1 1 2
1878
+ let src_2 = dst_before_wrap - src_before_wrap;
1879
+ let dst_start_2 = dst_start_1 + src_before_wrap;
1880
+ let src_3 = src_total - dst_before_wrap;
1881
+
1882
+ unsafe {
1883
+ copy_part ( src_start_1, dst_start_1, src_before_wrap, src, dst) ;
1884
+ copy_part ( 0 , dst_start_2, src_2, src, dst) ;
1885
+ copy_part ( src_2, 0 , src_3, src, dst) ;
1886
+ }
1887
+ src_3
1888
+ } else if src_before_wrap > dst_before_wrap {
1889
+ // src
1890
+ // [o o o . . . . . o o o o]
1891
+ // 3 3 3 1 1 2 2
1892
+ //
1893
+ // dst
1894
+ // [. . . . . . o o o o . .]
1895
+ // 2 2 3 3 3 H 1 1
1896
+ let src_2 = src_before_wrap - dst_before_wrap;
1897
+ let src_start_2 = src_start_1 + dst_before_wrap;
1898
+ let src_3 = src_total - src_before_wrap;
1899
+
1900
+ unsafe {
1901
+ copy_part ( src_start_1, dst_start_1, dst_before_wrap, src, dst) ;
1902
+ copy_part ( src_start_2, 0 , src_2, src, dst) ;
1903
+ copy_part ( 0 , src_2, src_3, src, dst) ;
1904
+ }
1905
+ src_2 + src_3
1906
+ } else {
1907
+ // src
1908
+ // [o o . . . . . . . o o o]
1909
+ // 2 2 1 1 1
1910
+ //
1911
+ // dst
1912
+ // [. . . . . . . o o . . .]
1913
+ // 2 2 H 1 1 1
1914
+ let src_2 = src_total - src_before_wrap;
1915
+
1916
+ unsafe {
1917
+ copy_part ( src_start_1, dst_start_1, src_before_wrap, src, dst) ;
1918
+ copy_part ( 0 , 0 , src_2, src, dst) ;
1919
+ }
1920
+ src_2
1921
+ }
1922
+ }
1923
+ ( false , true ) => {
1924
+ // src
1925
+ // [. . . o o o o o . . . .]
1926
+ // 1 1 2 2 2
1927
+ //
1928
+ // dst
1929
+ // [. . . . . . . o o o . .]
1930
+ // 2 2 2 H 1 1
1931
+ let dst_1 = dst_wrap_point - dst_start_1;
1932
+ let src_start_2 = src_start_1 + dst_1;
1933
+ let dst_2 = src_total - dst_1;
1934
+
1935
+ unsafe {
1936
+ copy_part ( src_start_1, dst_start_1, dst_1, src, dst) ;
1937
+ copy_part ( src_start_2, 0 , dst_2, src, dst) ;
1938
+ }
1939
+ dst_2
1940
+ }
1941
+ ( true , false ) => {
1942
+ // src
1943
+ // [o o . . . . . . . o o o]
1944
+ // 2 2 1 1 1
1945
+ //
1946
+ // dst
1947
+ // [. o o . . . . . . . . .]
1948
+ // 1 1 1 2 2 H
1949
+ let src_1 = src_wrap_point - src_start_1;
1950
+ let dst_start_2 = dst_start_1 + src_1;
1951
+ let src_2 = src_total - src_1;
1952
+
1953
+ unsafe {
1954
+ copy_part ( src_start_1, dst_start_1, src_1, src, dst) ;
1955
+ copy_part ( 0 , dst_start_2, src_2, src, dst) ;
1956
+ }
1957
+ dst_start_1 + src_1 + src_2
1958
+ }
1959
+ ( false , false ) => {
1960
+ // src
1961
+ // [. . . o o o . . . . . .]
1962
+ // 1 1 1
1963
+ //
1964
+ // dst
1965
+ // [. o o o o o . . . . . .]
1966
+ // 1 1 1 H
1967
+ unsafe {
1968
+ copy_part ( src_start_1, dst_start_1, src_total, src, dst) ;
1969
+ }
1970
+ dst_start_1 + src_total
1971
+ }
1972
+ }
1973
+ } ;
1974
+ other. clear ( ) ;
1839
1975
}
1840
1976
1841
1977
/// Retains only the elements specified by the predicate.
0 commit comments