|
| 1 | +use core::cell::Cell; |
1 | 2 | use core::num::NonZero; |
2 | 3 | use std::assert_matches::assert_matches; |
3 | 4 | use std::collections::TryReserveErrorKind::*; |
@@ -1863,22 +1864,185 @@ fn test_extend_from_within() { |
1863 | 1864 | assert_eq!(v, [2, 3, 4, 5, 3, 4, 5, 3, 4, 2, 3, 4]); |
1864 | 1865 | } |
1865 | 1866 |
|
| 1867 | +struct CloneTracker<'a> { |
| 1868 | + clone: &'a Cell<u32>, |
| 1869 | + drop: &'a Cell<u32>, |
| 1870 | + panic: bool, |
| 1871 | +} |
| 1872 | + |
| 1873 | +impl<'a> Clone for CloneTracker<'a> { |
| 1874 | + fn clone(&self) -> Self { |
| 1875 | + self.clone.set(self.clone.get() + 1); |
| 1876 | + if self.panic { |
| 1877 | + panic!(); |
| 1878 | + } |
| 1879 | + Self { clone: self.clone, drop: self.drop, panic: false } |
| 1880 | + } |
| 1881 | +} |
| 1882 | + |
| 1883 | +impl<'a> Drop for CloneTracker<'a> { |
| 1884 | + fn drop(&mut self) { |
| 1885 | + self.drop.set(self.drop.get() + 1); |
| 1886 | + } |
| 1887 | +} |
| 1888 | + |
1866 | 1889 | #[test] |
1867 | 1890 | fn test_extend_from_within_clone() { |
1868 | | - // keep track of clone count and correct dropping when clone impl panics |
| 1891 | + let clone_counts = [const { Cell::new(0) }; 6]; |
| 1892 | + let drop_count = Cell::new(0); |
| 1893 | + let mut v = VecDeque::with_capacity(10); |
| 1894 | + v.extend(clone_counts.iter().map(|clone_count| CloneTracker { |
| 1895 | + clone: clone_count, |
| 1896 | + drop: &drop_count, |
| 1897 | + panic: false, |
| 1898 | + })); |
| 1899 | + v.truncate_front(4); |
| 1900 | + |
| 1901 | + v.extend_from_within(2..); |
| 1902 | + v.extend_from_within(1..5); |
| 1903 | + assert_eq!( |
| 1904 | + v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), |
| 1905 | + [0, 1, 3, 2, 3, 2, 1, 3, 2, 3], |
| 1906 | + ); |
| 1907 | + assert_eq!( |
| 1908 | + clone_counts.each_ref().map(|c| { |
| 1909 | + let old = c.get(); |
| 1910 | + c.set(0); |
| 1911 | + old |
| 1912 | + }), |
| 1913 | + [0, 0, 0, 1, 3, 2], |
| 1914 | + ); |
| 1915 | +} |
| 1916 | + |
| 1917 | +#[test] |
| 1918 | +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] |
| 1919 | +fn test_extend_from_within_clone_panic() { |
| 1920 | + let clone_counts = [const { Cell::new(0) }; 6]; |
| 1921 | + let drop_count = Cell::new(0); |
| 1922 | + let mut v = VecDeque::with_capacity(8); |
| 1923 | + v.extend(clone_counts.iter().map(|clone_count| CloneTracker { |
| 1924 | + clone: clone_count, |
| 1925 | + drop: &drop_count, |
| 1926 | + panic: false, |
| 1927 | + })); |
| 1928 | + |
| 1929 | + v.truncate_front(4); |
| 1930 | + |
| 1931 | + // panic after wrapping |
| 1932 | + v[2].panic = true; |
| 1933 | + catch_unwind(AssertUnwindSafe(|| { |
| 1934 | + v.extend_from_within(..); |
| 1935 | + })) |
| 1936 | + .unwrap_err(); |
| 1937 | + v[2].panic = false; |
| 1938 | + assert_eq!(v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), [1, 1, 1, 0, 1, 1]); |
| 1939 | + assert_eq!(clone_counts.each_ref().map(|c| c.get()), [0, 0, 1, 1, 1, 0]); |
| 1940 | + assert_eq!(drop_count.get(), 2); |
| 1941 | + |
| 1942 | + v.truncate_front(2); |
| 1943 | + |
| 1944 | + // panic before wrapping |
| 1945 | + v[1].panic = true; |
| 1946 | + catch_unwind(AssertUnwindSafe(|| { |
| 1947 | + v.extend_from_within(..); |
| 1948 | + })) |
| 1949 | + .unwrap_err(); |
| 1950 | + v[1].panic = false; |
| 1951 | + assert_eq!(v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), [2, 2, 2]); |
| 1952 | + assert_eq!(clone_counts.each_ref().map(|c| c.get()), [0, 0, 2, 2, 1, 0]); |
| 1953 | + assert_eq!(drop_count.get(), 6); |
1869 | 1954 | } |
1870 | 1955 |
|
1871 | 1956 | #[test] |
1872 | 1957 | fn test_prepend_from_within() { |
1873 | | - // like test_extend_from_within |
| 1958 | + let mut v = VecDeque::with_capacity(8); |
| 1959 | + v.extend(0..6); |
| 1960 | + v.truncate_front(4); |
| 1961 | + v.prepend_from_within(..=0); |
| 1962 | + assert_eq!(v.as_slices(), ([2, 2, 3, 4, 5].as_slice(), [].as_slice())); |
| 1963 | + v.prepend_from_within(2..); |
| 1964 | + assert_eq!(v.as_slices(), ([3, 4].as_slice(), [5, 2, 2, 3, 4, 5].as_slice())); |
| 1965 | + v.prepend_from_within(..); |
| 1966 | + assert_eq!(v, [[3, 4, 5, 2, 2, 3, 4, 5]; 2].as_flattened()); |
1874 | 1967 | } |
1875 | 1968 |
|
1876 | 1969 | #[test] |
1877 | 1970 | fn test_prepend_from_within_clone() { |
1878 | | - // like test_extend_from_within_clone |
| 1971 | + let clone_counts = [const { Cell::new(0) }; 6]; |
| 1972 | + let drop_count = Cell::new(0); |
| 1973 | + let mut v = VecDeque::with_capacity(10); |
| 1974 | + v.extend(clone_counts.iter().map(|clone_count| CloneTracker { |
| 1975 | + clone: clone_count, |
| 1976 | + drop: &drop_count, |
| 1977 | + panic: false, |
| 1978 | + })); |
| 1979 | + v.truncate_front(4); |
| 1980 | + |
| 1981 | + v.prepend_from_within(..2); |
| 1982 | + v.prepend_from_within(1..5); |
| 1983 | + assert_eq!( |
| 1984 | + v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), |
| 1985 | + [3, 2, 3, 1, 2, 3, 2, 3, 1, 0], |
| 1986 | + ); |
| 1987 | + assert_eq!( |
| 1988 | + clone_counts.each_ref().map(|c| { |
| 1989 | + let old = c.get(); |
| 1990 | + c.set(0); |
| 1991 | + old |
| 1992 | + }), |
| 1993 | + [0, 0, 2, 3, 1, 0], |
| 1994 | + ); |
| 1995 | +} |
| 1996 | + |
| 1997 | +#[test] |
| 1998 | +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] |
| 1999 | +fn test_prepend_from_within_clone_panic() { |
| 2000 | + let clone_counts = [const { Cell::new(0) }; 6]; |
| 2001 | + let drop_count = Cell::new(0); |
| 2002 | + let mut v = VecDeque::with_capacity(8); |
| 2003 | + v.extend(clone_counts.iter().map(|clone_count| CloneTracker { |
| 2004 | + clone: clone_count, |
| 2005 | + drop: &drop_count, |
| 2006 | + panic: false, |
| 2007 | + })); |
| 2008 | + |
| 2009 | + v.truncate_front(4); |
| 2010 | + |
| 2011 | + // panic after wrapping |
| 2012 | + v[1].panic = true; |
| 2013 | + catch_unwind(AssertUnwindSafe(|| { |
| 2014 | + v.prepend_from_within(..); |
| 2015 | + })) |
| 2016 | + .unwrap_err(); |
| 2017 | + v[1].panic = false; |
| 2018 | + assert_eq!(v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), [1, 1, 0, 1, 1, 1]); |
| 2019 | + assert_eq!(clone_counts.each_ref().map(|c| c.get()), [0, 0, 0, 1, 1, 1]); |
| 2020 | + assert_eq!(drop_count.get(), 2); |
| 2021 | + |
| 2022 | + v.truncate_front(2); |
| 2023 | + |
| 2024 | + // panic before wrapping |
| 2025 | + v[0].panic = true; |
| 2026 | + catch_unwind(AssertUnwindSafe(|| { |
| 2027 | + v.prepend_from_within(..); |
| 2028 | + })) |
| 2029 | + .unwrap_err(); |
| 2030 | + v[0].panic = false; |
| 2031 | + assert_eq!(v.iter().map(|tr| tr.clone.get()).collect::<Vec<_>>(), [2, 2, 2]); |
| 2032 | + assert_eq!(clone_counts.each_ref().map(|c| c.get()), [0, 0, 0, 1, 2, 2]); |
| 2033 | + assert_eq!(drop_count.get(), 6); |
1879 | 2034 | } |
1880 | 2035 |
|
1881 | 2036 | #[test] |
1882 | 2037 | fn test_extend_and_prepend_from_within() { |
1883 | | - // mix extend_from_within and prepend_from_within |
| 2038 | + let mut v = ('0'..='9').map(String::from).collect::<VecDeque<_>>(); |
| 2039 | + v.truncate_front(5); |
| 2040 | + v.extend_from_within(4..); |
| 2041 | + v.prepend_from_within(..2); |
| 2042 | + assert_eq!(v.iter().map(|s| &**s).collect::<String>(), "56567899"); |
| 2043 | + v.clear(); |
| 2044 | + v.extend(['1', '2', '3'].into_iter().map(String::from)); |
| 2045 | + v.prepend_from_within(..); |
| 2046 | + v.extend_from_within(..); |
| 2047 | + assert_eq!(v.iter().map(|s| &**s).collect::<String>(), "123123123123"); |
1884 | 2048 | } |
0 commit comments