Coverage Report

Created: 2025-11-24 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.15/src/lib.rs
Line
Count
Source
1
//! [![github]](https://github.com/dtolnay/itoa) [![crates-io]](https://crates.io/crates/itoa) [![docs-rs]](https://docs.rs/itoa)
2
//!
3
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6
//!
7
//! <br>
8
//!
9
//! This crate provides a fast conversion of integer primitives to decimal
10
//! strings. The implementation comes straight from [libcore] but avoids the
11
//! performance penalty of going through [`core::fmt::Formatter`].
12
//!
13
//! See also [`ryu`] for printing floating point primitives.
14
//!
15
//! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254
16
//! [`ryu`]: https://github.com/dtolnay/ryu
17
//!
18
//! # Example
19
//!
20
//! ```
21
//! fn main() {
22
//!     let mut buffer = itoa::Buffer::new();
23
//!     let printed = buffer.format(128u64);
24
//!     assert_eq!(printed, "128");
25
//! }
26
//! ```
27
//!
28
//! # Performance (lower is better)
29
//!
30
//! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png)
31
32
#![doc(html_root_url = "https://docs.rs/itoa/1.0.15")]
33
#![no_std]
34
#![allow(
35
    clippy::cast_lossless,
36
    clippy::cast_possible_truncation,
37
    clippy::cast_possible_wrap,
38
    clippy::cast_sign_loss,
39
    clippy::expl_impl_clone_on_copy,
40
    clippy::must_use_candidate,
41
    clippy::needless_doctest_main,
42
    clippy::unreadable_literal
43
)]
44
45
mod udiv128;
46
47
use core::hint;
48
use core::mem::MaybeUninit;
49
use core::{ptr, slice, str};
50
#[cfg(feature = "no-panic")]
51
use no_panic::no_panic;
52
53
/// A correctly sized stack allocation for the formatted integer to be written
54
/// into.
55
///
56
/// # Example
57
///
58
/// ```
59
/// let mut buffer = itoa::Buffer::new();
60
/// let printed = buffer.format(1234);
61
/// assert_eq!(printed, "1234");
62
/// ```
63
pub struct Buffer {
64
    bytes: [MaybeUninit<u8>; i128::MAX_STR_LEN],
65
}
66
67
impl Default for Buffer {
68
    #[inline]
69
    fn default() -> Buffer {
70
        Buffer::new()
71
    }
72
}
73
74
impl Copy for Buffer {}
75
76
impl Clone for Buffer {
77
    #[inline]
78
    #[allow(clippy::non_canonical_clone_impl)] // false positive https://github.com/rust-lang/rust-clippy/issues/11072
79
    fn clone(&self) -> Self {
80
        Buffer::new()
81
    }
82
}
83
84
impl Buffer {
85
    /// This is a cheap operation; you don't need to worry about reusing buffers
86
    /// for efficiency.
87
    #[inline]
88
    #[cfg_attr(feature = "no-panic", no_panic)]
89
5.13M
    pub fn new() -> Buffer {
90
5.13M
        let bytes = [MaybeUninit::<u8>::uninit(); i128::MAX_STR_LEN];
91
5.13M
        Buffer { bytes }
92
5.13M
    }
<itoa::Buffer>::new
Line
Count
Source
89
80.6k
    pub fn new() -> Buffer {
90
80.6k
        let bytes = [MaybeUninit::<u8>::uninit(); i128::MAX_STR_LEN];
91
80.6k
        Buffer { bytes }
92
80.6k
    }
<itoa::Buffer>::new
Line
Count
Source
89
5.05M
    pub fn new() -> Buffer {
90
5.05M
        let bytes = [MaybeUninit::<u8>::uninit(); i128::MAX_STR_LEN];
91
5.05M
        Buffer { bytes }
92
5.05M
    }
93
94
    /// Print an integer into this buffer and return a reference to its string
95
    /// representation within the buffer.
96
    #[cfg_attr(feature = "no-panic", no_panic)]
97
5.13M
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
5.13M
        let string = i.write(unsafe {
99
5.13M
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
5.13M
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
5.13M
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
5.13M
        }
105
5.13M
        string
106
5.13M
    }
<itoa::Buffer>::format::<i8>
Line
Count
Source
97
8.56k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
8.56k
        let string = i.write(unsafe {
99
8.56k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
8.56k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
8.56k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
8.56k
        }
105
8.56k
        string
106
8.56k
    }
<itoa::Buffer>::format::<u8>
Line
Count
Source
97
2.27k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
2.27k
        let string = i.write(unsafe {
99
2.27k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
2.27k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
2.27k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
2.27k
        }
105
2.27k
        string
106
2.27k
    }
<itoa::Buffer>::format::<i32>
Line
Count
Source
97
50.2k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
50.2k
        let string = i.write(unsafe {
99
50.2k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
50.2k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
50.2k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
50.2k
        }
105
50.2k
        string
106
50.2k
    }
<itoa::Buffer>::format::<u32>
Line
Count
Source
97
3.18k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
3.18k
        let string = i.write(unsafe {
99
3.18k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
3.18k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
3.18k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
3.18k
        }
105
3.18k
        string
106
3.18k
    }
<itoa::Buffer>::format::<i128>
Line
Count
Source
97
2.93k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
2.93k
        let string = i.write(unsafe {
99
2.93k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
2.93k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
2.93k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
2.93k
        }
105
2.93k
        string
106
2.93k
    }
<itoa::Buffer>::format::<u128>
Line
Count
Source
97
2.23k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
2.23k
        let string = i.write(unsafe {
99
2.23k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
2.23k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
2.23k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
2.23k
        }
105
2.23k
        string
106
2.23k
    }
<itoa::Buffer>::format::<i16>
Line
Count
Source
97
2.32k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
2.32k
        let string = i.write(unsafe {
99
2.32k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
2.32k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
2.32k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
2.32k
        }
105
2.32k
        string
106
2.32k
    }
<itoa::Buffer>::format::<u16>
Line
Count
Source
97
2.14k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
2.14k
        let string = i.write(unsafe {
99
2.14k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
2.14k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
2.14k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
2.14k
        }
105
2.14k
        string
106
2.14k
    }
<itoa::Buffer>::format::<i64>
Line
Count
Source
97
3.22k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
3.22k
        let string = i.write(unsafe {
99
3.22k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
3.22k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
3.22k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
3.22k
        }
105
3.22k
        string
106
3.22k
    }
<itoa::Buffer>::format::<u64>
Line
Count
Source
97
3.42k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
3.42k
        let string = i.write(unsafe {
99
3.42k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
3.42k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
3.42k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
3.42k
        }
105
3.42k
        string
106
3.42k
    }
<itoa::Buffer>::format::<i8>
Line
Count
Source
97
839k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
839k
        let string = i.write(unsafe {
99
839k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
839k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
839k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
839k
        }
105
839k
        string
106
839k
    }
<itoa::Buffer>::format::<u8>
Line
Count
Source
97
334k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
334k
        let string = i.write(unsafe {
99
334k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
334k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
334k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
334k
        }
105
334k
        string
106
334k
    }
<itoa::Buffer>::format::<u32>
Line
Count
Source
97
312k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
312k
        let string = i.write(unsafe {
99
312k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
312k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
312k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
312k
        }
105
312k
        string
106
312k
    }
<itoa::Buffer>::format::<u16>
Line
Count
Source
97
507k
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
507k
        let string = i.write(unsafe {
99
507k
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
507k
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
507k
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
507k
        }
105
507k
        string
106
507k
    }
<itoa::Buffer>::format::<u64>
Line
Count
Source
97
3.06M
    pub fn format<I: Integer>(&mut self, i: I) -> &str {
98
3.06M
        let string = i.write(unsafe {
99
3.06M
            &mut *(&mut self.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN]
100
3.06M
                as *mut <I as private::Sealed>::Buffer)
101
        });
102
3.06M
        if string.len() > I::MAX_STR_LEN {
103
0
            unsafe { hint::unreachable_unchecked() };
104
3.06M
        }
105
3.06M
        string
106
3.06M
    }
