Allow inferring array type for macro constructors

This commit is contained in:
Wim Looman
2020-01-27 14:38:26 +01:00
parent 6bced3d4e4
commit ac8dfa5cef
2 changed files with 41 additions and 8 deletions
+11 -1
View File
@@ -11,9 +11,13 @@ use super::*;
/// ```rust
/// use tinyvec::*;
///
/// // The backing array type can be specified in the macro call
/// let empty_av = array_vec!([u8; 16]);
///
/// let some_ints = array_vec!([i32; 4], 1, 2, 3);
///
/// // Or left to inference
/// let empty_av: ArrayVec<[u8; 10]> = array_vec!();
/// let some_ints: ArrayVec<[u8; 10]> = array_vec!(5, 6, 7, 8);
/// ```
#[macro_export]
macro_rules! array_vec {
@@ -30,6 +34,12 @@ macro_rules! array_vec {
av
}
};
() => {
array_vec!(_)
};
($($elem:expr),*) => {
array_vec!(_, $($elem),*)
};
}
/// An array-backed, vector-like data structure.
+30 -7
View File
@@ -15,11 +15,15 @@ use alloc::vec::Vec;
/// ```rust
/// use tinyvec::*;
///
/// // The backing array type can be specified in the macro call
/// let empty_tv = tiny_vec!([u8; 16]);
///
/// let some_ints = tiny_vec!([i32; 4], 1, 2, 3);
///
/// let many_ints = tiny_vec!([i32; 4], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
///
/// // Or left to inference
/// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!();
/// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3);
/// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
/// ```
#[macro_export]
macro_rules! tiny_vec {
@@ -42,14 +46,19 @@ macro_rules! tiny_vec {
const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
// If we have more `$elem` than the `CAPACITY` we will simply go directly
// to constructing on the heap.
let av: $crate::TinyVec<$array_type> = if INVOKED_ELEM_COUNT <= <$array_type as $crate::Array>::CAPACITY {
$crate::TinyVec::<$array_type>::Inline($crate::array_vec!($array_type, $($elem),*))
} else {
$crate::TinyVec::<$array_type>::Heap($crate::alloc::vec!($($elem),*))
};
let av: $crate::TinyVec<$array_type> = $crate::TinyVec::from_either_with_capacity(
INVOKED_ELEM_COUNT,
#[inline(always)] || $crate::array_vec!($array_type, $($elem),*),
#[inline(always)] || vec!($($elem),*));
av
}
};
() => {
tiny_vec!(_)
};
($($elem:expr),*) => {
tiny_vec!(_, $($elem),*)
};
}
/// A vector that starts inline, but can automatically move to the heap.
@@ -333,6 +342,20 @@ impl<A: Array> TinyVec<A> {
}
}
#[inline(always)]
#[doc(hidden)] // Internal implementation details of `tiny_vec!`
pub fn from_either_with_capacity(
cap: usize,
make_array: impl FnOnce() -> ArrayVec<A>,
make_vec: impl FnOnce() -> Vec<A::Item>,
) -> Self {
if cap <= A::CAPACITY {
TinyVec::Inline(make_array())
} else {
TinyVec::Heap(make_vec())
}
}
/// Inserts an item at the position given, moving all following elements +1
/// index.
///