From fe810e8c5c2e41698174536bf09716a0bb5ef6d8 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Mon, 28 May 2018 16:12:04 +0200 Subject: [PATCH] Use reverse_bits intrinsic when running on nightly Detect nightly and auto-enable reverse_bits --- .travis.yml | 14 ++++++-------- Cargo.toml | 3 +++ benches/vob.rs | 9 +++++++++ build.rs | 19 +++++++++++++++++++ src/lib.rs | 23 ++++++++++++++++++----- 5 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 build.rs diff --git a/.travis.yml b/.travis.yml index 4277668..ca4672b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,11 @@ language: rust -matrix: - include: - - rust: nightly - env: FEATURES=unsafe_internals - - rust: nightly - env: FEATURES='' - - rust: stable - - rust: beta +rust: + - stable + - nightly +env: + - FEATURES='' + - FEATURES='unsafe_internals' before_script: - rustup component add rustfmt-preview diff --git a/Cargo.toml b/Cargo.toml index af82120..ce058d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ readme = "README.md" license = "Apache-2.0 OR MIT" categories = ["data-structures"] +[build-dependencies] +rustc_version = "0.2" + [dependencies] num-traits = "0.2.1" serde = { version="1.0", features=["derive"], optional=true } diff --git a/benches/vob.rs b/benches/vob.rs index 56ba789..5cd83b4 100644 --- a/benches/vob.rs +++ b/benches/vob.rs @@ -101,3 +101,12 @@ fn and(bench: &mut Bencher) { a.and(&b); }); } + +#[bench] +fn from_bytes(b: &mut Bencher) { + let mut rng = rand::thread_rng(); + let mut source = [0u8; 1024]; + rng.fill(&mut source); + + b.iter(|| Vob::from_bytes(&source)); +} diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8cb47e0 --- /dev/null +++ b/build.rs @@ -0,0 +1,19 @@ +extern crate rustc_version; + +use rustc_version::{version_meta, Channel}; +use std::env; + +fn main() { + assert!( + !(env::var("CARGO_FEATURE_REVERSE_BITS").is_ok() + && env::var("CARGO_FEATURE_NO_REVERSE_BITS").is_ok()), + "Can't both enable and disable REVERSE_BITS" + ); + + // Set features depending on channel + if let Channel::Nightly = version_meta().unwrap().channel { + println!("cargo:rustc-cfg=nightly"); + // Nightly supports https://github.com/rust-lang/rust/issues/48763 + println!("cargo:rustc-cfg=reverse_bits"); + } +} diff --git a/src/lib.rs b/src/lib.rs index 4833637..c50be86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(nightly, feature(reverse_bits))] // Copyright (c) 2018 King's College London created by the Software Development Team // // @@ -162,6 +163,9 @@ impl Vob { /// Create a Vob from a `u8` slice. The most significant bit of each byte comes first in the /// resulting Vob. /// + /// If you are running nightly, this method will use the new `reverse_bits` intrinsic. + /// Set the `no_reverse_bits` feature to manually disable it. + /// /// # Examples /// /// ``` @@ -187,12 +191,21 @@ impl Vob { continue; } let b = slice[off]; - if b != 0 { - let mut rb: u8 = 0; // the byte b with its bits in reverse order - for k in 0..8 { - rb |= ((b >> k) & 1) << (8 - k - 1); + #[cfg(not(reverse_bits))] + { + if b != 0 { + { + let mut rb: u8 = 0; // the byte b with its bits in reverse order + for k in 0..8 { + rb |= ((b >> k) & 1) << (8 - k - 1); + } + w |= (rb as usize) << (j * 8); + } } - w |= (rb as usize) << (j * 8); + } + #[cfg(reverse_bits)] + { + w |= (b.reverse_bits() as usize) << (j * 8); } } v.vec.push(w);