diff --git a/.travis.yml b/.travis.yml index 5abe18d..7e2bcbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ matrix: - rust: nightly - rust: nightly env: - - NODROP_FEATURES='no_drop_flag' + - NODROP_FEATURES='no_drop_flag use_needs_drop' script: - | [ -z "$NODROP_FEATURES" ] && cargo build --verbose --features "$FEATURES" diff --git a/README.rst b/README.rst index 8fc385b..2fa899d 100644 --- a/README.rst +++ b/README.rst @@ -19,8 +19,8 @@ __ http://bluss.github.io/arrayvec .. |crates2| image:: http://meritbadge.herokuapp.com/nodrop .. _crates2: https://crates.io/crates/nodrop -Recent Changes --------------- +Recent Changes (arrayvec) +------------------------- - 0.3.12 @@ -44,6 +44,16 @@ Recent Changes - Added method .into_inner() - Added unsafe method .set_len() +Recent Changes (nodrop) +----------------------- + +- 0.1.5 + + - Added crate feature ``use_needs_drop`` which is a nightly-only + optimization, which skips overwriting if the inner value does not need + drop. + + License ======= diff --git a/nodrop/Cargo.toml b/nodrop/Cargo.toml index 4049f7b..678db85 100644 --- a/nodrop/Cargo.toml +++ b/nodrop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nodrop" -version = "0.1.4" +version = "0.1.5" authors = ["bluss"] license = "MIT/Apache-2.0" @@ -17,5 +17,9 @@ keywords = ["container", "drop"] # Use no drop flag. See API doc for more info. no_drop_flag = [] +# Optional, nightly channel +# Use `needs_drop` to skip overwriting if not necessary +use_needs_drop = [] + [dependencies.odds] version = "0.2" diff --git a/nodrop/src/lib.rs b/nodrop/src/lib.rs index 7a41c3c..645e2b3 100644 --- a/nodrop/src/lib.rs +++ b/nodrop/src/lib.rs @@ -1,6 +1,10 @@ //! //! The **nodrop** crate has the following cargo feature flags: //! +//! - `use_needs_drop` +//! - Optional +//! - Requires nightly channel. +//! - Use `needs_drop` to skip overwriting if not necessary //! - `no_drop_flag`. //! - Optional. //! - Requires nightly channel. @@ -11,6 +15,7 @@ //! #![cfg_attr(feature="no_drop_flag", feature(unsafe_no_drop_flag))] +#![cfg_attr(feature="use_needs_drop", feature(core_intrinsics))] extern crate odds; @@ -52,12 +57,28 @@ impl NoDrop { } } +#[cfg(not(feature = "use_needs_drop"))] +#[inline] +fn needs_drop() -> bool { + true +} + +#[cfg(feature = "use_needs_drop")] +#[inline] +fn needs_drop() -> bool { + unsafe { + std::intrinsics::needs_drop::() + } +} + impl Drop for NoDrop { fn drop(&mut self) { - // no drop flag info: writing repeatedly is idempotent - // inhibit drop - unsafe { - ptr::write(&mut self.0, Flag::Dropped); + if needs_drop::() { + // no drop flag info: writing repeatedly is idempotent + // inhibit drop + unsafe { + ptr::write(&mut self.0, Flag::Dropped); + } } } }