+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "arrayvec"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
authors = ["bluss"]
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@ __ http://bluss.github.io/arrayvec
|
||||
Recent Changes
|
||||
--------------
|
||||
|
||||
- 0.3.8
|
||||
|
||||
- Inline the non-dropping logic to remove one drop flag in the
|
||||
ArrayVec representation.
|
||||
|
||||
- 0.3.7
|
||||
|
||||
- Added method .into_inner()
|
||||
|
||||
+43
-7
@@ -1,7 +1,4 @@
|
||||
extern crate odds;
|
||||
extern crate nodrop;
|
||||
|
||||
use nodrop::NoDrop;
|
||||
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
@@ -17,6 +14,8 @@ use std::borrow::{Borrow, BorrowMut};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::fmt;
|
||||
|
||||
use odds::debug_assert_unreachable;
|
||||
|
||||
mod array;
|
||||
pub use array::Array;
|
||||
pub use odds::IndexRange as RangeArgument;
|
||||
@@ -27,10 +26,17 @@ unsafe fn new_array<A: Array>() -> A {
|
||||
// Note: Returning an uninitialized value here only works
|
||||
// if we can be sure the data is never used. The nullable pointer
|
||||
// inside enum optimization conflicts with this this for example,
|
||||
// so we need to be extra careful. See `Flag` enum.
|
||||
// so we need to be extra careful. See `NoDrop` enum.
|
||||
mem::uninitialized()
|
||||
}
|
||||
|
||||
/// repr(u8) - Make sure the non-nullable pointer optimization does not occur!
|
||||
#[repr(u8)]
|
||||
enum NoDrop<T> {
|
||||
Alive(T),
|
||||
Dropped,
|
||||
}
|
||||
|
||||
/// A vector with a fixed capacity.
|
||||
///
|
||||
/// The **ArrayVec** is a vector backed by a fixed size array. It keeps track of
|
||||
@@ -50,8 +56,13 @@ pub struct ArrayVec<A: Array> {
|
||||
|
||||
impl<A: Array> Drop for ArrayVec<A> {
|
||||
fn drop(&mut self) {
|
||||
// clear all elements, then NoDrop inhibits drop of inner array
|
||||
// clear all elements
|
||||
while let Some(_) = self.pop() { }
|
||||
|
||||
// inhibit drop
|
||||
unsafe {
|
||||
ptr::write(&mut self.xs, NoDrop::Dropped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +84,7 @@ impl<A: Array> ArrayVec<A> {
|
||||
/// ```
|
||||
pub fn new() -> ArrayVec<A> {
|
||||
unsafe {
|
||||
ArrayVec { xs: NoDrop::new(new_array()), len: Index::zero() }
|
||||
ArrayVec { xs: NoDrop::Alive(new_array()), len: Index::zero() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,6 +375,31 @@ impl<A: Array> DerefMut for ArrayVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for NoDrop<T> {
|
||||
type Target = T;
|
||||
|
||||
// Use type invariant, always Alive.
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
match *self {
|
||||
NoDrop::Alive(ref inner) => inner,
|
||||
_ => unsafe { debug_assert_unreachable() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for NoDrop<T> {
|
||||
// Use type invariant, always Alive.
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
match *self {
|
||||
NoDrop::Alive(ref mut inner) => inner,
|
||||
_ => unsafe { debug_assert_unreachable() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Create an **ArrayVec** from an array.
|
||||
///
|
||||
/// ## Examples
|
||||
@@ -376,7 +412,7 @@ impl<A: Array> DerefMut for ArrayVec<A> {
|
||||
/// ```
|
||||
impl<A: Array> From<A> for ArrayVec<A> {
|
||||
fn from(array: A) -> Self {
|
||||
ArrayVec { xs: NoDrop::new(array), len: Index::from(A::capacity()) }
|
||||
ArrayVec { xs: NoDrop::Alive(array), len: Index::from(A::capacity()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -127,15 +127,15 @@ fn test_is_send_sync() {
|
||||
#[test]
|
||||
fn test_compact_size() {
|
||||
// Future rust will kill these drop flags!
|
||||
// 4 elements size + 1 len + 1 enum tag + [1 drop flag] + [1 drop flag nodrop]
|
||||
// 4 elements size + 1 len + 1 enum tag + [1 drop flag]
|
||||
type ByteArray = ArrayVec<[u8; 4]>;
|
||||
println!("{}", mem::size_of::<ByteArray>());
|
||||
assert!(mem::size_of::<ByteArray>() <= 8);
|
||||
assert!(mem::size_of::<ByteArray>() <= 7);
|
||||
|
||||
// 12 element size + 1 len + 1 drop flag + 2 padding + 1 enum tag + 3 padding
|
||||
// 12 element size + 1 enum tag + 3 padding + 1 len + 1 drop flag + 2 padding
|
||||
type QuadArray = ArrayVec<[u32; 3]>;
|
||||
println!("{}", mem::size_of::<QuadArray>());
|
||||
assert!(mem::size_of::<QuadArray>() <= 24);
|
||||
assert!(mem::size_of::<QuadArray>() <= 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user