Skip to content

Commit b7f3aa9

Browse files
committed
FIX: Add new_const() for const construction and revert new to old version
The new() function is significantly faster, it optimizes better at the moment/in current rust. For this reason, provide a const fn constructor, but not as the default `new`.
1 parent 198a403 commit b7f3aa9

File tree

4 files changed

+65
-6
lines changed

4 files changed

+65
-6
lines changed

src/array_string.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,27 @@ impl<const CAP: usize> ArrayString<CAP>
5959
/// assert_eq!(&string[..], "foo");
6060
/// assert_eq!(string.capacity(), 16);
6161
/// ```
62-
pub const fn new() -> ArrayString<CAP> {
62+
pub fn new() -> ArrayString<CAP> {
6363
assert_capacity_limit!(CAP);
64+
unsafe {
65+
ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 }
66+
}
67+
}
68+
69+
/// Create a new empty `ArrayString` (const fn).
70+
///
71+
/// Capacity is inferred from the type parameter.
72+
///
73+
/// ```
74+
/// use arrayvec::ArrayString;
75+
///
76+
/// let mut string = ArrayString::<16>::new();
77+
/// string.push_str("foo");
78+
/// assert_eq!(&string[..], "foo");
79+
/// assert_eq!(string.capacity(), 16);
80+
/// ```
81+
pub const fn new_const() -> ArrayString<CAP> {
82+
assert_capacity_limit_const!(CAP);
6483
ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 }
6584
}
6685

src/arrayvec.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,28 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
7777
/// assert_eq!(&array[..], &[1, 2]);
7878
/// assert_eq!(array.capacity(), 16);
7979
/// ```
80-
pub const fn new() -> ArrayVec<T, CAP> {
80+
pub fn new() -> ArrayVec<T, CAP> {
8181
assert_capacity_limit!(CAP);
82+
unsafe {
83+
ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 }
84+
}
85+
}
86+
87+
/// Create a new empty `ArrayVec` (const fn).
88+
///
89+
/// The maximum capacity is given by the generic parameter `CAP`.
90+
///
91+
/// ```
92+
/// use arrayvec::ArrayVec;
93+
///
94+
/// let mut array = ArrayVec::<_, 16>::new();
95+
/// array.push(1);
96+
/// array.push(2);
97+
/// assert_eq!(&array[..], &[1, 2]);
98+
/// assert_eq!(array.capacity(), 16);
99+
/// ```
100+
pub const fn new_const() -> ArrayVec<T, CAP> {
101+
assert_capacity_limit_const!(CAP);
82102
ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 }
83103
}
84104

src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ extern crate core as std;
3131
pub(crate) type LenUint = u32;
3232

3333
macro_rules! assert_capacity_limit {
34+
($cap:expr) => {
35+
if std::mem::size_of::<usize>() > std::mem::size_of::<LenUint>() {
36+
if $cap > LenUint::MAX as usize {
37+
panic!("ArrayVec: largest supported capacity is u32::MAX")
38+
}
39+
}
40+
}
41+
}
42+
43+
macro_rules! assert_capacity_limit_const {
3444
($cap:expr) => {
3545
if std::mem::size_of::<usize>() > std::mem::size_of::<LenUint>() {
3646
if $cap > LenUint::MAX as usize {

tests/tests.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -718,19 +718,29 @@ fn allow_max_capacity_arrayvec_type() {
718718
let _v: ArrayVec<(), {usize::MAX}>;
719719
}
720720

721-
#[should_panic(expected="index out of bounds")]
721+
#[should_panic(expected="largest supported capacity")]
722722
#[test]
723723
fn deny_max_capacity_arrayvec_value() {
724724
if mem::size_of::<usize>() <= mem::size_of::<u32>() {
725-
panic!("This test does not work on this platform. 'index out of bounds'");
725+
panic!("This test does not work on this platform. 'largest supported capacity'");
726726
}
727727
// this type is allowed to be used (but can't be constructed)
728728
let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new();
729729
}
730730

731+
#[should_panic(expected="index out of bounds")]
732+
#[test]
733+
fn deny_max_capacity_arrayvec_value_const() {
734+
if mem::size_of::<usize>() <= mem::size_of::<u32>() {
735+
panic!("This test does not work on this platform. 'index out of bounds'");
736+
}
737+
// this type is allowed to be used (but can't be constructed)
738+
let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new_const();
739+
}
740+
731741
#[test]
732742
fn test_arrayvec_const_constructible() {
733-
const OF_U8: ArrayVec<Vec<u8>, 10> = ArrayVec::new();
743+
const OF_U8: ArrayVec<Vec<u8>, 10> = ArrayVec::new_const();
734744

735745
let mut var = OF_U8;
736746
assert!(var.is_empty());
@@ -742,7 +752,7 @@ fn test_arrayvec_const_constructible() {
742752

743753
#[test]
744754
fn test_arraystring_const_constructible() {
745-
const AS: ArrayString<10> = ArrayString::new();
755+
const AS: ArrayString<10> = ArrayString::new_const();
746756

747757
let mut var = AS;
748758
assert!(var.is_empty());

0 commit comments

Comments
 (0)