@@ -45,6 +45,7 @@ impl const From<char> for u32 {
4545 /// ```
4646 /// let c = 'c';
4747 /// let u = u32::from(c);
48+ ///
4849 /// assert!(4 == size_of_val(&u))
4950 /// ```
5051 #[ inline]
@@ -63,6 +64,7 @@ impl const From<char> for u64 {
6364 /// ```
6465 /// let c = '👤';
6566 /// let u = u64::from(c);
67+ ///
6668 /// assert!(8 == size_of_val(&u))
6769 /// ```
6870 #[ inline]
@@ -83,6 +85,7 @@ impl const From<char> for u128 {
8385 /// ```
8486 /// let c = '⚙';
8587 /// let u = u128::from(c);
88+ ///
8689 /// assert!(16 == size_of_val(&u))
8790 /// ```
8891 #[ inline]
@@ -93,8 +96,8 @@ impl const From<char> for u128 {
9396 }
9497}
9598
96- /// Maps a `char` with code point in U+0000..= U+00FF to a byte in 0x00..=0xFF with same value,
97- /// failing if the code point is greater than U+00FF.
99+ /// Maps a `char` with a code point from U+0000 to U+00FF (inclusive) to a byte in ` 0x00..=0xFF` with
100+ /// the same value, failing if the code point is greater than U+00FF.
98101///
99102/// See [`impl From<u8> for char`](char#impl-From<u8>-for-char) for details on the encoding.
100103#[ stable( feature = "u8_from_char" , since = "1.59.0" ) ]
@@ -109,6 +112,7 @@ impl const TryFrom<char> for u8 {
109112 /// ```
110113 /// let a = 'ÿ'; // U+00FF
111114 /// let b = 'Ā'; // U+0100
115+ ///
112116 /// assert_eq!(u8::try_from(a), Ok(0xFF_u8));
113117 /// assert!(u8::try_from(b).is_err());
114118 /// ```
@@ -122,8 +126,8 @@ impl const TryFrom<char> for u8 {
122126 }
123127}
124128
125- /// Maps a `char` with code point in U+0000..= U+FFFF to a `u16` in 0x0000..=0xFFFF with same value,
126- /// failing if the code point is greater than U+FFFF.
129+ /// Maps a `char` with a code point from U+0000 to U+FFFF (inclusive) to a `u16` in ` 0x0000..=0xFFFF`
130+ /// with the same value, failing if the code point is greater than U+FFFF.
127131///
128132/// This corresponds to the UCS-2 encoding, as specified in ISO/IEC 10646:2003.
129133#[ stable( feature = "u16_from_char" , since = "1.74.0" ) ]
@@ -138,6 +142,7 @@ impl const TryFrom<char> for u16 {
138142 /// ```
139143 /// let trans_rights = '⚧'; // U+26A7
140144 /// let ninjas = '🥷'; // U+1F977
145+ ///
141146 /// assert_eq!(u16::try_from(trans_rights), Ok(0x26A7_u16));
142147 /// assert!(u16::try_from(ninjas).is_err());
143148 /// ```
@@ -151,7 +156,45 @@ impl const TryFrom<char> for u16 {
151156 }
152157}
153158
154- /// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF.
159+ /// Maps a `char` with a code point from U+0000 to U+10FFFF (inclusive) to a `usize` in
160+ /// `0x0000..=0x10FFFF` with the same value, failing if the final value is unrepresentable by
161+ /// `usize`.
162+ ///
163+ /// Generally speaking, this conversion can be seen as obtaining the character's corresponding
164+ /// UTF-32 code point to the extent representable by pointers addresses.
165+ #[ stable( feature = "usize_try_from_char" , since = CURRENT_RUSTC_VERSION ) ]
166+ #[ rustc_const_unstable( feature = "const_convert" , issue = "143773" ) ]
167+ impl const TryFrom < char > for usize {
168+ type Error = TryFromCharError ;
169+
170+ /// Tries to convert a [`char`] into a [`usize`].
171+ ///
172+ /// # Examples
173+ ///
174+ /// ```
175+ /// let a = '\u{FFFF}'; // Always succeeds.
176+ /// let b = '\u{10FFFF}'; // Conditionally succeeds.
177+ ///
178+ /// assert_eq!(usize::try_from(a), Ok(0xFFFF));
179+ ///
180+ /// if size_of::<usize>() >= size_of::<u32>() {
181+ /// assert_eq!(usize::try_from(b), Ok(0x10FFFF));
182+ /// else {
183+ /// assert_eq!(usize::try_from(b), Err(_));
184+ /// }
185+ /// ```
186+ #[ inline]
187+ fn try_from ( c : char ) -> Result < usize , Self :: Error > {
188+ // FIXME(const-hack): this should use map_err instead
189+ match usize:: try_from ( u32:: from ( c) ) {
190+ Ok ( x) => Ok ( x) ,
191+ Err ( _) => Err ( TryFromCharError ( ( ) ) ) ,
192+ }
193+ }
194+ }
195+
196+ /// Maps a byte in `0x00..=0xFF` to a `char` whose code point has the same value from U+0000 to U+00FF
197+ /// (inclusive).
155198///
156199/// Unicode is designed such that this effectively decodes bytes
157200/// with the character encoding that IANA calls ISO-8859-1.
@@ -179,6 +222,7 @@ impl const From<u8> for char {
179222 /// ```
180223 /// let u = 32 as u8;
181224 /// let c = char::from(u);
225+ ///
182226 /// assert!(4 == size_of_val(&c))
183227 /// ```
184228 #[ inline]
@@ -246,7 +290,6 @@ const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
246290 // Subtracting 0x800 causes 0x0000..0x0800 to wrap, meaning that a single
247291 // unsigned comparison against 0x110000 - 0x800 will detect both the wrapped
248292 // surrogate range as well as the numbers originally larger than 0x110000.
249- //
250293 if ( i ^ 0xD800 ) . wrapping_sub ( 0x800 ) >= 0x110000 - 0x800 {
251294 Err ( CharTryFromError ( ( ) ) )
252295 } else {
0 commit comments