@@ -1322,20 +1322,6 @@ pub enum FpCategory {
13221322 Normal ,
13231323}
13241324
1325- macro_rules! from_str_radix_int_impl {
1326- ( $( $t: ty) * ) => { $(
1327- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1328- impl FromStr for $t {
1329- type Err = ParseIntError ;
1330- #[ inline]
1331- fn from_str( src: & str ) -> Result <Self , ParseIntError > {
1332- <$t>:: from_str_radix( src, 10 )
1333- }
1334- }
1335- ) * }
1336- }
1337- from_str_radix_int_impl ! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
1338-
13391325/// Determines if a string of text of that length of that radix could be guaranteed to be
13401326/// stored in the given type T.
13411327/// Note that if the radix is known to the compiler, it is just the check of digits.len that
@@ -1351,18 +1337,58 @@ pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8])
13511337#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
13521338#[ cold]
13531339#[ track_caller]
1354- const fn from_str_radix_panic ( radix : u32 ) -> ! {
1340+ const fn from_ascii_radix_panic ( radix : u32 ) -> ! {
13551341 const_panic ! (
1356- "from_str_radix_int: must lie in the range `[2, 36]`" ,
1357- "from_str_radix_int: must lie in the range `[2, 36]` - found {radix}" ,
1342+ "from_ascii_radix: radix must lie in the range `[2, 36]`" ,
1343+ "from_ascii_radix: radix must lie in the range `[2, 36]` - found {radix}" ,
13581344 radix: u32 = radix,
13591345 )
13601346}
13611347
1362- macro_rules! from_str_radix {
1348+ macro_rules! from_str_int_impl {
13631349 ( $signedness: ident $( $int_ty: ty) +) => { $(
1350+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1351+ impl FromStr for $int_ty {
1352+ type Err = ParseIntError ;
1353+
1354+ /// Parses an integer from a string slice with decimal digits.
1355+ ///
1356+ /// The characters are expected to be an optional
1357+ #[ doc = sign_dependent_expr!{
1358+ $signedness ?
1359+ if signed {
1360+ " `+` or `-` "
1361+ }
1362+ if unsigned {
1363+ " `+` "
1364+ }
1365+ } ]
1366+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1367+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1368+ /// also represent an error.
1369+ ///
1370+ /// # Examples
1371+ ///
1372+ /// Basic usage:
1373+ /// ```
1374+ /// use std::str::FromStr;
1375+ ///
1376+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_str(\" +10\" ), Ok(10));" ) ]
1377+ /// ```
1378+ /// Trailing space returns error:
1379+ /// ```
1380+ /// # use std::str::FromStr;
1381+ /// #
1382+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_str(\" 1 \" ).is_err());" ) ]
1383+ /// ```
1384+ #[ inline]
1385+ fn from_str( src: & str ) -> Result <$int_ty, ParseIntError > {
1386+ <$int_ty>:: from_str_radix( src, 10 )
1387+ }
1388+ }
1389+
13641390 impl $int_ty {
1365- /// Converts a string slice in a given base to an integer .
1391+ /// Parses an integer from a string slice with digits in a given base.
13661392 ///
13671393 /// The string is expected to be an optional
13681394 #[ doc = sign_dependent_expr!{
@@ -1375,7 +1401,7 @@ macro_rules! from_str_radix {
13751401 }
13761402 } ]
13771403 /// sign followed by only digits. Leading and trailing non-digit characters (including
1378- /// whitespace) represent an error. Underscores (which are accepted in rust literals)
1404+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
13791405 /// also represent an error.
13801406 ///
13811407 /// Digits are a subset of these characters, depending on `radix`:
@@ -1401,11 +1427,92 @@ macro_rules! from_str_radix {
14011427 #[ rustc_const_stable( feature = "const_int_from_str" , since = "1.82.0" ) ]
14021428 #[ inline]
14031429 pub const fn from_str_radix( src: & str , radix: u32 ) -> Result <$int_ty, ParseIntError > {
1430+ <$int_ty>:: from_ascii_radix( src. as_bytes( ) , radix)
1431+ }
1432+
1433+ /// Parses an integer from an ASCII-byte slice with decimal digits.
1434+ ///
1435+ /// The characters are expected to be an optional
1436+ #[ doc = sign_dependent_expr!{
1437+ $signedness ?
1438+ if signed {
1439+ " `+` or `-` "
1440+ }
1441+ if unsigned {
1442+ " `+` "
1443+ }
1444+ } ]
1445+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1446+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1447+ /// also represent an error.
1448+ ///
1449+ /// # Examples
1450+ ///
1451+ /// Basic usage:
1452+ /// ```
1453+ /// #![feature(int_from_ascii)]
1454+ ///
1455+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_ascii(b\" +10\" ), Ok(10));" ) ]
1456+ /// ```
1457+ /// Trailing space returns error:
1458+ /// ```
1459+ /// # #![feature(int_from_ascii)]
1460+ /// #
1461+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_ascii(b\" 1 \" ).is_err());" ) ]
1462+ /// ```
1463+ #[ unstable( feature = "int_from_ascii" , issue = "134821" ) ]
1464+ #[ inline]
1465+ pub const fn from_ascii( src: & [ u8 ] ) -> Result <$int_ty, ParseIntError > {
1466+ <$int_ty>:: from_ascii_radix( src, 10 )
1467+ }
1468+
1469+ /// Parses an integer from an ASCII-byte slice with digits in a given base.
1470+ ///
1471+ /// The characters are expected to be an optional
1472+ #[ doc = sign_dependent_expr!{
1473+ $signedness ?
1474+ if signed {
1475+ " `+` or `-` "
1476+ }
1477+ if unsigned {
1478+ " `+` "
1479+ }
1480+ } ]
1481+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1482+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1483+ /// also represent an error.
1484+ ///
1485+ /// Digits are a subset of these characters, depending on `radix`:
1486+ /// * `0-9`
1487+ /// * `a-z`
1488+ /// * `A-Z`
1489+ ///
1490+ /// # Panics
1491+ ///
1492+ /// This function panics if `radix` is not in the range from 2 to 36.
1493+ ///
1494+ /// # Examples
1495+ ///
1496+ /// Basic usage:
1497+ /// ```
1498+ /// #![feature(int_from_ascii)]
1499+ ///
1500+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_ascii_radix(b\" A\" , 16), Ok(10));" ) ]
1501+ /// ```
1502+ /// Trailing space returns error:
1503+ /// ```
1504+ /// # #![feature(int_from_ascii)]
1505+ /// #
1506+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_ascii_radix(b\" 1 \" , 10).is_err());" ) ]
1507+ /// ```
1508+ #[ unstable( feature = "int_from_ascii" , issue = "134821" ) ]
1509+ #[ inline]
1510+ pub const fn from_ascii_radix( src: & [ u8 ] , radix: u32 ) -> Result <$int_ty, ParseIntError > {
14041511 use self :: IntErrorKind :: * ;
14051512 use self :: ParseIntError as PIE ;
14061513
14071514 if 2 > radix || radix > 36 {
1408- from_str_radix_panic ( radix) ;
1515+ from_ascii_radix_panic ( radix) ;
14091516 }
14101517
14111518 if src. is_empty( ) {
@@ -1415,12 +1522,6 @@ macro_rules! from_str_radix {
14151522 #[ allow( unused_comparisons) ]
14161523 let is_signed_ty = 0 > <$int_ty>:: MIN ;
14171524
1418- // all valid digits are ascii, so we will just iterate over the utf8 bytes
1419- // and cast them to chars. .to_digit() will safely return None for anything
1420- // other than a valid ascii digit for the given radix, including the first-byte
1421- // of multi-byte sequences
1422- let src = src. as_bytes( ) ;
1423-
14241525 let ( is_positive, mut digits) = match src {
14251526 [ b'+' | b'-' ] => {
14261527 return Err ( PIE { kind: InvalidDigit } ) ;
@@ -1496,67 +1597,8 @@ macro_rules! from_str_radix {
14961597 Ok ( result)
14971598 }
14981599 }
1499- ) +}
1500- }
1501-
1502- from_str_radix ! { unsigned u8 u16 u32 u64 u128 }
1503- from_str_radix ! { signed i8 i16 i32 i64 i128 }
1504-
1505- // Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two
1506- // identical functions.
1507- macro_rules! from_str_radix_size_impl {
1508- ( $( $signedness: ident $t: ident $size: ty) ,* ) => { $(
1509- impl $size {
1510- /// Converts a string slice in a given base to an integer.
1511- ///
1512- /// The string is expected to be an optional
1513- #[ doc = sign_dependent_expr!{
1514- $signedness ?
1515- if signed {
1516- " `+` or `-` "
1517- }
1518- if unsigned {
1519- " `+` "
1520- }
1521- } ]
1522- /// sign followed by only digits. Leading and trailing non-digit characters (including
1523- /// whitespace) represent an error. Underscores (which are accepted in rust literals)
1524- /// also represent an error.
1525- ///
1526- /// Digits are a subset of these characters, depending on `radix`:
1527- /// * `0-9`
1528- /// * `a-z`
1529- /// * `A-Z`
1530- ///
1531- /// # Panics
1532- ///
1533- /// This function panics if `radix` is not in the range from 2 to 36.
1534- ///
1535- /// # Examples
1536- ///
1537- /// Basic usage:
1538- /// ```
1539- #[ doc = concat!( "assert_eq!(" , stringify!( $size) , "::from_str_radix(\" A\" , 16), Ok(10));" ) ]
1540- /// ```
1541- /// Trailing space returns error:
1542- /// ```
1543- #[ doc = concat!( "assert!(" , stringify!( $size) , "::from_str_radix(\" 1 \" , 10).is_err());" ) ]
1544- /// ```
1545- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1546- #[ rustc_const_stable( feature = "const_int_from_str" , since = "1.82.0" ) ]
1547- #[ inline]
1548- pub const fn from_str_radix( src: & str , radix: u32 ) -> Result <$size, ParseIntError > {
1549- match <$t>:: from_str_radix( src, radix) {
1550- Ok ( x) => Ok ( x as $size) ,
1551- Err ( e) => Err ( e) ,
1552- }
1553- }
1554- } ) * }
1600+ ) * }
15551601}
15561602
1557- #[ cfg( target_pointer_width = "16" ) ]
1558- from_str_radix_size_impl ! { signed i16 isize , unsigned u16 usize }
1559- #[ cfg( target_pointer_width = "32" ) ]
1560- from_str_radix_size_impl ! { signed i32 isize , unsigned u32 usize }
1561- #[ cfg( target_pointer_width = "64" ) ]
1562- from_str_radix_size_impl ! { signed i64 isize , unsigned u64 usize }
1603+ from_str_int_impl ! { signed isize i8 i16 i32 i64 i128 }
1604+ from_str_int_impl ! { unsigned usize u8 u16 u32 u64 u128 }
0 commit comments