@@ -1453,20 +1453,6 @@ pub enum FpCategory {
14531453 Normal ,
14541454}
14551455
1456- macro_rules! from_str_radix_int_impl {
1457- ( $( $t: ty) * ) => { $(
1458- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1459- impl FromStr for $t {
1460- type Err = ParseIntError ;
1461- #[ inline]
1462- fn from_str( src: & str ) -> Result <Self , ParseIntError > {
1463- <$t>:: from_str_radix( src, 10 )
1464- }
1465- }
1466- ) * }
1467- }
1468- from_str_radix_int_impl ! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
1469-
14701456/// Determines if a string of text of that length of that radix could be guaranteed to be
14711457/// stored in the given type T.
14721458/// Note that if the radix is known to the compiler, it is just the check of digits.len that
@@ -1482,18 +1468,58 @@ pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8])
14821468#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
14831469#[ cold]
14841470#[ track_caller]
1485- const fn from_str_radix_panic ( radix : u32 ) -> ! {
1471+ const fn from_ascii_radix_panic ( radix : u32 ) -> ! {
14861472 const_panic ! (
1487- "from_str_radix_int: must lie in the range `[2, 36]`" ,
1488- "from_str_radix_int: must lie in the range `[2, 36]` - found {radix}" ,
1473+ "from_ascii_radix: radix must lie in the range `[2, 36]`" ,
1474+ "from_ascii_radix: radix must lie in the range `[2, 36]` - found {radix}" ,
14891475 radix: u32 = radix,
14901476 )
14911477}
14921478
1493- macro_rules! from_str_radix {
1479+ macro_rules! from_str_int_impl {
14941480 ( $signedness: ident $( $int_ty: ty) +) => { $(
1481+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1482+ impl FromStr for $int_ty {
1483+ type Err = ParseIntError ;
1484+
1485+ /// Parses an integer from a string slice with decimal digits.
1486+ ///
1487+ /// The characters are expected to be an optional
1488+ #[ doc = sign_dependent_expr!{
1489+ $signedness ?
1490+ if signed {
1491+ " `+` or `-` "
1492+ }
1493+ if unsigned {
1494+ " `+` "
1495+ }
1496+ } ]
1497+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1498+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1499+ /// also represent an error.
1500+ ///
1501+ /// # Examples
1502+ ///
1503+ /// Basic usage:
1504+ /// ```
1505+ /// use std::str::FromStr;
1506+ ///
1507+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_str(\" +10\" ), Ok(10));" ) ]
1508+ /// ```
1509+ /// Trailing space returns error:
1510+ /// ```
1511+ /// # use std::str::FromStr;
1512+ /// #
1513+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_str(\" 1 \" ).is_err());" ) ]
1514+ /// ```
1515+ #[ inline]
1516+ fn from_str( src: & str ) -> Result <$int_ty, ParseIntError > {
1517+ <$int_ty>:: from_str_radix( src, 10 )
1518+ }
1519+ }
1520+
14951521 impl $int_ty {
1496- /// Converts a string slice in a given base to an integer .
1522+ /// Parses an integer from a string slice with digits in a given base.
14971523 ///
14981524 /// The string is expected to be an optional
14991525 #[ doc = sign_dependent_expr!{
@@ -1506,7 +1532,7 @@ macro_rules! from_str_radix {
15061532 }
15071533 } ]
15081534 /// sign followed by only digits. Leading and trailing non-digit characters (including
1509- /// whitespace) represent an error. Underscores (which are accepted in rust literals)
1535+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
15101536 /// also represent an error.
15111537 ///
15121538 /// Digits are a subset of these characters, depending on `radix`:
@@ -1532,11 +1558,92 @@ macro_rules! from_str_radix {
15321558 #[ rustc_const_stable( feature = "const_int_from_str" , since = "1.82.0" ) ]
15331559 #[ inline]
15341560 pub const fn from_str_radix( src: & str , radix: u32 ) -> Result <$int_ty, ParseIntError > {
1561+ <$int_ty>:: from_ascii_radix( src. as_bytes( ) , radix)
1562+ }
1563+
1564+ /// Parses an integer from an ASCII-byte slice with decimal digits.
1565+ ///
1566+ /// The characters are expected to be an optional
1567+ #[ doc = sign_dependent_expr!{
1568+ $signedness ?
1569+ if signed {
1570+ " `+` or `-` "
1571+ }
1572+ if unsigned {
1573+ " `+` "
1574+ }
1575+ } ]
1576+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1577+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1578+ /// also represent an error.
1579+ ///
1580+ /// # Examples
1581+ ///
1582+ /// Basic usage:
1583+ /// ```
1584+ /// #![feature(int_from_ascii)]
1585+ ///
1586+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_ascii(b\" +10\" ), Ok(10));" ) ]
1587+ /// ```
1588+ /// Trailing space returns error:
1589+ /// ```
1590+ /// # #![feature(int_from_ascii)]
1591+ /// #
1592+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_ascii(b\" 1 \" ).is_err());" ) ]
1593+ /// ```
1594+ #[ unstable( feature = "int_from_ascii" , issue = "134821" ) ]
1595+ #[ inline]
1596+ pub const fn from_ascii( src: & [ u8 ] ) -> Result <$int_ty, ParseIntError > {
1597+ <$int_ty>:: from_ascii_radix( src, 10 )
1598+ }
1599+
1600+ /// Parses an integer from an ASCII-byte slice with digits in a given base.
1601+ ///
1602+ /// The characters are expected to be an optional
1603+ #[ doc = sign_dependent_expr!{
1604+ $signedness ?
1605+ if signed {
1606+ " `+` or `-` "
1607+ }
1608+ if unsigned {
1609+ " `+` "
1610+ }
1611+ } ]
1612+ /// sign followed by only digits. Leading and trailing non-digit characters (including
1613+ /// whitespace) represent an error. Underscores (which are accepted in Rust literals)
1614+ /// also represent an error.
1615+ ///
1616+ /// Digits are a subset of these characters, depending on `radix`:
1617+ /// * `0-9`
1618+ /// * `a-z`
1619+ /// * `A-Z`
1620+ ///
1621+ /// # Panics
1622+ ///
1623+ /// This function panics if `radix` is not in the range from 2 to 36.
1624+ ///
1625+ /// # Examples
1626+ ///
1627+ /// Basic usage:
1628+ /// ```
1629+ /// #![feature(int_from_ascii)]
1630+ ///
1631+ #[ doc = concat!( "assert_eq!(" , stringify!( $int_ty) , "::from_ascii_radix(b\" A\" , 16), Ok(10));" ) ]
1632+ /// ```
1633+ /// Trailing space returns error:
1634+ /// ```
1635+ /// # #![feature(int_from_ascii)]
1636+ /// #
1637+ #[ doc = concat!( "assert!(" , stringify!( $int_ty) , "::from_ascii_radix(b\" 1 \" , 10).is_err());" ) ]
1638+ /// ```
1639+ #[ unstable( feature = "int_from_ascii" , issue = "134821" ) ]
1640+ #[ inline]
1641+ pub const fn from_ascii_radix( src: & [ u8 ] , radix: u32 ) -> Result <$int_ty, ParseIntError > {
15351642 use self :: IntErrorKind :: * ;
15361643 use self :: ParseIntError as PIE ;
15371644
15381645 if 2 > radix || radix > 36 {
1539- from_str_radix_panic ( radix) ;
1646+ from_ascii_radix_panic ( radix) ;
15401647 }
15411648
15421649 if src. is_empty( ) {
@@ -1546,12 +1653,6 @@ macro_rules! from_str_radix {
15461653 #[ allow( unused_comparisons) ]
15471654 let is_signed_ty = 0 > <$int_ty>:: MIN ;
15481655
1549- // all valid digits are ascii, so we will just iterate over the utf8 bytes
1550- // and cast them to chars. .to_digit() will safely return None for anything
1551- // other than a valid ascii digit for the given radix, including the first-byte
1552- // of multi-byte sequences
1553- let src = src. as_bytes( ) ;
1554-
15551656 let ( is_positive, mut digits) = match src {
15561657 [ b'+' | b'-' ] => {
15571658 return Err ( PIE { kind: InvalidDigit } ) ;
@@ -1627,67 +1728,8 @@ macro_rules! from_str_radix {
16271728 Ok ( result)
16281729 }
16291730 }
1630- ) +}
1631- }
1632-
1633- from_str_radix ! { unsigned u8 u16 u32 u64 u128 }
1634- from_str_radix ! { signed i8 i16 i32 i64 i128 }
1635-
1636- // Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two
1637- // identical functions.
1638- macro_rules! from_str_radix_size_impl {
1639- ( $( $signedness: ident $t: ident $size: ty) ,* ) => { $(
1640- impl $size {
1641- /// Converts a string slice in a given base to an integer.
1642- ///
1643- /// The string is expected to be an optional
1644- #[ doc = sign_dependent_expr!{
1645- $signedness ?
1646- if signed {
1647- " `+` or `-` "
1648- }
1649- if unsigned {
1650- " `+` "
1651- }
1652- } ]
1653- /// sign followed by only digits. Leading and trailing non-digit characters (including
1654- /// whitespace) represent an error. Underscores (which are accepted in rust literals)
1655- /// also represent an error.
1656- ///
1657- /// Digits are a subset of these characters, depending on `radix`:
1658- /// * `0-9`
1659- /// * `a-z`
1660- /// * `A-Z`
1661- ///
1662- /// # Panics
1663- ///
1664- /// This function panics if `radix` is not in the range from 2 to 36.
1665- ///
1666- /// # Examples
1667- ///
1668- /// Basic usage:
1669- /// ```
1670- #[ doc = concat!( "assert_eq!(" , stringify!( $size) , "::from_str_radix(\" A\" , 16), Ok(10));" ) ]
1671- /// ```
1672- /// Trailing space returns error:
1673- /// ```
1674- #[ doc = concat!( "assert!(" , stringify!( $size) , "::from_str_radix(\" 1 \" , 10).is_err());" ) ]
1675- /// ```
1676- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1677- #[ rustc_const_stable( feature = "const_int_from_str" , since = "1.82.0" ) ]
1678- #[ inline]
1679- pub const fn from_str_radix( src: & str , radix: u32 ) -> Result <$size, ParseIntError > {
1680- match <$t>:: from_str_radix( src, radix) {
1681- Ok ( x) => Ok ( x as $size) ,
1682- Err ( e) => Err ( e) ,
1683- }
1684- }
1685- } ) * }
1731+ ) * }
16861732}
16871733
1688- #[ cfg( target_pointer_width = "16" ) ]
1689- from_str_radix_size_impl ! { signed i16 isize , unsigned u16 usize }
1690- #[ cfg( target_pointer_width = "32" ) ]
1691- from_str_radix_size_impl ! { signed i32 isize , unsigned u32 usize }
1692- #[ cfg( target_pointer_width = "64" ) ]
1693- from_str_radix_size_impl ! { signed i64 isize , unsigned u64 usize }
1734+ from_str_int_impl ! { signed isize i8 i16 i32 i64 i128 }
1735+ from_str_int_impl ! { unsigned usize u8 u16 u32 u64 u128 }
0 commit comments