Skip to content

Commit

Permalink
i128: enable support for 128-bit integers automatically
Browse files Browse the repository at this point in the history
This adds a build.rs to byteorder that will set a conditional compilation
flag automatically if the current Rust compiler supports 128-bit integers.

This makes the i128 feature itself a no-op. We continue to allow the
feature to be supplied for backwards compatibility.

Addresses bincode-org/bincode#250
  • Loading branch information
BurntSushi committed Jan 19, 2019
1 parent 688ec9d commit 168648f
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 186 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Expand Up @@ -23,6 +23,10 @@ rand = "0.6"
[features]
default = ["std"]
std = []

# This feature is no longer used and is DEPRECATED. This crate now
# automatically enables i128 support for Rust compilers that support it. The
# feature will be removed if and when a new major version is released.
i128 = []

[profile.bench]
Expand Down
68 changes: 34 additions & 34 deletions benches/bench.rs
Expand Up @@ -148,108 +148,108 @@ bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]);
bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]);
bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]);

#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(u128, MAX, read_u128, write_u128,
16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(i128, MAX, read_i128, write_i128,
16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_1, read_uint128,
1, [1]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_2, read_uint128,
2, [1, 2]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_3, read_uint128,
3, [1, 2, 3]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_4, read_uint128,
4, [1, 2, 3, 4]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_5, read_uint128,
5, [1, 2, 3, 4, 5]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_6, read_uint128,
6, [1, 2, 3, 4, 5, 6]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_7, read_uint128,
7, [1, 2, 3, 4, 5, 6, 7]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_8, read_uint128,
8, [1, 2, 3, 4, 5, 6, 7, 8]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_9, read_uint128,
9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_10, read_uint128,
10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_11, read_uint128,
11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_12, read_uint128,
12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_13, read_uint128,
13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_14, read_uint128,
14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_15, read_uint128,
15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(uint128_16, read_uint128,
16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_1, read_int128,
1, [1]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_2, read_int128,
2, [1, 2]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_3, read_int128,
3, [1, 2, 3]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_4, read_int128,
4, [1, 2, 3, 4]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_5, read_int128,
5, [1, 2, 3, 4, 5]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_6, read_int128,
6, [1, 2, 3, 4, 5, 6]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_7, read_int128,
7, [1, 2, 3, 4, 5, 6, 7]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_8, read_int128,
8, [1, 2, 3, 4, 5, 6, 7, 8]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_9, read_int128,
9, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_10, read_int128,
10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_11, read_int128,
11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_12, read_int128,
12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_13, read_int128,
13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_14, read_int128,
14, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_15, read_int128,
15, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
bench_num!(int128_16, read_int128,
16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

Expand Down
82 changes: 82 additions & 0 deletions build.rs
@@ -0,0 +1,82 @@
use std::env;
use std::ffi::OsString;
use std::process::Command;

fn main() {
let version = match Version::read() {
Ok(version) => version,
Err(err) => {
eprintln!("failed to parse `rustc --version`: {}", err);
return;
}
};
enable_i128(version);
}

fn enable_i128(version: Version) {
if version < (Version { major: 1, minor: 26, patch: 0 }) {
return;
}

println!("cargo:rustc-cfg=byteorder_i128");
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
struct Version {
major: u32,
minor: u32,
patch: u32,
}

impl Version {
fn read() -> Result<Version, String> {
let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc"));
let output = Command::new(&rustc)
.arg("--version")
.output()
.unwrap()
.stdout;
Version::parse(&String::from_utf8(output).unwrap())
}

fn parse(mut s: &str) -> Result<Version, String> {
if !s.starts_with("rustc ") {
return Err(format!("unrecognized version string: {}", s));
}
s = &s["rustc ".len()..];

let parts: Vec<&str> = s.split(".").collect();
if parts.len() < 3 {
return Err(format!("not enough version parts: {:?}", parts));
}

let mut num = String::new();
for c in parts[0].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let major = num.parse::<u32>().map_err(|e| e.to_string())?;

num.clear();
for c in parts[1].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let minor = num.parse::<u32>().map_err(|e| e.to_string())?;

num.clear();
for c in parts[2].chars() {
if !c.is_digit(10) {
break;
}
num.push(c);
}
let patch = num.parse::<u32>().map_err(|e| e.to_string())?;

Ok(Version { major, minor, patch })
}
}
21 changes: 10 additions & 11 deletions src/io.rs
Expand Up @@ -370,7 +370,7 @@ pub trait ReadBytesExt: io::Read {
/// ]);
/// assert_eq!(16947640962301618749969007319746179, rdr.read_u128::<BigEndian>().unwrap());
/// ```
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
let mut buf = [0; 16];
Expand All @@ -391,14 +391,13 @@ pub trait ReadBytesExt: io::Read {
/// Read a signed 128 bit big-endian integer from a `Read`:
///
/// ```rust
/// #![feature(i128_type)]
/// use std::io::Cursor;
/// use byteorder::{BigEndian, ReadBytesExt};
///
/// let mut rdr = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// assert_eq!(i128::min_value(), rdr.read_i128::<BigEndian>().unwrap());
/// ```
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_i128<T: ByteOrder>(&mut self) -> Result<i128> {
let mut buf = [0; 16];
Expand Down Expand Up @@ -457,7 +456,7 @@ pub trait ReadBytesExt: io::Read {
}

/// Reads an unsigned n-bytes integer from the underlying reader.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_uint128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u128> {
let mut buf = [0; 16];
Expand All @@ -466,7 +465,7 @@ pub trait ReadBytesExt: io::Read {
}

/// Reads a signed n-bytes integer from the underlying reader.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_int128<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i128> {
let mut buf = [0; 16];
Expand Down Expand Up @@ -672,7 +671,7 @@ pub trait ReadBytesExt: io::Read {
/// rdr.read_u128_into::<BigEndian>(&mut dst).unwrap();
/// assert_eq!([517, 768], dst);
/// ```
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_u128_into<T: ByteOrder>(
&mut self,
Expand Down Expand Up @@ -822,7 +821,7 @@ pub trait ReadBytesExt: io::Read {
/// rdr.read_i128_into::<BigEndian>(&mut dst).unwrap();
/// assert_eq!([517, 768], dst);
/// ```
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn read_i128_into<T: ByteOrder>(
&mut self,
Expand Down Expand Up @@ -1373,7 +1372,7 @@ pub trait WriteBytesExt: io::Write {
}

/// Writes an unsigned 128 bit integer to the underlying writer.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
let mut buf = [0; 16];
Expand All @@ -1382,7 +1381,7 @@ pub trait WriteBytesExt: io::Write {
}

/// Writes a signed 128 bit integer to the underlying writer.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn write_i128<T: ByteOrder>(&mut self, n: i128) -> Result<()> {
let mut buf = [0; 16];
Expand Down Expand Up @@ -1466,7 +1465,7 @@ pub trait WriteBytesExt: io::Write {
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 16`, this method panics.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn write_uint128<T: ByteOrder>(
&mut self,
Expand All @@ -1482,7 +1481,7 @@ pub trait WriteBytesExt: io::Write {
///
/// If the given integer is not representable in the given number of bytes,
/// this method panics. If `nbytes > 16`, this method panics.
#[cfg(feature = "i128")]
#[cfg(byteorder_i128)]
#[inline]
fn write_int128<T: ByteOrder>(
&mut self,
Expand Down

0 comments on commit 168648f

Please sign in to comment.