mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Move flt2dec::{Formatted, Part}
to dedicated module
They are used by integer formatting as well and is not exclusive to float.
This commit is contained in:
parent
ac3e680193
commit
37647d1733
@ -1,6 +1,7 @@
|
|||||||
use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
|
use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
use crate::num::flt2dec;
|
use crate::num::flt2dec;
|
||||||
|
use crate::num::fmt as numfmt;
|
||||||
|
|
||||||
// Don't inline this so callers don't use the stack space this function
|
// Don't inline this so callers don't use the stack space this function
|
||||||
// requires unless they have to.
|
// requires unless they have to.
|
||||||
@ -15,7 +16,7 @@ where
|
|||||||
T: flt2dec::DecodableFloat,
|
T: flt2dec::DecodableFloat,
|
||||||
{
|
{
|
||||||
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
|
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
|
||||||
let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
|
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
|
||||||
let formatted = flt2dec::to_exact_fixed_str(
|
let formatted = flt2dec::to_exact_fixed_str(
|
||||||
flt2dec::strategy::grisu::format_exact,
|
flt2dec::strategy::grisu::format_exact,
|
||||||
*num,
|
*num,
|
||||||
@ -41,7 +42,7 @@ where
|
|||||||
{
|
{
|
||||||
// enough for f32 and f64
|
// enough for f32 and f64
|
||||||
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
|
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
|
||||||
let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
|
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
|
||||||
let formatted = flt2dec::to_shortest_str(
|
let formatted = flt2dec::to_shortest_str(
|
||||||
flt2dec::strategy::grisu::format_shortest,
|
flt2dec::strategy::grisu::format_shortest,
|
||||||
*num,
|
*num,
|
||||||
@ -85,7 +86,7 @@ where
|
|||||||
T: flt2dec::DecodableFloat,
|
T: flt2dec::DecodableFloat,
|
||||||
{
|
{
|
||||||
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
|
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
|
||||||
let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
|
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
|
||||||
let formatted = flt2dec::to_exact_exp_str(
|
let formatted = flt2dec::to_exact_exp_str(
|
||||||
flt2dec::strategy::grisu::format_exact,
|
flt2dec::strategy::grisu::format_exact,
|
||||||
*num,
|
*num,
|
||||||
@ -112,7 +113,7 @@ where
|
|||||||
{
|
{
|
||||||
// enough for f32 and f64
|
// enough for f32 and f64
|
||||||
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
|
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
|
||||||
let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
|
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
|
||||||
let formatted = flt2dec::to_shortest_exp_str(
|
let formatted = flt2dec::to_shortest_exp_str(
|
||||||
flt2dec::strategy::grisu::format_shortest,
|
flt2dec::strategy::grisu::format_shortest,
|
||||||
*num,
|
*num,
|
||||||
|
@ -7,7 +7,7 @@ use crate::char::EscapeDebugExtArgs;
|
|||||||
use crate::iter;
|
use crate::iter;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::num::flt2dec;
|
use crate::num::fmt as numfmt;
|
||||||
use crate::ops::Deref;
|
use crate::ops::Deref;
|
||||||
use crate::result;
|
use crate::result;
|
||||||
use crate::str;
|
use crate::str;
|
||||||
@ -1421,7 +1421,7 @@ impl<'a> Formatter<'a> {
|
|||||||
/// Takes the formatted parts and applies the padding.
|
/// Takes the formatted parts and applies the padding.
|
||||||
/// Assumes that the caller already has rendered the parts with required precision,
|
/// Assumes that the caller already has rendered the parts with required precision,
|
||||||
/// so that `self.precision` can be ignored.
|
/// so that `self.precision` can be ignored.
|
||||||
fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result {
|
fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
|
||||||
if let Some(mut width) = self.width {
|
if let Some(mut width) = self.width {
|
||||||
// for the sign-aware zero padding, we render the sign first and
|
// for the sign-aware zero padding, we render the sign first and
|
||||||
// behave as if we had no sign from the beginning.
|
// behave as if we had no sign from the beginning.
|
||||||
@ -1461,14 +1461,14 @@ impl<'a> Formatter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result {
|
fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
|
||||||
fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
|
fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
|
||||||
// SAFETY: This is used for `flt2dec::Part::Num` and `flt2dec::Part::Copy`.
|
// SAFETY: This is used for `numfmt::Part::Num` and `numfmt::Part::Copy`.
|
||||||
// It's safe to use for `flt2dec::Part::Num` since every char `c` is between
|
// It's safe to use for `numfmt::Part::Num` since every char `c` is between
|
||||||
// `b'0'` and `b'9'`, which means `s` is valid UTF-8.
|
// `b'0'` and `b'9'`, which means `s` is valid UTF-8.
|
||||||
// It's also probably safe in practice to use for `flt2dec::Part::Copy(buf)`
|
// It's also probably safe in practice to use for `numfmt::Part::Copy(buf)`
|
||||||
// since `buf` should be plain ASCII, but it's possible for someone to pass
|
// since `buf` should be plain ASCII, but it's possible for someone to pass
|
||||||
// in a bad value for `buf` into `flt2dec::to_shortest_str` since it is a
|
// in a bad value for `buf` into `numfmt::to_shortest_str` since it is a
|
||||||
// public function.
|
// public function.
|
||||||
// FIXME: Determine whether this could result in UB.
|
// FIXME: Determine whether this could result in UB.
|
||||||
buf.write_str(unsafe { str::from_utf8_unchecked(s) })
|
buf.write_str(unsafe { str::from_utf8_unchecked(s) })
|
||||||
@ -1479,7 +1479,7 @@ impl<'a> Formatter<'a> {
|
|||||||
}
|
}
|
||||||
for part in formatted.parts {
|
for part in formatted.parts {
|
||||||
match *part {
|
match *part {
|
||||||
flt2dec::Part::Zero(mut nzeroes) => {
|
numfmt::Part::Zero(mut nzeroes) => {
|
||||||
const ZEROES: &str = // 64 zeroes
|
const ZEROES: &str = // 64 zeroes
|
||||||
"0000000000000000000000000000000000000000000000000000000000000000";
|
"0000000000000000000000000000000000000000000000000000000000000000";
|
||||||
while nzeroes > ZEROES.len() {
|
while nzeroes > ZEROES.len() {
|
||||||
@ -1490,7 +1490,7 @@ impl<'a> Formatter<'a> {
|
|||||||
self.buf.write_str(&ZEROES[..nzeroes])?;
|
self.buf.write_str(&ZEROES[..nzeroes])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flt2dec::Part::Num(mut v) => {
|
numfmt::Part::Num(mut v) => {
|
||||||
let mut s = [0; 5];
|
let mut s = [0; 5];
|
||||||
let len = part.len();
|
let len = part.len();
|
||||||
for c in s[..len].iter_mut().rev() {
|
for c in s[..len].iter_mut().rev() {
|
||||||
@ -1499,7 +1499,7 @@ impl<'a> Formatter<'a> {
|
|||||||
}
|
}
|
||||||
write_bytes(self.buf, &s[..len])?;
|
write_bytes(self.buf, &s[..len])?;
|
||||||
}
|
}
|
||||||
flt2dec::Part::Copy(buf) => {
|
numfmt::Part::Copy(buf) => {
|
||||||
write_bytes(self.buf, buf)?;
|
write_bytes(self.buf, buf)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
use crate::num::flt2dec;
|
use crate::num::fmt as numfmt;
|
||||||
use crate::ops::{Div, Rem, Sub};
|
use crate::ops::{Div, Rem, Sub};
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::slice;
|
use crate::slice;
|
||||||
@ -406,9 +406,9 @@ macro_rules! impl_Exp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let parts = &[
|
let parts = &[
|
||||||
flt2dec::Part::Copy(buf_slice),
|
numfmt::Part::Copy(buf_slice),
|
||||||
flt2dec::Part::Zero(added_precision),
|
numfmt::Part::Zero(added_precision),
|
||||||
flt2dec::Part::Copy(exp_slice)
|
numfmt::Part::Copy(exp_slice)
|
||||||
];
|
];
|
||||||
let sign = if !is_nonnegative {
|
let sign = if !is_nonnegative {
|
||||||
"-"
|
"-"
|
||||||
@ -417,7 +417,7 @@ macro_rules! impl_Exp {
|
|||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
let formatted = flt2dec::Formatted{sign, parts};
|
let formatted = numfmt::Formatted{sign, parts};
|
||||||
f.pad_formatted_parts(&formatted)
|
f.pad_formatted_parts(&formatted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ functions.
|
|||||||
|
|
||||||
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
|
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
|
||||||
|
|
||||||
|
use super::fmt::{Formatted, Part};
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
|
|
||||||
pub mod decoder;
|
pub mod decoder;
|
||||||
@ -170,107 +171,6 @@ pub fn round_up(d: &mut [u8]) -> Option<u8> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formatted parts.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub enum Part<'a> {
|
|
||||||
/// Given number of zero digits.
|
|
||||||
Zero(usize),
|
|
||||||
/// A literal number up to 5 digits.
|
|
||||||
Num(u16),
|
|
||||||
/// A verbatim copy of given bytes.
|
|
||||||
Copy(&'a [u8]),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Part<'a> {
|
|
||||||
/// Returns the exact byte length of given part.
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
match *self {
|
|
||||||
Part::Zero(nzeroes) => nzeroes,
|
|
||||||
Part::Num(v) => {
|
|
||||||
if v < 1_000 {
|
|
||||||
if v < 10 {
|
|
||||||
1
|
|
||||||
} else if v < 100 {
|
|
||||||
2
|
|
||||||
} else {
|
|
||||||
3
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if v < 10_000 { 4 } else { 5 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Part::Copy(buf) => buf.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a part into the supplied buffer.
|
|
||||||
/// Returns the number of written bytes, or `None` if the buffer is not enough.
|
|
||||||
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
|
|
||||||
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
|
|
||||||
let len = self.len();
|
|
||||||
if out.len() >= len {
|
|
||||||
match *self {
|
|
||||||
Part::Zero(nzeroes) => {
|
|
||||||
for c in &mut out[..nzeroes] {
|
|
||||||
*c = b'0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Part::Num(mut v) => {
|
|
||||||
for c in out[..len].iter_mut().rev() {
|
|
||||||
*c = b'0' + (v % 10) as u8;
|
|
||||||
v /= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Part::Copy(buf) => {
|
|
||||||
out[..buf.len()].copy_from_slice(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(len)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Formatted result containing one or more parts.
|
|
||||||
/// This can be written to the byte buffer or converted to the allocated string.
|
|
||||||
#[allow(missing_debug_implementations)]
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Formatted<'a> {
|
|
||||||
/// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
|
|
||||||
pub sign: &'static str,
|
|
||||||
/// Formatted parts to be rendered after a sign and optional zero padding.
|
|
||||||
pub parts: &'a [Part<'a>],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Formatted<'a> {
|
|
||||||
/// Returns the exact byte length of combined formatted result.
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
let mut len = self.sign.len();
|
|
||||||
for part in self.parts {
|
|
||||||
len += part.len();
|
|
||||||
}
|
|
||||||
len
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes all formatted parts into the supplied buffer.
|
|
||||||
/// Returns the number of written bytes, or `None` if the buffer is not enough.
|
|
||||||
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
|
|
||||||
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
|
|
||||||
if out.len() < self.sign.len() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
|
|
||||||
|
|
||||||
let mut written = self.sign.len();
|
|
||||||
for part in self.parts {
|
|
||||||
let len = part.write(&mut out[written..])?;
|
|
||||||
written += len;
|
|
||||||
}
|
|
||||||
Some(written)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Formats given decimal digits `0.<...buf...> * 10^exp` into the decimal form
|
/// Formats given decimal digits `0.<...buf...> * 10^exp` into the decimal form
|
||||||
/// with at least given number of fractional digits. The result is stored to
|
/// with at least given number of fractional digits. The result is stored to
|
||||||
/// the supplied parts array and a slice of written parts is returned.
|
/// the supplied parts array and a slice of written parts is returned.
|
||||||
|
108
library/core/src/num/fmt.rs
Normal file
108
library/core/src/num/fmt.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
//! Shared utilties used by both float and integer formatting.
|
||||||
|
#![doc(hidden)]
|
||||||
|
#![unstable(
|
||||||
|
feature = "numfmt",
|
||||||
|
reason = "internal routines only exposed for testing",
|
||||||
|
issue = "none"
|
||||||
|
)]
|
||||||
|
|
||||||
|
/// Formatted parts.
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub enum Part<'a> {
|
||||||
|
/// Given number of zero digits.
|
||||||
|
Zero(usize),
|
||||||
|
/// A literal number up to 5 digits.
|
||||||
|
Num(u16),
|
||||||
|
/// A verbatim copy of given bytes.
|
||||||
|
Copy(&'a [u8]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Part<'a> {
|
||||||
|
/// Returns the exact byte length of given part.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
match *self {
|
||||||
|
Part::Zero(nzeroes) => nzeroes,
|
||||||
|
Part::Num(v) => {
|
||||||
|
if v < 1_000 {
|
||||||
|
if v < 10 {
|
||||||
|
1
|
||||||
|
} else if v < 100 {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if v < 10_000 { 4 } else { 5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Part::Copy(buf) => buf.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes a part into the supplied buffer.
|
||||||
|
/// Returns the number of written bytes, or `None` if the buffer is not enough.
|
||||||
|
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
|
||||||
|
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
|
||||||
|
let len = self.len();
|
||||||
|
if out.len() >= len {
|
||||||
|
match *self {
|
||||||
|
Part::Zero(nzeroes) => {
|
||||||
|
for c in &mut out[..nzeroes] {
|
||||||
|
*c = b'0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Part::Num(mut v) => {
|
||||||
|
for c in out[..len].iter_mut().rev() {
|
||||||
|
*c = b'0' + (v % 10) as u8;
|
||||||
|
v /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Part::Copy(buf) => {
|
||||||
|
out[..buf.len()].copy_from_slice(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(len)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Formatted result containing one or more parts.
|
||||||
|
/// This can be written to the byte buffer or converted to the allocated string.
|
||||||
|
#[allow(missing_debug_implementations)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Formatted<'a> {
|
||||||
|
/// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
|
||||||
|
pub sign: &'static str,
|
||||||
|
/// Formatted parts to be rendered after a sign and optional zero padding.
|
||||||
|
pub parts: &'a [Part<'a>],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Formatted<'a> {
|
||||||
|
/// Returns the exact byte length of combined formatted result.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
let mut len = self.sign.len();
|
||||||
|
for part in self.parts {
|
||||||
|
len += part.len();
|
||||||
|
}
|
||||||
|
len
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes all formatted parts into the supplied buffer.
|
||||||
|
/// Returns the number of written bytes, or `None` if the buffer is not enough.
|
||||||
|
/// (It may still leave partially written bytes in the buffer; do not rely on that.)
|
||||||
|
pub fn write(&self, out: &mut [u8]) -> Option<usize> {
|
||||||
|
if out.len() < self.sign.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
|
||||||
|
|
||||||
|
let mut written = self.sign.len();
|
||||||
|
for part in self.parts {
|
||||||
|
let len = part.write(&mut out[written..])?;
|
||||||
|
written += len;
|
||||||
|
}
|
||||||
|
Some(written)
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@ pub mod bignum;
|
|||||||
pub mod dec2flt;
|
pub mod dec2flt;
|
||||||
pub mod diy_float;
|
pub mod diy_float;
|
||||||
pub mod flt2dec;
|
pub mod flt2dec;
|
||||||
|
pub mod fmt;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod int_macros; // import int_impl!
|
mod int_macros; // import int_impl!
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#![feature(maybe_uninit_extra)]
|
#![feature(maybe_uninit_extra)]
|
||||||
#![feature(maybe_uninit_write_slice)]
|
#![feature(maybe_uninit_write_slice)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![feature(numfmt)]
|
||||||
#![feature(step_trait)]
|
#![feature(step_trait)]
|
||||||
#![feature(str_internals)]
|
#![feature(str_internals)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
@ -2,10 +2,11 @@ use std::mem::MaybeUninit;
|
|||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
|
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
|
||||||
use core::num::flt2dec::{round_up, Formatted, Part, Sign, MAX_SIG_DIGITS};
|
use core::num::flt2dec::{round_up, Sign, MAX_SIG_DIGITS};
|
||||||
use core::num::flt2dec::{
|
use core::num::flt2dec::{
|
||||||
to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
|
to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
|
||||||
};
|
};
|
||||||
|
use core::num::fmt::{Formatted, Part};
|
||||||
|
|
||||||
pub use test::Bencher;
|
pub use test::Bencher;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user