summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ryu/src/pretty
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/ryu/src/pretty
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/ryu/src/pretty')
-rw-r--r--third_party/rust/ryu/src/pretty/exponent.rs49
-rw-r--r--third_party/rust/ryu/src/pretty/mantissa.rs51
-rw-r--r--third_party/rust/ryu/src/pretty/mod.rs228
3 files changed, 328 insertions, 0 deletions
diff --git a/third_party/rust/ryu/src/pretty/exponent.rs b/third_party/rust/ryu/src/pretty/exponent.rs
new file mode 100644
index 0000000000..f10643f22d
--- /dev/null
+++ b/third_party/rust/ryu/src/pretty/exponent.rs
@@ -0,0 +1,49 @@
+use core::ptr;
+
+use digit_table::*;
+
+#[cfg_attr(feature = "no-panic", inline)]
+pub unsafe fn write_exponent3(mut k: isize, mut result: *mut u8) -> usize {
+ let sign = k < 0;
+ if sign {
+ *result = b'-';
+ result = result.offset(1);
+ k = -k;
+ }
+
+ debug_assert!(k < 1000);
+ if k >= 100 {
+ *result = b'0' + (k / 100) as u8;
+ k %= 100;
+ let d = DIGIT_TABLE.get_unchecked(k as usize * 2);
+ ptr::copy_nonoverlapping(d, result.offset(1), 2);
+ sign as usize + 3
+ } else if k >= 10 {
+ let d = DIGIT_TABLE.get_unchecked(k as usize * 2);
+ ptr::copy_nonoverlapping(d, result, 2);
+ sign as usize + 2
+ } else {
+ *result = b'0' + k as u8;
+ sign as usize + 1
+ }
+}
+
+#[cfg_attr(feature = "no-panic", inline)]
+pub unsafe fn write_exponent2(mut k: isize, mut result: *mut u8) -> usize {
+ let sign = k < 0;
+ if sign {
+ *result = b'-';
+ result = result.offset(1);
+ k = -k;
+ }
+
+ debug_assert!(k < 100);
+ if k >= 10 {
+ let d = DIGIT_TABLE.get_unchecked(k as usize * 2);
+ ptr::copy_nonoverlapping(d, result, 2);
+ sign as usize + 2
+ } else {
+ *result = b'0' + k as u8;
+ sign as usize + 1
+ }
+}
diff --git a/third_party/rust/ryu/src/pretty/mantissa.rs b/third_party/rust/ryu/src/pretty/mantissa.rs
new file mode 100644
index 0000000000..428023233d
--- /dev/null
+++ b/third_party/rust/ryu/src/pretty/mantissa.rs
@@ -0,0 +1,51 @@
+use core::ptr;
+
+use digit_table::*;
+
+#[cfg_attr(feature = "no-panic", inline)]
+pub unsafe fn write_mantissa_long(mut output: u64, mut result: *mut u8) {
+ if (output >> 32) != 0 {
+ // One expensive 64-bit division.
+ let mut output2 = (output - 100_000_000 * (output / 100_000_000)) as u32;
+ output /= 100_000_000;
+
+ let c = output2 % 10_000;
+ output2 /= 10_000;
+ let d = output2 % 10_000;
+ let c0 = (c % 100) << 1;
+ let c1 = (c / 100) << 1;
+ let d0 = (d % 100) << 1;
+ let d1 = (d / 100) << 1;
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c0 as usize), result.offset(-2), 2);
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c1 as usize), result.offset(-4), 2);
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(d0 as usize), result.offset(-6), 2);
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(d1 as usize), result.offset(-8), 2);
+ result = result.offset(-8);
+ }
+ write_mantissa(output as u32, result);
+}
+
+#[cfg_attr(feature = "no-panic", inline)]
+pub unsafe fn write_mantissa(mut output: u32, mut result: *mut u8) {
+ while output >= 10_000 {
+ let c = (output - 10_000 * (output / 10_000)) as u32;
+ output /= 10_000;
+ let c0 = (c % 100) << 1;
+ let c1 = (c / 100) << 1;
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c0 as usize), result.offset(-2), 2);
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c1 as usize), result.offset(-4), 2);
+ result = result.offset(-4);
+ }
+ if output >= 100 {
+ let c = ((output % 100) << 1) as u32;
+ output /= 100;
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c as usize), result.offset(-2), 2);
+ result = result.offset(-2);
+ }
+ if output >= 10 {
+ let c = (output << 1) as u32;
+ ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c as usize), result.offset(-2), 2);
+ } else {
+ *result.offset(-1) = b'0' + output as u8;
+ }
+}
diff --git a/third_party/rust/ryu/src/pretty/mod.rs b/third_party/rust/ryu/src/pretty/mod.rs
new file mode 100644
index 0000000000..3dead1bf36
--- /dev/null
+++ b/third_party/rust/ryu/src/pretty/mod.rs
@@ -0,0 +1,228 @@
+mod exponent;
+mod mantissa;
+
+use core::{mem, ptr};
+
+use self::exponent::*;
+use self::mantissa::*;
+use common;
+use d2s;
+use d2s::*;
+use f2s::*;
+
+#[cfg(feature = "no-panic")]
+use no_panic::no_panic;
+
+/// Print f64 to the given buffer and return number of bytes written.
+///
+/// At most 24 bytes will be written.
+///
+/// ## Special cases
+///
+/// This function **does not** check for NaN or infinity. If the input
+/// number is not a finite float, the printed representation will be some
+/// correctly formatted but unspecified numerical value.
+///
+/// Please check [`is_finite`] yourself before calling this function, or
+/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
+///
+/// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite
+/// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan
+/// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite
+///
+/// ## Safety
+///
+/// The `result` pointer argument must point to sufficiently many writable bytes
+/// to hold Ryū's representation of `f`.
+///
+/// ## Example
+///
+/// ```edition2018
+/// use std::mem::MaybeUninit;
+///
+/// let f = 1.234f64;
+///
+/// unsafe {
+/// let mut buffer: [MaybeUninit<u8>; 24] = MaybeUninit::uninit().assume_init();
+/// let len = ryu::raw::format64(f, buffer.as_mut_ptr() as *mut u8);
+/// let slice = std::slice::from_raw_parts(buffer.as_ptr() as *const u8, len);
+/// let print = std::str::from_utf8_unchecked(slice);
+/// assert_eq!(print, "1.234");
+/// }
+/// ```
+#[cfg_attr(must_use_return, must_use)]
+#[cfg_attr(feature = "no-panic", no_panic)]
+pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
+ let bits = mem::transmute::<f64, u64>(f);
+ let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
+ let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
+ let ieee_exponent =
+ (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
+
+ let mut index = 0isize;
+ if sign {
+ *result = b'-';
+ index += 1;
+ }
+
+ if ieee_exponent == 0 && ieee_mantissa == 0 {
+ ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
+ return sign as usize + 3;
+ }
+
+ let v = d2d(ieee_mantissa, ieee_exponent);
+
+ let length = d2s::decimal_length17(v.mantissa) as isize;
+ let k = v.exponent as isize;
+ let kk = length + k; // 10^(kk-1) <= v < 10^kk
+ debug_assert!(k >= -324);
+
+ if 0 <= k && kk <= 16 {
+ // 1234e7 -> 12340000000.0
+ write_mantissa_long(v.mantissa, result.offset(index + length));
+ for i in length..kk {
+ *result.offset(index + i) = b'0';
+ }
+ *result.offset(index + kk) = b'.';
+ *result.offset(index + kk + 1) = b'0';
+ index as usize + kk as usize + 2
+ } else if 0 < kk && kk <= 16 {
+ // 1234e-2 -> 12.34
+ write_mantissa_long(v.mantissa, result.offset(index + length + 1));
+ ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
+ *result.offset(index + kk) = b'.';
+ index as usize + length as usize + 1
+ } else if -5 < kk && kk <= 0 {
+ // 1234e-6 -> 0.001234
+ *result.offset(index) = b'0';
+ *result.offset(index + 1) = b'.';
+ let offset = 2 - kk;
+ for i in 2..offset {
+ *result.offset(index + i) = b'0';
+ }
+ write_mantissa_long(v.mantissa, result.offset(index + length + offset));
+ index as usize + length as usize + offset as usize
+ } else if length == 1 {
+ // 1e30
+ *result.offset(index) = b'0' + v.mantissa as u8;
+ *result.offset(index + 1) = b'e';
+ index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
+ } else {
+ // 1234e30 -> 1.234e33
+ write_mantissa_long(v.mantissa, result.offset(index + length + 1));
+ *result.offset(index) = *result.offset(index + 1);
+ *result.offset(index + 1) = b'.';
+ *result.offset(index + length + 1) = b'e';
+ index as usize
+ + length as usize
+ + 2
+ + write_exponent3(kk - 1, result.offset(index + length + 2))
+ }
+}
+
+/// Print f32 to the given buffer and return number of bytes written.
+///
+/// At most 16 bytes will be written.
+///
+/// ## Special cases
+///
+/// This function **does not** check for NaN or infinity. If the input
+/// number is not a finite float, the printed representation will be some
+/// correctly formatted but unspecified numerical value.
+///
+/// Please check [`is_finite`] yourself before calling this function, or
+/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
+///
+/// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_finite
+/// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_nan
+/// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_infinite
+///
+/// ## Safety
+///
+/// The `result` pointer argument must point to sufficiently many writable bytes
+/// to hold Ryū's representation of `f`.
+///
+/// ## Example
+///
+/// ```edition2018
+/// use std::mem::MaybeUninit;
+///
+/// let f = 1.234f32;
+///
+/// unsafe {
+/// let mut buffer: [MaybeUninit<u8>; 16] = MaybeUninit::uninit().assume_init();
+/// let len = ryu::raw::format32(f, buffer.as_mut_ptr() as *mut u8);
+/// let slice = std::slice::from_raw_parts(buffer.as_ptr() as *const u8, len);
+/// let print = std::str::from_utf8_unchecked(slice);
+/// assert_eq!(print, "1.234");
+/// }
+/// ```
+#[cfg_attr(must_use_return, must_use)]
+#[cfg_attr(feature = "no-panic", no_panic)]
+pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
+ let bits = mem::transmute::<f32, u32>(f);
+ let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
+ let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
+ let ieee_exponent =
+ ((bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1)) as u32;
+
+ let mut index = 0isize;
+ if sign {
+ *result = b'-';
+ index += 1;
+ }
+
+ if ieee_exponent == 0 && ieee_mantissa == 0 {
+ ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
+ return sign as usize + 3;
+ }
+
+ let v = f2d(ieee_mantissa, ieee_exponent);
+
+ let length = common::decimal_length9(v.mantissa) as isize;
+ let k = v.exponent as isize;
+ let kk = length + k; // 10^(kk-1) <= v < 10^kk
+ debug_assert!(k >= -45);
+
+ if 0 <= k && kk <= 13 {
+ // 1234e7 -> 12340000000.0
+ write_mantissa(v.mantissa, result.offset(index + length));
+ for i in length..kk {
+ *result.offset(index + i) = b'0';
+ }
+ *result.offset(index + kk) = b'.';
+ *result.offset(index + kk + 1) = b'0';
+ index as usize + kk as usize + 2
+ } else if 0 < kk && kk <= 13 {
+ // 1234e-2 -> 12.34
+ write_mantissa(v.mantissa, result.offset(index + length + 1));
+ ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
+ *result.offset(index + kk) = b'.';
+ index as usize + length as usize + 1
+ } else if -6 < kk && kk <= 0 {
+ // 1234e-6 -> 0.001234
+ *result.offset(index) = b'0';
+ *result.offset(index + 1) = b'.';
+ let offset = 2 - kk;
+ for i in 2..offset {
+ *result.offset(index + i) = b'0';
+ }
+ write_mantissa(v.mantissa, result.offset(index + length + offset));
+ index as usize + length as usize + offset as usize
+ } else if length == 1 {
+ // 1e30
+ *result.offset(index) = b'0' + v.mantissa as u8;
+ *result.offset(index + 1) = b'e';
+ index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
+ } else {
+ // 1234e30 -> 1.234e33
+ write_mantissa(v.mantissa, result.offset(index + length + 1));
+ *result.offset(index) = *result.offset(index + 1);
+ *result.offset(index + 1) = b'.';
+ *result.offset(index + length + 1) = b'e';
+ index as usize
+ + length as usize
+ + 2
+ + write_exponent2(kk - 1, result.offset(index + length + 2))
+ }
+}