forked from mirrors/gecko-dev
Bug 1769902 - Update the itoa crate to 1.0.x. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D146662
This commit is contained in:
parent
83c74198fa
commit
beaa7521c7
11 changed files with 178 additions and 294 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
|
@ -1081,7 +1081,7 @@ checksum = "031d29b6d1ea84f63436e45fb6f3c1a3d62dc1650018c53fa7165e108d35d88f"
|
|||
dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
"matches",
|
||||
"phf",
|
||||
"proc-macro2",
|
||||
|
|
@ -2388,7 +2388,7 @@ checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
|
|||
dependencies = [
|
||||
"bytes 1.1.0",
|
||||
"fnv",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2460,7 +2460,7 @@ dependencies = [
|
|||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
"log",
|
||||
"pin-project",
|
||||
"socket2",
|
||||
|
|
@ -2601,9 +2601,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
version = "0.4.999"
|
||||
dependencies = [
|
||||
"itoa 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
|
|
@ -4608,7 +4615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
|
@ -4631,7 +4638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
"serde",
|
||||
"url",
|
||||
]
|
||||
|
|
@ -4878,7 +4885,7 @@ dependencies = [
|
|||
"gecko-profiler",
|
||||
"indexmap",
|
||||
"itertools 0.8.2",
|
||||
"itoa",
|
||||
"itoa 0.4.999",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"malloc_size_of",
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ vcpkg = { path = "build/rust/vcpkg" }
|
|||
# Helper crate for integration in the gecko build system.
|
||||
mozbuild = { path = "build/rust/mozbuild" }
|
||||
|
||||
# Patch itoa 0.4 to 1.0.
|
||||
itoa = { path = "build/rust/itoa" }
|
||||
|
||||
# Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30
|
||||
autocfg = { path = "third_party/rust/autocfg" }
|
||||
|
||||
|
|
|
|||
11
build/rust/itoa/Cargo.toml
Normal file
11
build/rust/itoa/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "itoa"
|
||||
version = "0.4.999"
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
itoa = "1.0"
|
||||
21
build/rust/itoa/lib.rs
Normal file
21
build/rust/itoa/lib.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
pub use itoa::*;
|
||||
use std::{io, fmt};
|
||||
|
||||
// APIs that were in itoa 0.4 but aren't in 1.0.
|
||||
|
||||
#[inline]
|
||||
pub fn write<W: io::Write, V: Integer>(mut wr: W, value: V) -> io::Result<usize> {
|
||||
let mut buf = Buffer::new();
|
||||
let s = buf.format(value);
|
||||
match wr.write_all(s.as_bytes()) {
|
||||
Ok(()) => Ok(s.len()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Write integer to an `fmt::Write`.
|
||||
#[inline]
|
||||
pub fn fmt<W: fmt::Write, V: Integer>(mut wr: W, value: V) -> fmt::Result {
|
||||
let mut buf = Buffer::new();
|
||||
wr.write_str(buf.format(value))
|
||||
}
|
||||
2
third_party/rust/itoa/.cargo-checksum.json
vendored
2
third_party/rust/itoa/.cargo-checksum.json
vendored
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"46f2cf3006d59c73bed95c276f43ddab1a9a9fa177ea0142777b7471c753f558","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"5eac563c0123003363f4706f36927cf4d3b118965e35b51bc515343ce6a711ae","benches/bench.rs":"fc009678431563bfb1b51698fb5b83f5309a3cdab90dc7365800f4e32bc287be","src/lib.rs":"a7b37eab3872193cf666c1d7d4db8d7e82c6dc6d8121fc762b5f69ddb4df3b01","src/udiv128.rs":"1c9c374680162e12c734d369d1494ee8c91e11eb4b05500e96e6303155bdc623","tests/test.rs":"c9b124462b75078e2407e0239222edd7859c3112d65a114742dbb8c47dafc07c"},"package":"b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"}
|
||||
{"files":{"Cargo.toml":"3c81fd59c059ee454f7812e8a9e90078880a4c101964ac4ce63537cec7d36c1e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"8e9d4e6ac0c740793958bf57c3dbd62827340cf77a282633c388aff70a7c1a22","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"f3b4bd0934f41b8f8a8828a22a9f5ad2af1ac1e7b632743ec2de46fbb4cb0b59","src/udiv128.rs":"16394f767854452756372d74f8025f7329fd8b61a676d81edf489681a6332ee9","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"}
|
||||
17
third_party/rust/itoa/Cargo.toml
vendored
17
third_party/rust/itoa/Cargo.toml
vendored
|
|
@ -10,20 +10,21 @@
|
|||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.36"
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
version = "1.0.2"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
exclude = ["performance.png"]
|
||||
description = "Fast functions for printing integer primitives to an io::Write"
|
||||
exclude = [
|
||||
"performance.png",
|
||||
"chart/**",
|
||||
]
|
||||
description = "Fast integer primitive to string conversion"
|
||||
documentation = "https://docs.rs/itoa"
|
||||
readme = "README.md"
|
||||
categories = ["value-formatting"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/dtolnay/itoa"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
i128 = []
|
||||
std = []
|
||||
|
|
|
|||
77
third_party/rust/itoa/README.md
vendored
77
third_party/rust/itoa/README.md
vendored
|
|
@ -6,24 +6,33 @@ itoa
|
|||
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/itoa)
|
||||
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/itoa/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)
|
||||
|
||||
This crate provides fast functions for printing integer primitives to an
|
||||
[`io::Write`] or a [`fmt::Write`]. The implementation comes straight from
|
||||
[libcore] but avoids the performance penalty of going through
|
||||
[`fmt::Formatter`].
|
||||
This crate provides a fast conversion of integer primitives to decimal strings.
|
||||
The implementation comes straight from [libcore] but avoids the performance
|
||||
penalty of going through [`core::fmt::Formatter`].
|
||||
|
||||
See also [`dtoa`] for printing floating point primitives.
|
||||
See also [`ryu`] for printing floating point primitives.
|
||||
|
||||
*Version requirement: rustc 1.0+*
|
||||
*Version requirement: rustc 1.36+*
|
||||
|
||||
[`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||
[`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html
|
||||
[libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254
|
||||
[`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
|
||||
[`dtoa`]: https://github.com/dtolnay/dtoa
|
||||
[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
|
||||
[`ryu`]: https://github.com/dtolnay/ryu
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
itoa = "0.4"
|
||||
itoa = "1.0"
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
let printed = buffer.format(128u64);
|
||||
assert_eq!(printed, "128");
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
|
@ -34,52 +43,6 @@ itoa = "0.4"
|
|||
|
||||
<br>
|
||||
|
||||
## Examples
|
||||
|
||||
```rust
|
||||
use std::{fmt, io};
|
||||
|
||||
fn demo_itoa_write() -> io::Result<()> {
|
||||
// Write to a vector or other io::Write.
|
||||
let mut buf = Vec::new();
|
||||
itoa::write(&mut buf, 128u64)?;
|
||||
println!("{:?}", buf);
|
||||
|
||||
// Write to a stack buffer.
|
||||
let mut bytes = [0u8; 20];
|
||||
let n = itoa::write(&mut bytes[..], 128u64)?;
|
||||
println!("{:?}", &bytes[..n]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn demo_itoa_fmt() -> fmt::Result {
|
||||
// Write to a string.
|
||||
let mut s = String::new();
|
||||
itoa::fmt(&mut s, 128u64)?;
|
||||
println!("{}", s);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
The function signatures are:
|
||||
|
||||
```rust
|
||||
fn write<W: io::Write, V: itoa::Integer>(writer: W, value: V) -> io::Result<usize>;
|
||||
|
||||
fn fmt<W: fmt::Write, V: itoa::Integer>(writer: W, value: V) -> fmt::Result;
|
||||
```
|
||||
|
||||
where `itoa::Integer` is implemented for i8, u8, i16, u16, i32, u32, i64, u64,
|
||||
i128, u128, isize and usize. 128-bit integer support requires rustc 1.26+ and
|
||||
the `i128` feature of this crate enabled.
|
||||
|
||||
The `write` function is only available when the `std` feature is enabled
|
||||
(default is enabled). The return value gives the number of bytes written.
|
||||
|
||||
<br>
|
||||
|
||||
#### License
|
||||
|
||||
<sup>
|
||||
|
|
|
|||
64
third_party/rust/itoa/benches/bench.rs
vendored
64
third_party/rust/itoa/benches/bench.rs
vendored
|
|
@ -1,66 +1,40 @@
|
|||
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
|
||||
#![feature(test)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(clippy::cast_lossless)]
|
||||
|
||||
extern crate itoa;
|
||||
extern crate test;
|
||||
|
||||
macro_rules! benches {
|
||||
(
|
||||
$(
|
||||
$(#[$attr:meta])*
|
||||
$name:ident($value:expr)
|
||||
),*
|
||||
) => {
|
||||
mod bench_itoa_write {
|
||||
($($name:ident($value:expr))*) => {
|
||||
mod bench_itoa_format {
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[bench]
|
||||
fn $name(b: &mut Bencher) {
|
||||
use itoa;
|
||||
|
||||
let mut buf = Vec::with_capacity(40);
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
|
||||
b.iter(|| {
|
||||
buf.clear();
|
||||
itoa::write(&mut buf, black_box($value)).unwrap()
|
||||
});
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
mod bench_itoa_fmt {
|
||||
use test::{Bencher, black_box};
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[bench]
|
||||
fn $name(b: &mut Bencher) {
|
||||
use itoa;
|
||||
|
||||
let mut buf = String::with_capacity(40);
|
||||
|
||||
b.iter(|| {
|
||||
buf.clear();
|
||||
itoa::fmt(&mut buf, black_box($value)).unwrap()
|
||||
let printed = buffer.format(black_box($value));
|
||||
black_box(printed);
|
||||
});
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
mod bench_std_fmt {
|
||||
use std::io::Write;
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[bench]
|
||||
fn $name(b: &mut Bencher) {
|
||||
use std::io::Write;
|
||||
|
||||
let mut buf = Vec::with_capacity(40);
|
||||
|
||||
b.iter(|| {
|
||||
buf.clear();
|
||||
write!(&mut buf, "{}", black_box($value)).unwrap()
|
||||
write!(&mut buf, "{}", black_box($value)).unwrap();
|
||||
black_box(&buf);
|
||||
});
|
||||
}
|
||||
)*
|
||||
|
|
@ -69,15 +43,13 @@ macro_rules! benches {
|
|||
}
|
||||
|
||||
benches! {
|
||||
bench_u64_0(0u64),
|
||||
bench_u64_half(<u32>::max_value() as u64),
|
||||
bench_u64_max(<u64>::max_value()),
|
||||
bench_u64_0(0u64)
|
||||
bench_u64_half(u32::max_value() as u64)
|
||||
bench_u64_max(u64::max_value())
|
||||
|
||||
bench_i16_0(0i16),
|
||||
bench_i16_min(<i16>::min_value()),
|
||||
bench_i16_0(0i16)
|
||||
bench_i16_min(i16::min_value())
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
bench_u128_0(0u128),
|
||||
#[cfg(feature = "i128")]
|
||||
bench_u128_max(<u128>::max_value())
|
||||
bench_u128_0(0u128)
|
||||
bench_u128_max(u128::max_value())
|
||||
}
|
||||
|
|
|
|||
204
third_party/rust/itoa/src/lib.rs
vendored
204
third_party/rust/itoa/src/lib.rs
vendored
|
|
@ -6,98 +6,46 @@
|
|||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! This crate provides fast functions for printing integer primitives to an
|
||||
//! [`io::Write`] or a [`fmt::Write`]. The implementation comes straight from
|
||||
//! [libcore] but avoids the performance penalty of going through
|
||||
//! [`fmt::Formatter`].
|
||||
//! This crate provides a fast conversion of integer primitives to decimal
|
||||
//! strings. The implementation comes straight from [libcore] but avoids the
|
||||
//! performance penalty of going through [`core::fmt::Formatter`].
|
||||
//!
|
||||
//! See also [`dtoa`] for printing floating point primitives.
|
||||
//! See also [`ryu`] for printing floating point primitives.
|
||||
//!
|
||||
//! [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||
//! [`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html
|
||||
//! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254
|
||||
//! [`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
|
||||
//! [`dtoa`]: https://github.com/dtolnay/dtoa
|
||||
//! [`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html
|
||||
//! [`ryu`]: https://github.com/dtolnay/ryu
|
||||
//!
|
||||
//! <br>
|
||||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! fn main() {
|
||||
//! let mut buffer = itoa::Buffer::new();
|
||||
//! let printed = buffer.format(128u64);
|
||||
//! assert_eq!(printed, "128");
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Performance (lower is better)
|
||||
//!
|
||||
//! 
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```edition2018
|
||||
//! use std::{fmt, io};
|
||||
//!
|
||||
//! fn demo_itoa_write() -> io::Result<()> {
|
||||
//! // Write to a vector or other io::Write.
|
||||
//! let mut buf = Vec::new();
|
||||
//! itoa::write(&mut buf, 128u64)?;
|
||||
//! println!("{:?}", buf);
|
||||
//!
|
||||
//! // Write to a stack buffer.
|
||||
//! let mut bytes = [0u8; 20];
|
||||
//! let n = itoa::write(&mut bytes[..], 128u64)?;
|
||||
//! println!("{:?}", &bytes[..n]);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//!
|
||||
//! fn demo_itoa_fmt() -> fmt::Result {
|
||||
//! // Write to a string.
|
||||
//! let mut s = String::new();
|
||||
//! itoa::fmt(&mut s, 128u64)?;
|
||||
//! println!("{}", s);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/itoa/0.4.8")]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
expl_impl_clone_on_copy,
|
||||
missing_errors_doc,
|
||||
must_use_candidate,
|
||||
transmute_ptr_to_ptr
|
||||
)
|
||||
#![doc(html_root_url = "https://docs.rs/itoa/1.0.2")]
|
||||
#![no_std]
|
||||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::must_use_candidate,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
mod udiv128;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::{fmt, io, mem, ptr, slice, str};
|
||||
use core::mem::{self, MaybeUninit};
|
||||
use core::{ptr, slice, str};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use core::{fmt, mem, ptr, slice, str};
|
||||
|
||||
/// Write integer to an `io::Write`.
|
||||
#[cfg(feature = "std")]
|
||||
#[inline]
|
||||
pub fn write<W: io::Write, V: Integer>(mut wr: W, value: V) -> io::Result<usize> {
|
||||
let mut buf = Buffer::new();
|
||||
let s = buf.format(value);
|
||||
match wr.write_all(s.as_bytes()) {
|
||||
Ok(()) => Ok(s.len()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Write integer to an `fmt::Write`.
|
||||
#[inline]
|
||||
pub fn fmt<W: fmt::Write, V: Integer>(mut wr: W, value: V) -> fmt::Result {
|
||||
let mut buf = Buffer::new();
|
||||
wr.write_str(buf.format(value))
|
||||
}
|
||||
|
||||
/// A safe API for formatting integers to text.
|
||||
/// A correctly sized stack allocation for the formatted integer to be written
|
||||
/// into.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
|
@ -106,9 +54,8 @@ pub fn fmt<W: fmt::Write, V: Integer>(mut wr: W, value: V) -> fmt::Result {
|
|||
/// let printed = buffer.format(1234);
|
||||
/// assert_eq!(printed, "1234");
|
||||
/// ```
|
||||
#[derive(Copy)]
|
||||
pub struct Buffer {
|
||||
bytes: [u8; I128_MAX_LEN],
|
||||
bytes: [MaybeUninit<u8>; I128_MAX_LEN],
|
||||
}
|
||||
|
||||
impl Default for Buffer {
|
||||
|
|
@ -129,39 +76,35 @@ impl Buffer {
|
|||
/// This is a cheap operation; you don't need to worry about reusing buffers
|
||||
/// for efficiency.
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub fn new() -> Buffer {
|
||||
Buffer {
|
||||
bytes: unsafe { mem::uninitialized() },
|
||||
}
|
||||
let bytes = [MaybeUninit::<u8>::uninit(); I128_MAX_LEN];
|
||||
Buffer { bytes }
|
||||
}
|
||||
|
||||
/// Print an integer into this buffer and return a reference to its string representation
|
||||
/// within the buffer.
|
||||
/// Print an integer into this buffer and return a reference to its string
|
||||
/// representation within the buffer.
|
||||
pub fn format<I: Integer>(&mut self, i: I) -> &str {
|
||||
i.write(self)
|
||||
i.write(unsafe {
|
||||
&mut *(&mut self.bytes as *mut [MaybeUninit<u8>; I128_MAX_LEN]
|
||||
as *mut <I as private::Sealed>::Buffer)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// An integer that can be written into an [`itoa::Buffer`][Buffer].
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of itoa.
|
||||
pub trait Integer: private::Sealed {}
|
||||
|
||||
// Seal to prevent downstream implementations of the Integer trait.
|
||||
mod private {
|
||||
pub trait Sealed {}
|
||||
pub trait Sealed: Copy {
|
||||
type Buffer: 'static;
|
||||
fn write(self, buf: &mut Self::Buffer) -> &str;
|
||||
}
|
||||
}
|
||||
|
||||
/// An integer that can be formatted by `itoa::write` and `itoa::fmt`.
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of itoa.
|
||||
pub trait Integer: private::Sealed {
|
||||
// Not public API.
|
||||
#[doc(hidden)]
|
||||
fn write(self, buf: &mut Buffer) -> &str;
|
||||
}
|
||||
|
||||
trait IntegerPrivate<B> {
|
||||
fn write_to(self, buf: &mut B) -> &[u8];
|
||||
}
|
||||
|
||||
const DEC_DIGITS_LUT: &'static [u8] = b"\
|
||||
const DEC_DIGITS_LUT: &[u8] = b"\
|
||||
0001020304050607080910111213141516171819\
|
||||
2021222324252627282930313233343536373839\
|
||||
4041424344454647484950515253545556575859\
|
||||
|
|
@ -170,34 +113,16 @@ const DEC_DIGITS_LUT: &'static [u8] = b"\
|
|||
|
||||
// Adaptation of the original implementation at
|
||||
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
|
||||
macro_rules! impl_IntegerCommon {
|
||||
($max_len:expr, $t:ident) => {
|
||||
impl Integer for $t {
|
||||
#[inline]
|
||||
fn write(self, buf: &mut Buffer) -> &str {
|
||||
unsafe {
|
||||
debug_assert!($max_len <= I128_MAX_LEN);
|
||||
let buf = mem::transmute::<&mut [u8; I128_MAX_LEN], &mut [u8; $max_len]>(
|
||||
&mut buf.bytes,
|
||||
);
|
||||
let bytes = self.write_to(buf);
|
||||
str::from_utf8_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl private::Sealed for $t {}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_Integer {
|
||||
($($max_len:expr => $t:ident),* as $conv_fn:ident) => {$(
|
||||
impl_IntegerCommon!($max_len, $t);
|
||||
impl Integer for $t {}
|
||||
|
||||
impl private::Sealed for $t {
|
||||
type Buffer = [MaybeUninit<u8>; $max_len];
|
||||
|
||||
impl IntegerPrivate<[u8; $max_len]> for $t {
|
||||
#[allow(unused_comparisons)]
|
||||
#[inline]
|
||||
fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
|
||||
fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
|
||||
let is_nonnegative = self >= 0;
|
||||
let mut n = if is_nonnegative {
|
||||
self as $conv_fn
|
||||
|
|
@ -206,7 +131,7 @@ macro_rules! impl_Integer {
|
|||
(!(self as $conv_fn)).wrapping_add(1)
|
||||
};
|
||||
let mut curr = buf.len() as isize;
|
||||
let buf_ptr = buf.as_mut_ptr();
|
||||
let buf_ptr = buf.as_mut_ptr() as *mut u8;
|
||||
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
|
||||
|
||||
unsafe {
|
||||
|
|
@ -253,7 +178,8 @@ macro_rules! impl_Integer {
|
|||
}
|
||||
|
||||
let len = buf.len() - curr as usize;
|
||||
unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }
|
||||
let bytes = unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) };
|
||||
unsafe { str::from_utf8_unchecked(bytes) }
|
||||
}
|
||||
}
|
||||
)*};
|
||||
|
|
@ -288,15 +214,16 @@ impl_Integer!(I32_MAX_LEN => isize, U32_MAX_LEN => usize as u32);
|
|||
#[cfg(target_pointer_width = "64")]
|
||||
impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64);
|
||||
|
||||
#[cfg(all(feature = "i128"))]
|
||||
macro_rules! impl_Integer128 {
|
||||
($($max_len:expr => $t:ident),*) => {$(
|
||||
impl_IntegerCommon!($max_len, $t);
|
||||
impl Integer for $t {}
|
||||
|
||||
impl private::Sealed for $t {
|
||||
type Buffer = [MaybeUninit<u8>; $max_len];
|
||||
|
||||
impl IntegerPrivate<[u8; $max_len]> for $t {
|
||||
#[allow(unused_comparisons)]
|
||||
#[inline]
|
||||
fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] {
|
||||
fn write(self, buf: &mut [MaybeUninit<u8>; $max_len]) -> &str {
|
||||
let is_nonnegative = self >= 0;
|
||||
let n = if is_nonnegative {
|
||||
self as u128
|
||||
|
|
@ -305,13 +232,13 @@ macro_rules! impl_Integer128 {
|
|||
(!(self as u128)).wrapping_add(1)
|
||||
};
|
||||
let mut curr = buf.len() as isize;
|
||||
let buf_ptr = buf.as_mut_ptr();
|
||||
let buf_ptr = buf.as_mut_ptr() as *mut u8;
|
||||
|
||||
unsafe {
|
||||
// Divide by 10^19 which is the highest power less than 2^64.
|
||||
let (n, rem) = udiv128::udivmod_1e19(n);
|
||||
let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
|
||||
curr -= rem.write_to(&mut *buf1).len() as isize;
|
||||
let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit<u8>; U64_MAX_LEN];
|
||||
curr -= rem.write(&mut *buf1).len() as isize;
|
||||
|
||||
if n != 0 {
|
||||
// Memset the base10 leading zeros of rem.
|
||||
|
|
@ -321,8 +248,8 @@ macro_rules! impl_Integer128 {
|
|||
|
||||
// Divide by 10^19 again.
|
||||
let (n, rem) = udiv128::udivmod_1e19(n);
|
||||
let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN];
|
||||
curr -= rem.write_to(&mut *buf2).len() as isize;
|
||||
let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit<u8>; U64_MAX_LEN];
|
||||
curr -= rem.write(&mut *buf2).len() as isize;
|
||||
|
||||
if n != 0 {
|
||||
// Memset the leading zeros.
|
||||
|
|
@ -343,16 +270,15 @@ macro_rules! impl_Integer128 {
|
|||
}
|
||||
|
||||
let len = buf.len() - curr as usize;
|
||||
slice::from_raw_parts(buf_ptr.offset(curr), len)
|
||||
let bytes = slice::from_raw_parts(buf_ptr.offset(curr), len);
|
||||
str::from_utf8_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "i128"))]
|
||||
const U128_MAX_LEN: usize = 39;
|
||||
const I128_MAX_LEN: usize = 40;
|
||||
|
||||
#[cfg(all(feature = "i128"))]
|
||||
impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128);
|
||||
|
|
|
|||
6
third_party/rust/itoa/src/udiv128.rs
vendored
6
third_party/rust/itoa/src/udiv128.rs
vendored
|
|
@ -12,7 +12,7 @@ fn u128_mulhi(x: u128, y: u128) -> u128 {
|
|||
let high1 = m >> 64;
|
||||
|
||||
let m_lo = m as u64;
|
||||
let high2 = x_hi as u128 * y_lo as u128 + m_lo as u128 >> 64;
|
||||
let high2 = (x_hi as u128 * y_lo as u128 + m_lo as u128) >> 64;
|
||||
|
||||
x_hi as u128 * y_hi as u128 + high1 + high2
|
||||
}
|
||||
|
|
@ -32,9 +32,7 @@ pub fn udivmod_1e19(n: u128) -> (u128, u64) {
|
|||
let quot = if n < 1 << 83 {
|
||||
((n >> 19) as u64 / (d >> 19)) as u128
|
||||
} else {
|
||||
let factor =
|
||||
(8507059173023461586_u64 as u128) << 64 | 10779635027931437427 as u128;
|
||||
u128_mulhi(n, factor) >> 62
|
||||
u128_mulhi(n, 156927543384667019095894735580191660403) >> 62
|
||||
};
|
||||
|
||||
let rem = (n - quot * d as u128) as u64;
|
||||
|
|
|
|||
44
third_party/rust/itoa/tests/test.rs
vendored
44
third_party/rust/itoa/tests/test.rs
vendored
|
|
@ -1,28 +1,13 @@
|
|||
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, string_lit_as_bytes))]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate itoa;
|
||||
#![allow(clippy::cast_lossless)]
|
||||
|
||||
macro_rules! test {
|
||||
(
|
||||
($($name:ident($value:expr, $expected:expr))*) => {
|
||||
$(
|
||||
$(#[$attr:meta])*
|
||||
$name:ident($value:expr, $expected:expr)
|
||||
),*
|
||||
) => {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[test]
|
||||
fn $name() {
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
let mut buf = [b'\0'; 40];
|
||||
let len = itoa::write(&mut buf[..], $value).unwrap();
|
||||
assert_eq!(&buf[0..len], $expected.as_bytes());
|
||||
}
|
||||
|
||||
let mut s = String::new();
|
||||
itoa::fmt(&mut s, $value).unwrap();
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
let s = buffer.format($value);
|
||||
assert_eq!(s, $expected);
|
||||
}
|
||||
)*
|
||||
|
|
@ -30,18 +15,15 @@ macro_rules! test {
|
|||
}
|
||||
|
||||
test! {
|
||||
test_u64_0(0u64, "0"),
|
||||
test_u64_half(<u32>::max_value() as u64, "4294967295"),
|
||||
test_u64_max(<u64>::max_value(), "18446744073709551615"),
|
||||
test_i64_min(<i64>::min_value(), "-9223372036854775808"),
|
||||
test_u64_0(0u64, "0")
|
||||
test_u64_half(u32::max_value() as u64, "4294967295")
|
||||
test_u64_max(u64::max_value(), "18446744073709551615")
|
||||
test_i64_min(i64::min_value(), "-9223372036854775808")
|
||||
|
||||
test_i16_0(0i16, "0"),
|
||||
test_i16_min(<i16>::min_value(), "-32768"),
|
||||
test_i16_0(0i16, "0")
|
||||
test_i16_min(i16::min_value(), "-32768")
|
||||
|
||||
#[cfg(feature = "i128")]
|
||||
test_u128_0(0u128, "0"),
|
||||
#[cfg(feature = "i128")]
|
||||
test_u128_max(<u128>::max_value(), "340282366920938463463374607431768211455"),
|
||||
#[cfg(feature = "i128")]
|
||||
test_i128_min(<i128>::min_value(), "-170141183460469231731687303715884105728")
|
||||
test_u128_0(0u128, "0")
|
||||
test_u128_max(u128::max_value(), "340282366920938463463374607431768211455")
|
||||
test_i128_min(i128::min_value(), "-170141183460469231731687303715884105728")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue