diff --git a/.travis.yml b/.travis.yml index 42816fe..efec9f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,9 @@ matrix: - rust: nightly env: - FEATURES='array-sizes-33-128 array-sizes-129-255' + - rust: nightly + env: + - FEATURES='unstable-const-fn' - name: "miri" script: sh ci/miri.sh branches: diff --git a/Cargo.toml b/Cargo.toml index 66267cd..684d610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ harness = false [features] default = ["std"] std = [] +unstable-const-fn = [] array-sizes-33-128 = [] array-sizes-129-255 = [] diff --git a/src/array.rs b/src/array.rs index 96a8bfd..2de5e77 100644 --- a/src/array.rs +++ b/src/array.rs @@ -34,11 +34,13 @@ pub unsafe trait Array { } pub trait Index : PartialEq + Copy { + const ZERO: Self; fn to_usize(self) -> usize; fn from(_: usize) -> Self; } impl Index for () { + const ZERO: Self = (); #[inline(always)] fn to_usize(self) -> usize { 0 } #[inline(always)] @@ -46,6 +48,7 @@ impl Index for () { } impl Index for bool { + const ZERO: Self = false; #[inline(always)] fn to_usize(self) -> usize { self as usize } #[inline(always)] @@ -53,6 +56,7 @@ impl Index for bool { } impl Index for u8 { + const ZERO: Self = 0; #[inline(always)] fn to_usize(self) -> usize { self as usize } #[inline(always)] @@ -60,6 +64,7 @@ impl Index for u8 { } impl Index for u16 { + const ZERO: Self = 0; #[inline(always)] fn to_usize(self) -> usize { self as usize } #[inline(always)] @@ -67,6 +72,7 @@ impl Index for u16 { } impl Index for u32 { + const ZERO: Self = 0; #[inline(always)] fn to_usize(self) -> usize { self as usize } #[inline(always)] @@ -74,6 +80,7 @@ impl Index for u32 { } impl Index for usize { + const ZERO: Self = 0; #[inline(always)] fn to_usize(self) -> usize { self } #[inline(always)] diff --git a/src/array_string.rs b/src/array_string.rs index 46f4675..7239288 100644 --- a/src/array_string.rs +++ b/src/array_string.rs @@ -58,11 +58,22 @@ impl ArrayString /// assert_eq!(&string[..], "foo"); /// assert_eq!(string.capacity(), 16); /// ``` + #[cfg(not(feature="unstable-const-fn"))] pub fn new() -> ArrayString { unsafe { ArrayString { xs: MaybeUninitCopy::uninitialized(), - len: Index::from(0), + len: Index::ZERO, + } + } + } + + #[cfg(feature="unstable-const-fn")] + pub const fn new() -> ArrayString { + unsafe { + ArrayString { + xs: MaybeUninitCopy::uninitialized(), + len: Index::ZERO, } } } diff --git a/src/lib.rs b/src/lib.rs index 0268334..6267712 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,12 +14,19 @@ //! - Optional //! - Enable more array sizes (see [Array] for more information) //! +//! - `unstable-const-fn` +//! - Optional +//! - Makes [`ArrayVec::new`] and [`ArrayString::new`] `const fn`s, +//! using the nightly `const_fn` feature. +//! - Unstable and requires nightly. +//! //! ## Rust Version //! //! This version of arrayvec requires Rust 1.36 or later. //! #![doc(html_root_url="https://docs.rs/arrayvec/0.4/")] #![cfg_attr(not(feature="std"), no_std)] +#![cfg_attr(feature="unstable-const-fn", feature(const_fn))] #[cfg(feature="serde")] extern crate serde; @@ -106,9 +113,17 @@ impl ArrayVec { /// assert_eq!(&array[..], &[1, 2]); /// assert_eq!(array.capacity(), 16); /// ``` + #[cfg(not(feature="unstable-const-fn"))] pub fn new() -> ArrayVec { unsafe { - ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::from(0) } + ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::ZERO } + } + } + + #[cfg(feature="unstable-const-fn")] + pub const fn new() -> ArrayVec { + unsafe { + ArrayVec { xs: MaybeUninit::uninitialized(), len: Index::ZERO } } } diff --git a/src/maybe_uninit.rs b/src/maybe_uninit.rs index fc69a3f..e009abf 100644 --- a/src/maybe_uninit.rs +++ b/src/maybe_uninit.rs @@ -16,7 +16,7 @@ impl Clone for MaybeUninit impl MaybeUninit { /// Create a new MaybeUninit with uninitialized interior - pub unsafe fn uninitialized() -> Self { + pub const unsafe fn uninitialized() -> Self { MaybeUninit { inner: StdMaybeUninit::uninit() } }