From 09cf5168f9e7b45597c2431a01e427063d959d8b Mon Sep 17 00:00:00 2001 From: root Date: Tue, 26 May 2015 17:05:42 +0200 Subject: [PATCH] nodrop: Add no_drop_flag optional feature --- .travis.yml | 15 +++++++++------ nodrop/Cargo.toml | 6 ++++++ nodrop/src/lib.rs | 33 +++++++++++++++++++++++++-------- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69c9ab9..46d18f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,14 @@ matrix: include: - rust: stable - rust: nightly + - rust: nightly + env: + - NODROP_FEATURES='no_drop_flag' script: - | - cargo build --verbose --features "$FEATURES" - cargo test --verbose --features "$FEATURES" - cargo test --verbose --manifest-path=nodrop/Cargo.toml - cargo bench --verbose --features "$FEATURES" -- --test - cargo bench --verbose --manifest-path=nodrop/Cargo.toml -- --test - cargo doc --verbose --features "$FEATURES" + [ -z "$NODROP_FEATURES" ] && cargo build --verbose --features "$FEATURES" + [ -z "$NODROP_FEATURES" ] && cargo test --verbose --features "$FEATURES" + [ -z "$NODROP_FEATURES" ] && cargo bench --verbose --features "$FEATURES" -- --test + [ -z "$NODROP_FEATURES" ] && cargo doc --verbose --features "$FEATURES" + cargo test --verbose --manifest-path=nodrop/Cargo.toml --features "$NODROP_FEATURES" + cargo bench --verbose --manifest-path=nodrop/Cargo.toml --features "$NODROP_FEATURES" -- --test diff --git a/nodrop/Cargo.toml b/nodrop/Cargo.toml index 71d306b..b000f94 100644 --- a/nodrop/Cargo.toml +++ b/nodrop/Cargo.toml @@ -10,3 +10,9 @@ documentation = "http://bluss.github.io/arrayvec/doc/nodrop" repository = "https://github.com/bluss/arrayvec" keywords = ["container", "drop"] + +[features] + +# Optional, nightly channel +# Use no drop flag. See API doc for more info. +no_drop_flag = [] diff --git a/nodrop/src/lib.rs b/nodrop/src/lib.rs index cdd5974..53d82f1 100644 --- a/nodrop/src/lib.rs +++ b/nodrop/src/lib.rs @@ -1,3 +1,17 @@ +//! +//! The **nodrop** crate has the following cargo feature flags: +//! +//! - `no_drop_flag`. +//! - Optional. +//! - Requires nightly channel. +//! - Use no drop flag on the **NoDrop** type, +//! which means less space overhead. Use with care and report a bug if anything +//! changes behavior with this feature. +//! +//! + +#![cfg_attr(feature="no_drop_flag", feature(unsafe_no_drop_flag))] + use std::ops::{Deref, DerefMut}; use std::ptr; use std::mem; @@ -10,6 +24,7 @@ enum Flag { } /// A type holding **T** that will not call its destructor on drop +#[cfg_attr(feature="no_drop_flag", unsafe_no_drop_flag)] pub struct NoDrop(Flag); impl NoDrop { @@ -33,6 +48,16 @@ impl NoDrop { } } +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); + } + } +} + enum Void { } /// FIXME: Replace with intrinsic when it's stable @@ -50,14 +75,6 @@ unsafe fn debug_assert_unreachable() -> ! { unreachable() } -impl Drop for NoDrop { - fn drop(&mut self) { - // inhibit drop - unsafe { - ptr::write(&mut self.0, Flag::Dropped); - } - } -} impl Deref for NoDrop { type Target = T;