use core::hint; use core::mem::MaybeUninit; use core::{ptr, slice, str}; #[cfg(feature = "no-panic")] use no_panic::no_panic;
/// A correctly sized stack allocation for the formatted integer to be written /// into. /// /// # Example /// /// ``` /// let mut buffer = itoa::Buffer::new(); /// let printed = buffer.format(1234); /// assert_eq!(printed, "1234"); /// ``` pubstruct Buffer {
bytes: [MaybeUninit<u8>; i128::MAX_STR_LEN],
}
impl Buffer { /// This is a cheap operation; you don't need to worry about reusing buffers /// for efficiency. #[inline] #[cfg_attr(feature = "no-panic", no_panic)] pubfn new() -> Buffer { let bytes = [MaybeUninit::<u8>::uninit(); i128::MAX_STR_LEN];
Buffer { bytes }
}
/// Print an integer into this buffer and return a reference to its string /// representation within the buffer. #[cfg_attr(feature = "no-panic", no_panic)] pubfn format<I: Integer>(&mutself, i: I) -> &str { let string = i.write(unsafe {
&mut *(&mutself.bytes as *mut [MaybeUninit<u8>; i128::MAX_STR_LEN] as *mut <I as private::Sealed>::Buffer)
}); if string.len() > I::MAX_STR_LEN { unsafe { hint::unreachable_unchecked() };
}
string
}
}
/// An integer that can be written into an [`itoa::Buffer`][Buffer]. /// /// This trait is sealed and cannot be implemented for types outside of itoa. pubtrait Integer: private::Sealed { /// The maximum length of string that formatting an integer of this type can /// produce on the current target platform. const MAX_STR_LEN: usize;
}
// Seal to prevent downstream implementations of the Integer trait. mod private { #[doc(hidden)] pubtrait Sealed: Copy { #[doc(hidden)] type Buffer: 'static; fn write(self, buf: &mutSelf::Buffer) -> &str;
}
}
let len = buf.len() - curr; let bytes = unsafe { slice::from_raw_parts(buf_ptr.add(curr), len) }; unsafe { str::from_utf8_unchecked(bytes) }
}
}
};
}
impl_Integer!(i8[len = 4] as u32);
impl_Integer!(u8[len = 3] as u32);
impl_Integer!(i16[len = 6] as u32);
impl_Integer!(u16[len = 5] as u32);
impl_Integer!(i32[len = 11] as u32);
impl_Integer!(u32[len = 10] as u32);
impl_Integer!(i64[len = 20] as u64);
impl_Integer!(u64[len = 20] as u64);
macro_rules! impl_Integer_size {
($t:ty as $primitive:ident #[cfg(target_pointer_width = $width:literal)]) => { #[cfg(target_pointer_width = $width)] impl Integer for $t { const MAX_STR_LEN: usize = <$primitive as Integer>::MAX_STR_LEN;
}
#[cfg(target_pointer_width = $width)] impl private::Sealed for $t { type Buffer = <$primitive as private::Sealed>::Buffer;
impl private::Sealed for $t { type Buffer = [MaybeUninit<u8>; $max_len];
#[allow(unused_comparisons)] #[inline] #[cfg_attr(feature = "no-panic", no_panic)] fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str { let is_nonnegative = self >= 0; let n = if is_nonnegative { selfas u128
} else { // Convert negative number to positive by summing 1 to its two's complement.
(!(selfas u128)).wrapping_add(1)
}; letmut curr = buf.len(); let buf_ptr = buf.as_mut_ptr() as *mut u8;
// Divide by 10^19 which is the highest power less than 2^64. let (n, rem) = udiv128::udivmod_1e19(n); let buf1 = unsafe {
buf_ptr.add(curr - u64::MAX_STR_LEN) as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
};
curr -= rem.write(unsafe { &mut *buf1 }).len();
if n != 0 { // Memset the base10 leading zeros of rem. let target = buf.len() - 19; unsafe {
ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
}
curr = target;
// Divide by 10^19 again. let (n, rem) = udiv128::udivmod_1e19(n); let buf2 = unsafe {
buf_ptr.add(curr - u64::MAX_STR_LEN) as *mut [MaybeUninit<u8>; u64::MAX_STR_LEN]
};
curr -= rem.write(unsafe { &mut *buf2 }).len();
if n != 0 { // Memset the leading zeros. let target = buf.len() - 38; unsafe {
ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
}
curr = target;
// There is at most one digit left // because u128::MAX / 10^19 / 10^19 is 3.
curr -= 1; unsafe {
*buf_ptr.add(curr) = (n as u8) + b'0';
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.