@@ -22,7 +22,7 @@ use convert::TryFrom;
22
22
use fmt;
23
23
use iter:: { Map , Cloned , FusedIterator } ;
24
24
use mem;
25
- use slice;
25
+ use slice:: { self , SliceIndex } ;
26
26
27
27
pub mod pattern;
28
28
@@ -1445,6 +1445,8 @@ Section: Trait implementations
1445
1445
mod traits {
1446
1446
use cmp:: Ordering ;
1447
1447
use ops;
1448
+ use mem;
1449
+ use slice:: { self , SliceIndex } ;
1448
1450
use str:: eq_slice;
1449
1451
1450
1452
/// Implements ordering of strings.
@@ -1527,14 +1529,7 @@ mod traits {
1527
1529
type Output = str ;
1528
1530
#[ inline]
1529
1531
fn index ( & self , index : ops:: Range < usize > ) -> & str {
1530
- // is_char_boundary checks that the index is in [0, .len()]
1531
- if index. start <= index. end &&
1532
- self . is_char_boundary ( index. start ) &&
1533
- self . is_char_boundary ( index. end ) {
1534
- unsafe { self . slice_unchecked ( index. start , index. end ) }
1535
- } else {
1536
- super :: slice_error_fail ( self , index. start , index. end )
1537
- }
1532
+ index. index ( self )
1538
1533
}
1539
1534
}
1540
1535
@@ -1556,14 +1551,7 @@ mod traits {
1556
1551
impl ops:: IndexMut < ops:: Range < usize > > for str {
1557
1552
#[ inline]
1558
1553
fn index_mut ( & mut self , index : ops:: Range < usize > ) -> & mut str {
1559
- // is_char_boundary checks that the index is in [0, .len()]
1560
- if index. start <= index. end &&
1561
- self . is_char_boundary ( index. start ) &&
1562
- self . is_char_boundary ( index. end ) {
1563
- unsafe { self . slice_mut_unchecked ( index. start , index. end ) }
1564
- } else {
1565
- super :: slice_error_fail ( self , index. start , index. end )
1566
- }
1554
+ index. index_mut ( self )
1567
1555
}
1568
1556
}
1569
1557
@@ -1731,8 +1719,276 @@ mod traits {
1731
1719
self . index_mut ( 0 ...index. end )
1732
1720
}
1733
1721
}
1722
+
1723
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1724
+ impl SliceIndex < str > for ops:: RangeFull {
1725
+ type Output = str ;
1726
+ #[ inline]
1727
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1728
+ Some ( slice)
1729
+ }
1730
+ #[ inline]
1731
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1732
+ Some ( slice)
1733
+ }
1734
+ #[ inline]
1735
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1736
+ slice
1737
+ }
1738
+ #[ inline]
1739
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1740
+ slice
1741
+ }
1742
+ #[ inline]
1743
+ fn index ( self , slice : & str ) -> & Self :: Output {
1744
+ slice
1745
+ }
1746
+ #[ inline]
1747
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1748
+ slice
1749
+ }
1750
+ }
1751
+
1752
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1753
+ impl SliceIndex < str > for ops:: Range < usize > {
1754
+ type Output = str ;
1755
+ #[ inline]
1756
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1757
+ if self . start <= self . end &&
1758
+ slice. is_char_boundary ( self . start ) &&
1759
+ slice. is_char_boundary ( self . end ) {
1760
+ Some ( unsafe { self . get_unchecked ( slice) } )
1761
+ } else {
1762
+ None
1763
+ }
1764
+ }
1765
+ #[ inline]
1766
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1767
+ if self . start <= self . end &&
1768
+ slice. is_char_boundary ( self . start ) &&
1769
+ slice. is_char_boundary ( self . end ) {
1770
+ Some ( unsafe { self . get_unchecked_mut ( slice) } )
1771
+ } else {
1772
+ None
1773
+ }
1774
+ }
1775
+ #[ inline]
1776
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1777
+ let ptr = slice. as_ptr ( ) . offset ( self . start as isize ) ;
1778
+ let len = self . end - self . start ;
1779
+ super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) )
1780
+ }
1781
+ #[ inline]
1782
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1783
+ let ptr = slice. as_ptr ( ) . offset ( self . start as isize ) ;
1784
+ let len = self . end - self . start ;
1785
+ mem:: transmute ( slice:: from_raw_parts_mut ( ptr as * mut u8 , len) )
1786
+ }
1787
+ #[ inline]
1788
+ fn index ( self , slice : & str ) -> & Self :: Output {
1789
+ let ( start, end) = ( self . start , self . end ) ;
1790
+ self . get ( slice) . unwrap_or_else ( || super :: slice_error_fail ( slice, start, end) )
1791
+ }
1792
+ #[ inline]
1793
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1794
+ // is_char_boundary checks that the index is in [0, .len()]
1795
+ // canot reuse `get` as above, because of NLL trouble
1796
+ if self . start <= self . end &&
1797
+ slice. is_char_boundary ( self . start ) &&
1798
+ slice. is_char_boundary ( self . end ) {
1799
+ unsafe { self . get_unchecked_mut ( slice) }
1800
+ } else {
1801
+ super :: slice_error_fail ( slice, self . start , self . end )
1802
+ }
1803
+ }
1804
+ }
1805
+
1806
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1807
+ impl SliceIndex < str > for ops:: RangeTo < usize > {
1808
+ type Output = str ;
1809
+ #[ inline]
1810
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1811
+ if slice. is_char_boundary ( self . end ) {
1812
+ Some ( unsafe { self . get_unchecked ( slice) } )
1813
+ } else {
1814
+ None
1815
+ }
1816
+ }
1817
+ #[ inline]
1818
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1819
+ if slice. is_char_boundary ( self . end ) {
1820
+ Some ( unsafe { self . get_unchecked_mut ( slice) } )
1821
+ } else {
1822
+ None
1823
+ }
1824
+ }
1825
+ #[ inline]
1826
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1827
+ let ptr = slice. as_ptr ( ) ;
1828
+ super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, self . end ) )
1829
+ }
1830
+ #[ inline]
1831
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1832
+ let ptr = slice. as_ptr ( ) ;
1833
+ mem:: transmute ( slice:: from_raw_parts_mut ( ptr as * mut u8 , self . end ) )
1834
+ }
1835
+ #[ inline]
1836
+ fn index ( self , slice : & str ) -> & Self :: Output {
1837
+ let end = self . end ;
1838
+ self . get ( slice) . unwrap_or_else ( || super :: slice_error_fail ( slice, 0 , end) )
1839
+ }
1840
+ #[ inline]
1841
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1842
+ if slice. is_char_boundary ( self . end ) {
1843
+ unsafe { self . get_unchecked_mut ( slice) }
1844
+ } else {
1845
+ super :: slice_error_fail ( slice, 0 , self . end )
1846
+ }
1847
+ }
1848
+ }
1849
+
1850
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1851
+ impl SliceIndex < str > for ops:: RangeFrom < usize > {
1852
+ type Output = str ;
1853
+ #[ inline]
1854
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1855
+ if slice. is_char_boundary ( self . start ) {
1856
+ Some ( unsafe { self . get_unchecked ( slice) } )
1857
+ } else {
1858
+ None
1859
+ }
1860
+ }
1861
+ #[ inline]
1862
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1863
+ if slice. is_char_boundary ( self . start ) {
1864
+ Some ( unsafe { self . get_unchecked_mut ( slice) } )
1865
+ } else {
1866
+ None
1867
+ }
1868
+ }
1869
+ #[ inline]
1870
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1871
+ let ptr = slice. as_ptr ( ) . offset ( self . start as isize ) ;
1872
+ let len = slice. len ( ) - self . start ;
1873
+ super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) )
1874
+ }
1875
+ #[ inline]
1876
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1877
+ let ptr = slice. as_ptr ( ) . offset ( self . start as isize ) ;
1878
+ let len = slice. len ( ) - self . start ;
1879
+ mem:: transmute ( slice:: from_raw_parts_mut ( ptr as * mut u8 , len) )
1880
+ }
1881
+ #[ inline]
1882
+ fn index ( self , slice : & str ) -> & Self :: Output {
1883
+ let ( start, end) = ( self . start , slice. len ( ) ) ;
1884
+ self . get ( slice) . unwrap_or_else ( || super :: slice_error_fail ( slice, start, end) )
1885
+ }
1886
+ #[ inline]
1887
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1888
+ if slice. is_char_boundary ( self . start ) {
1889
+ unsafe { self . get_unchecked_mut ( slice) }
1890
+ } else {
1891
+ super :: slice_error_fail ( slice, self . start , slice. len ( ) )
1892
+ }
1893
+ }
1894
+ }
1895
+
1896
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1897
+ impl SliceIndex < str > for ops:: RangeInclusive < usize > {
1898
+ type Output = str ;
1899
+ #[ inline]
1900
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1901
+ match self {
1902
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1903
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1904
+ } . get ( slice)
1905
+ }
1906
+ #[ inline]
1907
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1908
+ match self {
1909
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1910
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1911
+ } . get_mut ( slice)
1912
+ }
1913
+ #[ inline]
1914
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1915
+ match self {
1916
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1917
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1918
+ } . get_unchecked ( slice)
1919
+ }
1920
+ #[ inline]
1921
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1922
+ match self {
1923
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1924
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1925
+ } . get_unchecked_mut ( slice)
1926
+ }
1927
+ #[ inline]
1928
+ fn index ( self , slice : & str ) -> & Self :: Output {
1929
+ match self {
1930
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1931
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1932
+ } . index ( slice)
1933
+ }
1934
+ #[ inline]
1935
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1936
+ match self {
1937
+ ops:: RangeInclusive :: Empty { .. } => 0 ..0 ,
1938
+ ops:: RangeInclusive :: NonEmpty { start, end } => start..end+1 ,
1939
+ } . index_mut ( slice)
1940
+ }
1941
+ }
1942
+
1943
+
1944
+
1945
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
1946
+ impl SliceIndex < str > for ops:: RangeToInclusive < usize > {
1947
+ type Output = str ;
1948
+ #[ inline]
1949
+ fn get ( self , slice : & str ) -> Option < & Self :: Output > {
1950
+ if slice. is_char_boundary ( self . end + 1 ) {
1951
+ Some ( unsafe { self . get_unchecked ( slice) } )
1952
+ } else {
1953
+ None
1954
+ }
1955
+ }
1956
+ #[ inline]
1957
+ fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
1958
+ if slice. is_char_boundary ( self . end + 1 ) {
1959
+ Some ( unsafe { self . get_unchecked_mut ( slice) } )
1960
+ } else {
1961
+ None
1962
+ }
1963
+ }
1964
+ #[ inline]
1965
+ unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1966
+ let ptr = slice. as_ptr ( ) ;
1967
+ super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, self . end + 1 ) )
1968
+ }
1969
+ #[ inline]
1970
+ unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1971
+ let ptr = slice. as_ptr ( ) ;
1972
+ mem:: transmute ( slice:: from_raw_parts_mut ( ptr as * mut u8 , self . end + 1 ) )
1973
+ }
1974
+ #[ inline]
1975
+ fn index ( self , slice : & str ) -> & Self :: Output {
1976
+ let end = self . end + 1 ;
1977
+ self . get ( slice) . unwrap_or_else ( || super :: slice_error_fail ( slice, 0 , end) )
1978
+ }
1979
+ #[ inline]
1980
+ fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1981
+ if slice. is_char_boundary ( self . end ) {
1982
+ unsafe { self . get_unchecked_mut ( slice) }
1983
+ } else {
1984
+ super :: slice_error_fail ( slice, 0 , self . end + 1 )
1985
+ }
1986
+ }
1987
+ }
1988
+
1734
1989
}
1735
1990
1991
+
1736
1992
/// Methods for string slices
1737
1993
#[ allow( missing_docs) ]
1738
1994
#[ doc( hidden) ]
@@ -1782,6 +2038,14 @@ pub trait StrExt {
1782
2038
#[ rustc_deprecated( since = "1.6.0" , reason = "use lines() instead now" ) ]
1783
2039
#[ allow( deprecated) ]
1784
2040
fn lines_any ( & self ) -> LinesAny ;
2041
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
2042
+ fn get < I : SliceIndex < str > > ( & self , i : I ) -> Option < & I :: Output > ;
2043
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
2044
+ fn get_mut < I : SliceIndex < str > > ( & mut self , i : I ) -> Option < & mut I :: Output > ;
2045
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
2046
+ unsafe fn get_unchecked < I : SliceIndex < str > > ( & self , i : I ) -> & I :: Output ;
2047
+ #[ unstable( feature = "str_checked_slicing" , issue = "39932" ) ]
2048
+ unsafe fn get_unchecked_mut < I : SliceIndex < str > > ( & mut self , i : I ) -> & mut I :: Output ;
1785
2049
#[ stable( feature = "core" , since = "1.6.0" ) ]
1786
2050
unsafe fn slice_unchecked ( & self , begin : usize , end : usize ) -> & str ;
1787
2051
#[ stable( feature = "core" , since = "1.6.0" ) ]
@@ -1971,18 +2235,34 @@ impl StrExt for str {
1971
2235
LinesAny ( self . lines ( ) )
1972
2236
}
1973
2237
2238
+ #[ inline]
2239
+ fn get < I : SliceIndex < str > > ( & self , i : I ) -> Option < & I :: Output > {
2240
+ i. get ( self )
2241
+ }
2242
+
2243
+ #[ inline]
2244
+ fn get_mut < I : SliceIndex < str > > ( & mut self , i : I ) -> Option < & mut I :: Output > {
2245
+ i. get_mut ( self )
2246
+ }
2247
+
2248
+ #[ inline]
2249
+ unsafe fn get_unchecked < I : SliceIndex < str > > ( & self , i : I ) -> & I :: Output {
2250
+ i. get_unchecked ( self )
2251
+ }
2252
+
2253
+ #[ inline]
2254
+ unsafe fn get_unchecked_mut < I : SliceIndex < str > > ( & mut self , i : I ) -> & mut I :: Output {
2255
+ i. get_unchecked_mut ( self )
2256
+ }
2257
+
1974
2258
#[ inline]
1975
2259
unsafe fn slice_unchecked ( & self , begin : usize , end : usize ) -> & str {
1976
- let ptr = self . as_ptr ( ) . offset ( begin as isize ) ;
1977
- let len = end - begin;
1978
- from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) )
2260
+ ( begin..end) . get_unchecked ( self )
1979
2261
}
1980
2262
1981
2263
#[ inline]
1982
2264
unsafe fn slice_mut_unchecked ( & mut self , begin : usize , end : usize ) -> & mut str {
1983
- let ptr = self . as_ptr ( ) . offset ( begin as isize ) ;
1984
- let len = end - begin;
1985
- mem:: transmute ( slice:: from_raw_parts_mut ( ptr as * mut u8 , len) )
2265
+ ( begin..end) . get_unchecked_mut ( self )
1986
2266
}
1987
2267
1988
2268
#[ inline]
0 commit comments