107
}
108
109
/// An integer that can be written into an [`itoa::Buffer`][Buffer].
110
///
111
/// This trait is sealed and cannot be implemented for types outside of itoa.
112
pub trait Integer: private::Sealed {
113
    /// The maximum length of string that formatting an integer of this type can
114
    /// produce on the current target platform.
115
    const MAX_STR_LEN: usize;
116
}
117
118
// Seal to prevent downstream implementations of the Integer trait.
119
mod private {
120
    #[doc(hidden)]
121
    pub trait Sealed: Copy {
122
        #[doc(hidden)]
123
        type Buffer: 'static;
124
        fn write(self, buf: &mut Self::Buffer) -> &str;
125
    }
126
}
127
128
const DEC_DIGITS_LUT: [u8; 200] = *b"\
129
      0001020304050607080910111213141516171819\
130
      2021222324252627282930313233343536373839\
131
      4041424344454647484950515253545556575859\
132
      6061626364656667686970717273747576777879\
133
      8081828384858687888990919293949596979899";
134
135
// Adaptation of the original implementation at
136
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
137
macro_rules! impl_Integer {
138
    ($t:ty[len = $max_len:expr] as $large_unsigned:ty) => {
139
        impl Integer for $t {
140
            const MAX_STR_LEN: usize = $max_len;
141
        }
142
143
        impl private::Sealed for $t {
144
            type Buffer = [MaybeUninit<u8>; $max_len];
145
146
            #[allow(unused_comparisons)]
147
            #[inline]
148
            #[cfg_attr(feature = "no-panic", no_panic)]
149
5.13M
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
5.13M
                let is_nonnegative = self >= 0;
151
5.13M
                let mut n = if is_nonnegative {
152
4.74M
                    self as $large_unsigned
153
391k
                } else {
154
391k
                    // Convert negative number to positive by summing 1 to its two's complement.
155
391k
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
5.13M
                let mut curr = buf.len();
158
5.13M
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
5.13M
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
18.5M
                while n >= 10000 {
163
13.3M
                    let rem = n % 10000;
164
13.3M
                    n /= 10000;
165
166
13.3M
                    let d1 = ((rem / 100) << 1) as usize;
167
13.3M
                    let d2 = ((rem % 100) << 1) as usize;
168
13.3M
                    curr -= 4;
169
13.3M
                    unsafe {
170
13.3M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
13.3M
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
13.3M
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
5.13M
                if n >= 100 {
177
3.70M
                    let d1 = ((n % 100) << 1) as usize;
178
3.70M
                    n /= 100;
179
3.70M
                    curr -= 2;
180
3.70M
                    unsafe {
181
3.70M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
3.70M
                    }
183
1.43M
                }
184
185
                // Render last 1 or 2 digits.
186
5.13M
                if n < 10 {
187
3.23M
                    curr -= 1;
188
3.23M
                    unsafe {
189
3.23M
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
3.23M
                    }
191
                } else {
192
1.90M
                    let d1 = (n << 1) as usize;
193
1.90M
                    curr -= 2;
194
1.90M
                    unsafe {
195
1.90M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.90M
                    }
197
                }
198
199
5.13M
                if !is_nonnegative {
200
391k
                    curr -= 1;
201
391k
                    unsafe {
202
391k
                        *buf_ptr.add(curr) = b'-';
203
391k
                    }
204
4.74M
                }
205
206
5.13M
                let len = buf.len() - curr;
207
5.13M
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
5.13M
                unsafe { str::from_utf8_unchecked(bytes) }
209
5.13M
            }
<i8 as itoa::private::Sealed>::write
Line
Count
Source
149
8.56k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
8.56k
                let is_nonnegative = self >= 0;
151
8.56k
                let mut n = if is_nonnegative {
152
7.93k
                    self as $large_unsigned
153
629
                } else {
154
629
                    // Convert negative number to positive by summing 1 to its two's complement.
155
629
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
8.56k
                let mut curr = buf.len();
158
8.56k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
8.56k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
8.56k
                while n >= 10000 {
163
0
                    let rem = n % 10000;
164
0
                    n /= 10000;
165
166
0
                    let d1 = ((rem / 100) << 1) as usize;
167
0
                    let d2 = ((rem % 100) << 1) as usize;
168
0
                    curr -= 4;
169
0
                    unsafe {
170
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
0
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
8.56k
                if n >= 100 {
177
268
                    let d1 = ((n % 100) << 1) as usize;
178
268
                    n /= 100;
179
268
                    curr -= 2;
180
268
                    unsafe {
181
268
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
268
                    }
183
8.29k
                }
184
185
                // Render last 1 or 2 digits.
186
8.56k
                if n < 10 {
187
5.24k
                    curr -= 1;
188
5.24k
                    unsafe {
189
5.24k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
5.24k
                    }
191
                } else {
192
3.32k
                    let d1 = (n << 1) as usize;
193
3.32k
                    curr -= 2;
194
3.32k
                    unsafe {
195
3.32k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
3.32k
                    }
197
                }
198
199
8.56k
                if !is_nonnegative {
200
629
                    curr -= 1;
201
629
                    unsafe {
202
629
                        *buf_ptr.add(curr) = b'-';
203
629
                    }
204
7.93k
                }
205
206
8.56k
                let len = buf.len() - curr;
207
8.56k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
8.56k
                unsafe { str::from_utf8_unchecked(bytes) }
209
8.56k
            }
<u8 as itoa::private::Sealed>::write
Line
Count
Source
149
2.27k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
2.27k
                let is_nonnegative = self >= 0;
151
2.27k
                let mut n = if is_nonnegative {
152
2.27k
                    self as $large_unsigned
153
0
                } else {
154
0
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
2.27k
                let mut curr = buf.len();
158
2.27k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
2.27k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
2.27k
                while n >= 10000 {
163
0
                    let rem = n % 10000;
164
0
                    n /= 10000;
165
166
0
                    let d1 = ((rem / 100) << 1) as usize;
167
0
                    let d2 = ((rem % 100) << 1) as usize;
168
0
                    curr -= 4;
169
0
                    unsafe {
170
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
0
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
2.27k
                if n >= 100 {
177
56
                    let d1 = ((n % 100) << 1) as usize;
178
56
                    n /= 100;
179
56
                    curr -= 2;
180
56
                    unsafe {
181
56
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
56
                    }
183
2.21k
                }
184
185
                // Render last 1 or 2 digits.
186
2.27k
                if n < 10 {
187
1.00k
                    curr -= 1;
188
1.00k
                    unsafe {
189
1.00k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.00k
                    }
191
                } else {
192
1.26k
                    let d1 = (n << 1) as usize;
193
1.26k
                    curr -= 2;
194
1.26k
                    unsafe {
195
1.26k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.26k
                    }
197
                }
198
199
2.27k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
2.27k
                }
205
206
2.27k
                let len = buf.len() - curr;
207
2.27k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
2.27k
                unsafe { str::from_utf8_unchecked(bytes) }
209
2.27k
            }
<i16 as itoa::private::Sealed>::write
Line
Count
Source
149
2.32k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
2.32k
                let is_nonnegative = self >= 0;
151
2.32k
                let mut n = if is_nonnegative {
152
2.17k
                    self as $large_unsigned
153
151
                } else {
154
151
                    // Convert negative number to positive by summing 1 to its two's complement.
155
151
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
2.32k
                let mut curr = buf.len();
158
2.32k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
2.32k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
2.36k
                while n >= 10000 {
163
36
                    let rem = n % 10000;
164
36
                    n /= 10000;
165
166
36
                    let d1 = ((rem / 100) << 1) as usize;
167
36
                    let d2 = ((rem % 100) << 1) as usize;
168
36
                    curr -= 4;
169
36
                    unsafe {
170
36
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
36
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
36
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
2.32k
                if n >= 100 {
177
329
                    let d1 = ((n % 100) << 1) as usize;
178
329
                    n /= 100;
179
329
                    curr -= 2;
180
329
                    unsafe {
181
329
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
329
                    }
183
2.00k
                }
184
185
                // Render last 1 or 2 digits.
186
2.32k
                if n < 10 {
187
1.32k
                    curr -= 1;
188
1.32k
                    unsafe {
189
1.32k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.32k
                    }
191
                } else {
192
1.00k
                    let d1 = (n << 1) as usize;
193
1.00k
                    curr -= 2;
194
1.00k
                    unsafe {
195
1.00k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.00k
                    }
197
                }
198
199
2.32k
                if !is_nonnegative {
200
151
                    curr -= 1;
201
151
                    unsafe {
202
151
                        *buf_ptr.add(curr) = b'-';
203
151
                    }
204
2.17k
                }
205
206
2.32k
                let len = buf.len() - curr;
207
2.32k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
2.32k
                unsafe { str::from_utf8_unchecked(bytes) }
209
2.32k
            }
<u16 as itoa::private::Sealed>::write
Line
Count
Source
149
2.14k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
2.14k
                let is_nonnegative = self >= 0;
151
2.14k
                let mut n = if is_nonnegative {
152
2.14k
                    self as $large_unsigned
153
0
                } else {
154
0
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
2.14k
                let mut curr = buf.len();
158
2.14k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
2.14k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
2.21k
                while n >= 10000 {
163
69
                    let rem = n % 10000;
164
69
                    n /= 10000;
165
166
69
                    let d1 = ((rem / 100) << 1) as usize;
167
69
                    let d2 = ((rem % 100) << 1) as usize;
168
69
                    curr -= 4;
169
69
                    unsafe {
170
69
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
69
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
69
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
2.14k
                if n >= 100 {
177
278
                    let d1 = ((n % 100) << 1) as usize;
178
278
                    n /= 100;
179
278
                    curr -= 2;
180
278
                    unsafe {
181
278
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
278
                    }
183
1.86k
                }
184
185
                // Render last 1 or 2 digits.
186
2.14k
                if n < 10 {
187
1.11k
                    curr -= 1;
188
1.11k
                    unsafe {
189
1.11k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.11k
                    }
191
                } else {
192
1.03k
                    let d1 = (n << 1) as usize;
193
1.03k
                    curr -= 2;
194
1.03k
                    unsafe {
195
1.03k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.03k
                    }
197
                }
198
199
2.14k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
2.14k
                }
205
206
2.14k
                let len = buf.len() - curr;
207
2.14k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
2.14k
                unsafe { str::from_utf8_unchecked(bytes) }
209
2.14k
            }
<i32 as itoa::private::Sealed>::write
Line
Count
Source
149
50.2k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
50.2k
                let is_nonnegative = self >= 0;
151
50.2k
                let mut n = if is_nonnegative {
152
45.6k
                    self as $large_unsigned
153
4.62k
                } else {
154
4.62k
                    // Convert negative number to positive by summing 1 to its two's complement.
155
4.62k
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
50.2k
                let mut curr = buf.len();
158
50.2k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
50.2k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
84.9k
                while n >= 10000 {
163
34.7k
                    let rem = n % 10000;
164
34.7k
                    n /= 10000;
165
166
34.7k
                    let d1 = ((rem / 100) << 1) as usize;
167
34.7k
                    let d2 = ((rem % 100) << 1) as usize;
168
34.7k
                    curr -= 4;
169
34.7k
                    unsafe {
170
34.7k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
34.7k
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
34.7k
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
50.2k
                if n >= 100 {
177
13.4k
                    let d1 = ((n % 100) << 1) as usize;
178
13.4k
                    n /= 100;
179
13.4k
                    curr -= 2;
180
13.4k
                    unsafe {
181
13.4k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
13.4k
                    }
183
36.8k
                }
184
185
                // Render last 1 or 2 digits.
186
50.2k
                if n < 10 {
187
31.6k
                    curr -= 1;
188
31.6k
                    unsafe {
189
31.6k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
31.6k
                    }
191
                } else {
192
18.6k
                    let d1 = (n << 1) as usize;
193
18.6k
                    curr -= 2;
194
18.6k
                    unsafe {
195
18.6k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
18.6k
                    }
197
                }
198
199
50.2k
                if !is_nonnegative {
200
4.62k
                    curr -= 1;
201
4.62k
                    unsafe {
202
4.62k
                        *buf_ptr.add(curr) = b'-';
203
4.62k
                    }
204
45.6k
                }
205
206
50.2k
                let len = buf.len() - curr;
207
50.2k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
50.2k
                unsafe { str::from_utf8_unchecked(bytes) }
209
50.2k
            }
<u32 as itoa::private::Sealed>::write
Line
Count
Source
149
3.18k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
3.18k
                let is_nonnegative = self >= 0;
151
3.18k
                let mut n = if is_nonnegative {
152
3.18k
                    self as $large_unsigned
153
                } else {
154
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
3.18k
                let mut curr = buf.len();
158
3.18k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
3.18k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
3.39k
                while n >= 10000 {
163
207
                    let rem = n % 10000;
164
207
                    n /= 10000;
165
166
207
                    let d1 = ((rem / 100) << 1) as usize;
167
207
                    let d2 = ((rem % 100) << 1) as usize;
168
207
                    curr -= 4;
169
207
                    unsafe {
170
207
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
207
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
207
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
3.18k
                if n >= 100 {
177
419
                    let d1 = ((n % 100) << 1) as usize;
178
419
                    n /= 100;
179
419
                    curr -= 2;
180
419
                    unsafe {
181
419
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
419
                    }
183
2.76k
                }
184
185
                // Render last 1 or 2 digits.
186
3.18k
                if n < 10 {
187
1.42k
                    curr -= 1;
188
1.42k
                    unsafe {
189
1.42k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.42k
                    }
191
                } else {
192
1.76k
                    let d1 = (n << 1) as usize;
193
1.76k
                    curr -= 2;
194
1.76k
                    unsafe {
195
1.76k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.76k
                    }
197
                }
198
199
3.18k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
3.18k
                }
205
206
3.18k
                let len = buf.len() - curr;
207
3.18k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
3.18k
                unsafe { str::from_utf8_unchecked(bytes) }
209
3.18k
            }
<i64 as itoa::private::Sealed>::write
Line
Count
Source
149
3.22k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
3.22k
                let is_nonnegative = self >= 0;
151
3.22k
                let mut n = if is_nonnegative {
152
3.07k
                    self as $large_unsigned
153
151
                } else {
154
151
                    // Convert negative number to positive by summing 1 to its two's complement.
155
151
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
3.22k
                let mut curr = buf.len();
158
3.22k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
3.22k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
3.87k
                while n >= 10000 {
163
643
                    let rem = n % 10000;
164
643
                    n /= 10000;
165
166
643
                    let d1 = ((rem / 100) << 1) as usize;
167
643
                    let d2 = ((rem % 100) << 1) as usize;
168
643
                    curr -= 4;
169
643
                    unsafe {
170
643
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
643
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
643
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
3.22k
                if n >= 100 {
177
499
                    let d1 = ((n % 100) << 1) as usize;
178
499
                    n /= 100;
179
499
                    curr -= 2;
180
499
                    unsafe {
181
499
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
499
                    }
183
2.72k
                }
184
185
                // Render last 1 or 2 digits.
186
3.22k
                if n < 10 {
187
1.44k
                    curr -= 1;
188
1.44k
                    unsafe {
189
1.44k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.44k
                    }
191
                } else {
192
1.78k
                    let d1 = (n << 1) as usize;
193
1.78k
                    curr -= 2;
194
1.78k
                    unsafe {
195
1.78k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.78k
                    }
197
                }
198
199
3.22k
                if !is_nonnegative {
200
151
                    curr -= 1;
201
151
                    unsafe {
202
151
                        *buf_ptr.add(curr) = b'-';
203
151
                    }
204
3.07k
                }
205
206
3.22k
                let len = buf.len() - curr;
207
3.22k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
3.22k
                unsafe { str::from_utf8_unchecked(bytes) }
209
3.22k
            }
<u64 as itoa::private::Sealed>::write
Line
Count
Source
149
8.94k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
8.94k
                let is_nonnegative = self >= 0;
151
8.94k
                let mut n = if is_nonnegative {
152
8.94k
                    self as $large_unsigned
153
                } else {
154
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
8.94k
                let mut curr = buf.len();
158
8.94k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
8.94k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
12.2k
                while n >= 10000 {
163
3.27k
                    let rem = n % 10000;
164
3.27k
                    n /= 10000;
165
166
3.27k
                    let d1 = ((rem / 100) << 1) as usize;
167
3.27k
                    let d2 = ((rem % 100) << 1) as usize;
168
3.27k
                    curr -= 4;
169
3.27k
                    unsafe {
170
3.27k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
3.27k
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
3.27k
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
8.94k
                if n >= 100 {
177
1.73k
                    let d1 = ((n % 100) << 1) as usize;
178
1.73k
                    n /= 100;
179
1.73k
                    curr -= 2;
180
1.73k
                    unsafe {
181
1.73k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
1.73k
                    }
183
7.21k
                }
184
185
                // Render last 1 or 2 digits.
186
8.94k
                if n < 10 {
187
4.38k
                    curr -= 1;
188
4.38k
                    unsafe {
189
4.38k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
4.38k
                    }
191
                } else {
192
4.55k
                    let d1 = (n << 1) as usize;
193
4.55k
                    curr -= 2;
194
4.55k
                    unsafe {
195
4.55k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
4.55k
                    }
197
                }
198
199
8.94k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
8.94k
                }
205
206
8.94k
                let len = buf.len() - curr;
207
8.94k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
8.94k
                unsafe { str::from_utf8_unchecked(bytes) }
209
8.94k
            }
<i8 as itoa::private::Sealed>::write
Line
Count
Source
149
839k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
839k
                let is_nonnegative = self >= 0;
151
839k
                let mut n = if is_nonnegative {
152
453k
                    self as $large_unsigned
153
386k
                } else {
154
386k
                    // Convert negative number to positive by summing 1 to its two's complement.
155
386k
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
839k
                let mut curr = buf.len();
158
839k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
839k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
839k
                while n >= 10000 {
163
0
                    let rem = n % 10000;
164
0
                    n /= 10000;
165
166
0
                    let d1 = ((rem / 100) << 1) as usize;
167
0
                    let d2 = ((rem % 100) << 1) as usize;
168
0
                    curr -= 4;
169
0
                    unsafe {
170
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
0
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
839k
                if n >= 100 {
177
376k
                    let d1 = ((n % 100) << 1) as usize;
178
376k
                    n /= 100;
179
376k
                    curr -= 2;
180
376k
                    unsafe {
181
376k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
376k
                    }
183
462k
                }
184
185
                // Render last 1 or 2 digits.
186
839k
                if n < 10 {
187
771k
                    curr -= 1;
188
771k
                    unsafe {
189
771k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
771k
                    }
191
                } else {
192
68.5k
                    let d1 = (n << 1) as usize;
193
68.5k
                    curr -= 2;
194
68.5k
                    unsafe {
195
68.5k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
68.5k
                    }
197
                }
198
199
839k
                if !is_nonnegative {
200
386k
                    curr -= 1;
201
386k
                    unsafe {
202
386k
                        *buf_ptr.add(curr) = b'-';
203
386k
                    }
204
453k
                }
205
206
839k
                let len = buf.len() - curr;
207
839k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
839k
                unsafe { str::from_utf8_unchecked(bytes) }
209
839k
            }
<u8 as itoa::private::Sealed>::write
Line
Count
Source
149
334k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
334k
                let is_nonnegative = self >= 0;
151
334k
                let mut n = if is_nonnegative {
152
334k
                    self as $large_unsigned
153
0
                } else {
154
0
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
334k
                let mut curr = buf.len();
158
334k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
334k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
334k
                while n >= 10000 {
163
0
                    let rem = n % 10000;
164
0
                    n /= 10000;
165
166
0
                    let d1 = ((rem / 100) << 1) as usize;
167
0
                    let d2 = ((rem % 100) << 1) as usize;
168
0
                    curr -= 4;
169
0
                    unsafe {
170
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
0
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
0
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
334k
                if n >= 100 {
177
312k
                    let d1 = ((n % 100) << 1) as usize;
178
312k
                    n /= 100;
179
312k
                    curr -= 2;
180
312k
                    unsafe {
181
312k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
312k
                    }
183
22.3k
                }
184
185
                // Render last 1 or 2 digits.
186
334k
                if n < 10 {
187
312k
                    curr -= 1;
188
312k
                    unsafe {
189
312k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
312k
                    }
191
                } else {
192
21.7k
                    let d1 = (n << 1) as usize;
193
21.7k
                    curr -= 2;
194
21.7k
                    unsafe {
195
21.7k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
21.7k
                    }
197
                }
198
199
334k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
334k
                }
205
206
334k
                let len = buf.len() - curr;
207
334k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
334k
                unsafe { str::from_utf8_unchecked(bytes) }
209
334k
            }
<u16 as itoa::private::Sealed>::write
Line
Count
Source
149
507k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
507k
                let is_nonnegative = self >= 0;
151
507k
                let mut n = if is_nonnegative {
152
507k
                    self as $large_unsigned
153
0
                } else {
154
0
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
507k
                let mut curr = buf.len();
158
507k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
507k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
1.00M
                while n >= 10000 {
163
500k
                    let rem = n % 10000;
164
500k
                    n /= 10000;
165
166
500k
                    let d1 = ((rem / 100) << 1) as usize;
167
500k
                    let d2 = ((rem % 100) << 1) as usize;
168
500k
                    curr -= 4;
169
500k
                    unsafe {
170
500k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
500k
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
500k
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
507k
                if n >= 100 {
177
6.01k
                    let d1 = ((n % 100) << 1) as usize;
178
6.01k
                    n /= 100;
179
6.01k
                    curr -= 2;
180
6.01k
                    unsafe {
181
6.01k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
6.01k
                    }
183
501k
                }
184
185
                // Render last 1 or 2 digits.
186
507k
                if n < 10 {
187
501k
                    curr -= 1;
188
501k
                    unsafe {
189
501k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
501k
                    }
191
                } else {
192
5.86k
                    let d1 = (n << 1) as usize;
193
5.86k
                    curr -= 2;
194
5.86k
                    unsafe {
195
5.86k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
5.86k
                    }
197
                }
198
199
507k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
507k
                }
205
206
507k
                let len = buf.len() - curr;
207
507k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
507k
                unsafe { str::from_utf8_unchecked(bytes) }
209
507k
            }
<u32 as itoa::private::Sealed>::write
Line
Count
Source
149
312k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
312k
                let is_nonnegative = self >= 0;
151
312k
                let mut n = if is_nonnegative {
152
312k
                    self as $large_unsigned
153
                } else {
154
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
312k
                let mut curr = buf.len();
158
312k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
312k
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
933k
                while n >= 10000 {
163
621k
                    let rem = n % 10000;
164
621k
                    n /= 10000;
165
166
621k
                    let d1 = ((rem / 100) << 1) as usize;
167
621k
                    let d2 = ((rem % 100) << 1) as usize;
168
621k
                    curr -= 4;
169
621k
                    unsafe {
170
621k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
621k
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
621k
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
312k
                if n >= 100 {
177
2.36k
                    let d1 = ((n % 100) << 1) as usize;
178
2.36k
                    n /= 100;
179
2.36k
                    curr -= 2;
180
2.36k
                    unsafe {
181
2.36k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
2.36k
                    }
183
309k
                }
184
185
                // Render last 1 or 2 digits.
186
312k
                if n < 10 {
187
12.6k
                    curr -= 1;
188
12.6k
                    unsafe {
189
12.6k
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
12.6k
                    }
191
                } else {
192
299k
                    let d1 = (n << 1) as usize;
193
299k
                    curr -= 2;
194
299k
                    unsafe {
195
299k
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
299k
                    }
197
                }
198
199
312k
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
312k
                }
205
206
312k
                let len = buf.len() - curr;
207
312k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
312k
                unsafe { str::from_utf8_unchecked(bytes) }
209
312k
            }
<u64 as itoa::private::Sealed>::write
Line
Count
Source
149
3.06M
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
150
3.06M
                let is_nonnegative = self >= 0;
151
3.06M
                let mut n = if is_nonnegative {
152
3.06M
                    self as $large_unsigned
153
                } else {
154
                    // Convert negative number to positive by summing 1 to its two's complement.
155
0
                    (!(self as $large_unsigned)).wrapping_add(1)
156
                };
157
3.06M
                let mut curr = buf.len();
158
3.06M
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
159
3.06M
                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
160
161
                // Render 4 digits at a time.
162
15.3M
                while n >= 10000 {
163
12.2M
                    let rem = n % 10000;
164
12.2M
                    n /= 10000;
165
166
12.2M
                    let d1 = ((rem / 100) << 1) as usize;
167
12.2M
                    let d2 = ((rem % 100) << 1) as usize;
168
12.2M
                    curr -= 4;
169
12.2M
                    unsafe {
170
12.2M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
171
12.2M
                        ptr::copy_nonoverlapping(lut_ptr.add(d2), buf_ptr.add(curr + 2), 2);
172
12.2M
                    }
173
                }
174
175
                // Render 2 more digits, if >2 digits.
176
3.06M
                if n >= 100 {
177
2.99M
                    let d1 = ((n % 100) << 1) as usize;
178
2.99M
                    n /= 100;
179
2.99M
                    curr -= 2;
180
2.99M
                    unsafe {
181
2.99M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
182
2.99M
                    }
183
71.6k
                }
184
185
                // Render last 1 or 2 digits.
186
3.06M
                if n < 10 {
187
1.59M
                    curr -= 1;
188
1.59M
                    unsafe {
189
1.59M
                        *buf_ptr.add(curr) = (n as u8) + b'0';
190
1.59M
                    }
191
                } else {
192
1.47M
                    let d1 = (n << 1) as usize;
193
1.47M
                    curr -= 2;
194
1.47M
                    unsafe {
195
1.47M
                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
196
1.47M
                    }
197
                }
198
199
3.06M
                if !is_nonnegative {
200
0
                    curr -= 1;
201
0
                    unsafe {
202
0
                        *buf_ptr.add(curr) = b'-';
203
0
                    }
204
3.06M
                }
205
206
3.06M
                let len = buf.len() - curr;
207
3.06M
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
208
3.06M
                unsafe { str::from_utf8_unchecked(bytes) }
209
3.06M
            }
210
        }
211
    };
212
}
213
214
impl_Integer!(i8[len = 4] as u32);
215
impl_Integer!(u8[len = 3] as u32);
216
impl_Integer!(i16[len = 6] as u32);
217
impl_Integer!(u16[len = 5] as u32);
218
impl_Integer!(i32[len = 11] as u32);
219
impl_Integer!(u32[len = 10] as u32);
220
impl_Integer!(i64[len = 20] as u64);
221
impl_Integer!(u64[len = 20] as u64);
222
223
macro_rules! impl_Integer_size {
224
    ($t:ty as $primitive:ident #[cfg(target_pointer_width = $width:literal)]) => {
225
        #[cfg(target_pointer_width = $width)]
226
        impl Integer for $t {
227
            const MAX_STR_LEN: usize = <$primitive as Integer>::MAX_STR_LEN;
228
        }
229
230
        #[cfg(target_pointer_width = $width)]
231
        impl private::Sealed for $t {
232
            type Buffer = <$primitive as private::Sealed>::Buffer;
233
234
            #[inline]
235
            #[cfg_attr(feature = "no-panic", no_panic)]
236
            fn write(self, buf: &mut Self::Buffer) -> &str {
237
                (self as $primitive).write(buf)
238
            }
239
        }
240
    };
241
}
242
243
impl_Integer_size!(isize as i16 #[cfg(target_pointer_width = "16")]);
244
impl_Integer_size!(usize as u16 #[cfg(target_pointer_width = "16")]);
245
impl_Integer_size!(isize as i32 #[cfg(target_pointer_width = "32")]);
246
impl_Integer_size!(usize as u32 #[cfg(target_pointer_width = "32")]);
247
impl_Integer_size!(isize as i64 #[cfg(target_pointer_width = "64")]);
248
impl_Integer_size!(usize as u64 #[cfg(target_pointer_width = "64")]);
249
250
macro_rules! impl_Integer128 {
251
    ($t:ty[len = $max_len:expr]) => {
252
        impl Integer for $t {
253
            const MAX_STR_LEN: usize = $max_len;
254
        }
255
256
        impl private::Sealed for $t {
257
            type Buffer = [MaybeUninit<u8>; $max_len];
258
259
            #[allow(unused_comparisons)]
260
            #[inline]
261
            #[cfg_attr(feature = "no-panic", no_panic)]
262
5.17k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
263
5.17k
                let is_nonnegative = self >= 0;
264
5.17k
                let n = if is_nonnegative {
265
2.23k
                    self as u128
266
                } else {
267
                    // Convert negative number to positive by summing 1 to its two's complement.
268
116
                    (!(self as u128)).wrapping_add(1)
269
                };
270
5.17k
                let mut curr = buf.len();
271
5.17k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
272
273
                // Divide by 10^19 which is the highest power less than 2^64.
274
5.17k
                let (n, rem) = udiv128::udivmod_1e19(n);
275
5.17k
                let buf1 = unsafe {
276
5.17k
                    buf_ptr.add(curr - u64::MAX_STR_LEN) as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
277
                };
278
5.17k
                curr -= rem.write(unsafe { &mut *buf1 }).len();
279
280
5.17k
                if n != 0 {
281
                    // Memset the base10 leading zeros of rem.
282
348
                    let target = buf.len() - 19;
283
348
                    unsafe {
284
348
                        ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
285
348
                    }
286
348
                    curr = target;
287
288
                    // Divide by 10^19 again.
289
348
                    let (n, rem) = udiv128::udivmod_1e19(n);
290
348
                    let buf2 = unsafe {
291
348
                        buf_ptr.add(curr - u64::MAX_STR_LEN)
292
348
                            as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
293
                    };
294
348
                    curr -= rem.write(unsafe { &mut *buf2 }).len();
295
296
348
                    if n != 0 {
297
                        // Memset the leading zeros.
298
30
                        let target = buf.len() - 38;
299
30
                        unsafe {
300
30
                            ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
301
30
                        }
302
30
                        curr = target;
303
304
                        // There is at most one digit left
305
                        // because u128::MAX / 10^19 / 10^19 is 3.
306
30
                        curr -= 1;
307
30
                        unsafe {
308
30
                            *buf_ptr.add(curr) = (n as u8) + b'0';
309
30
                        }
310
318
                    }
311
4.82k
                }
312
313
5.17k
                if !is_nonnegative {
314
116
                    curr -= 1;
315
116
                    unsafe {
316
116
                        *buf_ptr.add(curr) = b'-';
317
116
                    }
318
5.05k
                }
319
320
5.17k
                let len = buf.len() - curr;
321
5.17k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
322
5.17k
                unsafe { str::from_utf8_unchecked(bytes) }
323
5.17k
            }
<i128 as itoa::private::Sealed>::write
Line
Count
Source
262
2.93k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
263
2.93k
                let is_nonnegative = self >= 0;
264
2.93k
                let n = if is_nonnegative {
265
2.82k
                    self as u128
266
                } else {
267
                    // Convert negative number to positive by summing 1 to its two's complement.
268
116
                    (!(self as u128)).wrapping_add(1)
269
                };
270
2.93k
                let mut curr = buf.len();
271
2.93k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
272
273
                // Divide by 10^19 which is the highest power less than 2^64.
274
2.93k
                let (n, rem) = udiv128::udivmod_1e19(n);
275
2.93k
                let buf1 = unsafe {
276
2.93k
                    buf_ptr.add(curr - u64::MAX_STR_LEN) as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
277
                };
278
2.93k
                curr -= rem.write(unsafe { &mut *buf1 }).len();
279
280
2.93k
                if n != 0 {
281
                    // Memset the base10 leading zeros of rem.
282
204
                    let target = buf.len() - 19;
283
204
                    unsafe {
284
204
                        ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
285
204
                    }
286
204
                    curr = target;
287
288
                    // Divide by 10^19 again.
289
204
                    let (n, rem) = udiv128::udivmod_1e19(n);
290
204
                    let buf2 = unsafe {
291
204
                        buf_ptr.add(curr - u64::MAX_STR_LEN)
292
204
                            as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
293
                    };
294
204
                    curr -= rem.write(unsafe { &mut *buf2 }).len();
295
296
204
                    if n != 0 {
297
                        // Memset the leading zeros.
298
11
                        let target = buf.len() - 38;
299
11
                        unsafe {
300
11
                            ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
301
11
                        }
302
11
                        curr = target;
303
304
                        // There is at most one digit left
305
                        // because u128::MAX / 10^19 / 10^19 is 3.
306
11
                        curr -= 1;
307
11
                        unsafe {
308
11
                            *buf_ptr.add(curr) = (n as u8) + b'0';
309
11
                        }
310
193
                    }
311
2.73k
                }
312
313
2.93k
                if !is_nonnegative {
314
116
                    curr -= 1;
315
116
                    unsafe {
316
116
                        *buf_ptr.add(curr) = b'-';
317
116
                    }
318
2.82k
                }
319
320
2.93k
                let len = buf.len() - curr;
321
2.93k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
322
2.93k
                unsafe { str::from_utf8_unchecked(bytes) }
323
2.93k
            }
<u128 as itoa::private::Sealed>::write
Line
Count
Source
262
2.23k
            fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
263
2.23k
                let is_nonnegative = self >= 0;
264
2.23k
                let n = if is_nonnegative {
265
2.23k
                    self as u128
266
                } else {
267
                    // Convert negative number to positive by summing 1 to its two's complement.
268
0
                    (!(self as u128)).wrapping_add(1)
269
                };
270
2.23k
                let mut curr = buf.len();
271
2.23k
                let buf_ptr = buf.as_mut_ptr() as *mut u8;
272
273
                // Divide by 10^19 which is the highest power less than 2^64.
274
2.23k
                let (n, rem) = udiv128::udivmod_1e19(n);
275
2.23k
                let buf1 = unsafe {
276
2.23k
                    buf_ptr.add(curr - u64::MAX_STR_LEN) as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
277
                };
278
2.23k
                curr -= rem.write(unsafe { &mut *buf1 }).len();
279
280
2.23k
                if n != 0 {
281
                    // Memset the base10 leading zeros of rem.
282
144
                    let target = buf.len() - 19;
283
144
                    unsafe {
284
144
                        ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
285
144
                    }
286
144
                    curr = target;
287
288
                    // Divide by 10^19 again.
289
144
                    let (n, rem) = udiv128::udivmod_1e19(n);
290
144
                    let buf2 = unsafe {
291
144
                        buf_ptr.add(curr - u64::MAX_STR_LEN)
292
144
                            as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
293
                    };
294
144
                    curr -= rem.write(unsafe { &mut *buf2 }).len();
295
296
144
                    if n != 0 {
297
                        // Memset the leading zeros.
298
19
                        let target = buf.len() - 38;
299
19
                        unsafe {
300
19
                            ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
301
19
                        }
302
19
                        curr = target;
303
304
                        // There is at most one digit left
305
                        // because u128::MAX / 10^19 / 10^19 is 3.
306
19
                        curr -= 1;
307
19
                        unsafe {
308
19
                            *buf_ptr.add(curr) = (n as u8) + b'0';
309
19
                        }
310
125
                    }
311
2.08k
                }
312
313
2.23k
                if !is_nonnegative {
314
0
                    curr -= 1;
315
0
                    unsafe {
316
0
                        *buf_ptr.add(curr) = b'-';
317
0
                    }
318
2.23k
                }
319
320
2.23k
                let len = buf.len() - curr;
321
2.23k
                let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) };
322
2.23k
                unsafe { str::from_utf8_unchecked(bytes) }
323
2.23k
            }
324
        }
325
    };
326
}
327
328
impl_Integer128!(i128[len = 40]);
329
impl_Integer128!(u128[len = 39]);