Add support for 128-bit integers

This commit is contained in:
Henning Ottesen 2017-09-12 22:52:24 +02:00
parent d954ca8451
commit e9069ce1f1
6 changed files with 72 additions and 26 deletions

View File

@ -1,6 +1,17 @@
sudo: false sudo: false
language: rust language: rust
rust: matrix:
- nightly include:
- rust: stable
- rust: beta
- rust: nightly
env:
- FEATURES="i128"
- BUILD_BENCH="true"
script:
- cargo build --verbose --features "$FEATURES"
- cargo test --verbose --features "$FEATURES"
- if [ "$BUILD_BENCH" == "true" ]; then cargo bench --verbose --no-run --features "$FEATURES"; fi

View File

@ -9,3 +9,6 @@ documentation = "https://github.com/dtolnay/itoa"
categories = ["value-formatting"] categories = ["value-formatting"]
readme = "README.md" readme = "README.md"
exclude = ["performance.png"] exclude = ["performance.png"]
[features]
i128 = []

View File

@ -41,8 +41,9 @@ fn write<W: io::Write, V: itoa::Integer>(writer: W, value: V) -> io::Result<usiz
``` ```
where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`,
`i64`, `u64`, `isize` and `usize`. The return value gives the number of bytes `i64`, `u64`, `i128`, `u128`, `isize` and `usize`. 128-bit integer support is
written. only available with the nightly compiler when the `i128` feature is enabled for
this crate. The return value gives the number of bytes written.
## Dependency ## Dependency

View File

@ -1,3 +1,4 @@
#![cfg_attr(feature = "i128", feature(i128_type, i128))]
#![feature(test)] #![feature(test)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
@ -5,15 +6,21 @@ extern crate itoa;
extern crate test; extern crate test;
macro_rules! benches { macro_rules! benches {
($($name:ident($value:expr),)*) => { (
$(
$(#[$attr:meta])*
$name:ident($value:expr)
),*
) => {
mod bench_itoa { mod bench_itoa {
use test::{Bencher, black_box}; use test::{Bencher, black_box};
$( $(
$(#[$attr])*
#[bench] #[bench]
fn $name(b: &mut Bencher) { fn $name(b: &mut Bencher) {
use itoa; use itoa;
let mut buf = Vec::with_capacity(20); let mut buf = Vec::with_capacity(40);
b.iter(|| { b.iter(|| {
buf.clear(); buf.clear();
@ -26,11 +33,12 @@ macro_rules! benches {
mod bench_fmt { mod bench_fmt {
use test::{Bencher, black_box}; use test::{Bencher, black_box};
$( $(
$(#[$attr])*
#[bench] #[bench]
fn $name(b: &mut Bencher) { fn $name(b: &mut Bencher) {
use std::io::Write; use std::io::Write;
let mut buf = Vec::with_capacity(20); let mut buf = Vec::with_capacity(40);
b.iter(|| { b.iter(|| {
buf.clear(); buf.clear();
@ -42,11 +50,16 @@ macro_rules! benches {
} }
} }
benches!( benches!{
bench_0u64(0u64), bench_u64_0(0u64),
bench_HALFu64(<u32>::max_value() as u64), bench_u64_half(<u32>::max_value() as u64),
bench_MAXu64(<u64>::max_value()), bench_u64_max(<u64>::max_value()),
bench_0i16(0i16), bench_i16_0(0i16),
bench_MINi16(<i16>::min_value()), bench_i16_min(<i16>::min_value()),
);
#[cfg(feature = "i128")]
bench_u128_0(0u128),
#[cfg(feature = "i128")]
bench_u128_max(<u128>::max_value())
}

View File

@ -8,6 +8,8 @@
#![doc(html_root_url = "https://docs.rs/itoa/0.3.3")] #![doc(html_root_url = "https://docs.rs/itoa/0.3.3")]
#![cfg_attr(feature = "i128", feature(i128_type, i128))]
use std::{io, mem, ptr, slice}; use std::{io, mem, ptr, slice};
#[inline] #[inline]
@ -30,7 +32,7 @@ const DEC_DIGITS_LUT: &'static[u8] =
6061626364656667686970717273747576777879\ 6061626364656667686970717273747576777879\
8081828384858687888990919293949596979899"; 8081828384858687888990919293949596979899";
const MAX_LEN: usize = 20; // Tie between i64::MIN (including minus sign) and u64::MAX const MAX_LEN: usize = 40; // i128::MIN (including minus sign)
// Adaptation of the original implementation at // Adaptation of the original implementation at
// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266 // https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266
@ -115,3 +117,5 @@ impl_Integer!(isize, usize as u16);
impl_Integer!(isize, usize as u32); impl_Integer!(isize, usize as u32);
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
impl_Integer!(isize, usize as u64); impl_Integer!(isize, usize as u64);
#[cfg(feature = "i128")]
impl_Integer!(i128, u128 as u128);

View File

@ -1,13 +1,20 @@
#![cfg_attr(feature = "i128", feature(i128_type, i128))]
#![allow(non_snake_case)] #![allow(non_snake_case)]
extern crate itoa; extern crate itoa;
macro_rules! test { macro_rules! test {
($($name:ident($value:expr, $expected:expr),)*) => { (
$( $(
$(#[$attr:meta])*
$name:ident($value:expr, $expected:expr)
),*
) => {
$(
$(#[$attr])*
#[test] #[test]
fn $name() { fn $name() {
let mut buf = [b'\0'; 20]; let mut buf = [b'\0'; 40];
let len = itoa::write(&mut buf[..], $value).unwrap(); let len = itoa::write(&mut buf[..], $value).unwrap();
assert_eq!(&buf[0..len], $expected.as_bytes()); assert_eq!(&buf[0..len], $expected.as_bytes());
} }
@ -15,12 +22,19 @@ macro_rules! test {
} }
} }
test!( test!{
test_0u64(0u64, "0"), test_u64_0(0u64, "0"),
test_HALFu64(<u32>::max_value() as u64, "4294967295"), test_u64_half(<u32>::max_value() as u64, "4294967295"),
test_MAXu64(<u64>::max_value(), "18446744073709551615"), test_u64_max(<u64>::max_value(), "18446744073709551615"),
test_MINi64(<i64>::min_value(), "-9223372036854775808"), test_i64_min(<i64>::min_value(), "-9223372036854775808"),
test_0i16(0i16, "0"), test_i16_0(0i16, "0"),
test_MINi16(<i16>::min_value(), "-32768"), 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")
}