FEAT: Use u32 for the length field in arrayvec

Store the length as u32 internally. This is to shrink the size of the
ArrayVec value (when possible, depending on element type).

Inline storage vectors larger than u32::MAX are very unlikely to be
useful - for these cases, prefer using Vec instead.

It's not possible to have the CAP type parameter be of type u32 (missing
features in const evaluation/const generics). We also have to panic at
runtime instead of having a static assertion for capacity, for similar
reasons.
This commit is contained in:
bluss
2021-03-24 18:14:57 +01:00
parent dfd882bbe4
commit 0c90469b61
4 changed files with 64 additions and 22 deletions
+19 -3
View File
@@ -295,17 +295,17 @@ fn test_compact_size() {
// 4 bytes + padding + length
type ByteArray = ArrayVec<u8, 4>;
println!("{}", mem::size_of::<ByteArray>());
assert!(mem::size_of::<ByteArray>() <= 2 * mem::size_of::<usize>());
assert!(mem::size_of::<ByteArray>() <= 2 * mem::size_of::<u32>());
// just length
type EmptyArray = ArrayVec<u8, 0>;
println!("{}", mem::size_of::<EmptyArray>());
assert!(mem::size_of::<EmptyArray>() <= mem::size_of::<usize>());
assert!(mem::size_of::<EmptyArray>() <= mem::size_of::<u32>());
// 3 elements + padding + length
type QuadArray = ArrayVec<u32, 3>;
println!("{}", mem::size_of::<QuadArray>());
assert!(mem::size_of::<QuadArray>() <= 4 * 4 + mem::size_of::<usize>());
assert!(mem::size_of::<QuadArray>() <= 4 * 4 + mem::size_of::<u32>());
}
#[test]
@@ -711,3 +711,19 @@ fn test_try_from_argument() {
let v = ArrayString::<16>::try_from(format_args!("Hello {}", 123)).unwrap();
assert_eq!(&v, "Hello 123");
}
#[test]
fn allow_max_capacity_arrayvec_type() {
// this type is allowed to be used (but can't be constructed)
let _v: ArrayVec<(), {usize::MAX}>;
}
#[should_panic(expected="ArrayVec: largest supported")]
#[test]
fn deny_max_capacity_arrayvec_value() {
if mem::size_of::<usize>() <= mem::size_of::<u32>() {
panic!("This test does not work on this platform. 'ArrayVec: largest supported'");
}
// this type is allowed to be used (but can't be constructed)
let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new();
}