From 8047dc621cb21e7683295a1864b8998fe2775a39 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 May 2015 11:54:35 +0200 Subject: [PATCH] Use crate nodrop -- it moved to a separate crate --- .travis.yml | 2 ++ Cargo.toml | 4 ++++ Makefile | 2 +- src/lib.rs | 62 ++++++++++++++--------------------------------------- 4 files changed, 23 insertions(+), 47 deletions(-) diff --git a/.travis.yml b/.travis.yml index 46ce8ac..69c9ab9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,7 @@ 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" diff --git a/Cargo.toml b/Cargo.toml index 79ee10b..83b42b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,7 @@ documentation = "http://bluss.github.io/arrayvec" repository = "https://github.com/bluss/arrayvec" keywords = ["stack", "vector", "array", "container", "data-structure"] + +[dependencies] + +nodrop = "0.1" diff --git a/Makefile b/Makefile index 764e6f4..051a17d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ docs: VERSION - cargo doc --no-deps + cargo doc rm -rf ./doc cp -r ./target/doc ./doc # Put in the crate version into the docs diff --git a/src/lib.rs b/src/lib.rs index 15cd179..c4a70c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +extern crate nodrop; + +use nodrop::NoDrop; + use std::iter; use std::mem; use std::ptr; @@ -12,13 +16,6 @@ use std::borrow::{Borrow, BorrowMut}; use std::hash::{Hash, Hasher}; use std::fmt; -/// Make sure the non-nullable pointer optimization does not occur! -#[repr(u8)] -enum Flag { - Dropped, - Alive(T), -} - /// Trait for fixed size arrays. pub unsafe trait Array { /// The array's element type @@ -77,17 +74,14 @@ fix_array_impl_recursive!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /// /// The vector also implements a by value iterator. pub struct ArrayVec { - xs: Flag, + xs: NoDrop, len: u8, } impl Drop for ArrayVec { fn drop(&mut self) { - // clear all elements, then inhibit drop of inner array + // clear all elements, then NoDrop inhibits drop of inner array while let Some(_) = self.pop() { } - unsafe { - ptr::write(&mut self.xs, Flag::Dropped); - } } } @@ -109,26 +103,7 @@ impl ArrayVec { /// ``` pub fn new() -> ArrayVec { unsafe { - ArrayVec { xs: Flag::Alive(Array::new()), len: 0 } - } - } - - #[inline] - fn inner_ref(&self) -> &A { - match self.xs { - Flag::Alive(ref xs) => xs, - _ => unreachable!(), - //_ => std::intrinsics::unreachable(), - } - } - - #[inline] - fn inner_mut(&mut self) -> &mut A { - // FIXME: Optimize this, we know it's always Some. - match self.xs { - Flag::Alive(ref mut xs) => xs, - _ => unreachable!(), - //_ => std::intrinsics::unreachable(), + ArrayVec { xs: NoDrop::new(Array::new()), len: 0 } } } @@ -221,7 +196,7 @@ impl Deref for ArrayVec { #[inline] fn deref(&self) -> &[A::Item] { unsafe { - slice::from_raw_parts(self.inner_ref().as_ptr(), self.len()) + slice::from_raw_parts(self.xs.as_ptr(), self.len()) } } } @@ -231,7 +206,7 @@ impl DerefMut for ArrayVec { fn deref_mut(&mut self) -> &mut [A::Item] { let len = self.len(); unsafe { - slice::from_raw_parts_mut(self.inner_mut().as_mut_ptr(), len) + slice::from_raw_parts_mut(self.xs.as_mut_ptr(), len) } } } @@ -248,7 +223,7 @@ impl DerefMut for ArrayVec { /// ``` impl From for ArrayVec { fn from(array: A) -> Self { - ArrayVec { xs: Flag::Alive(array), len: A::capacity() as u8 } + ArrayVec { xs: NoDrop::new(array), len: A::capacity() as u8 } } } @@ -538,21 +513,16 @@ fn test_is_send_sync() { &data as &Sync; } -#[test] -fn test_no_nonnullable_opt() { - // Make sure `Flag` does not apply the non-nullable pointer optimization - // as Option would do. - assert!(mem::size_of::>() > mem::size_of::<&i32>()); - assert!(mem::size_of::>>() > mem::size_of::>()); -} - #[test] fn test_compact_size() { - // 4 elements size + 1 len + 1 enum tag + [1 drop flag] + // Future rust will kill these drop flags! + // 4 elements size + 1 len + 1 enum tag + [1 drop flag] + [1 drop flag nodrop] type ByteArray = ArrayVec<[u8; 4]>; - assert!(mem::size_of::() <= 7); + println!("{}", mem::size_of::()); + assert!(mem::size_of::() <= 8); // 12 element size + 1 len + 1 drop flag + 2 padding + 1 enum tag + 3 padding type QuadArray = ArrayVec<[u32; 3]>; - assert!(mem::size_of::() <= 20); + println!("{}", mem::size_of::()); + assert!(mem::size_of::() <= 24); }