mirror of
https://gitee.com/openharmony/third_party_rust_tinyvec
synced 2024-11-23 05:40:15 +00:00
Replace A: Default
bounds by a constructor on Array
(#112)
* Add Array::default function to construct a default array
* Use Array::default instead of Default::default to allow supporting all array sizes
* Missed impl Array for [T; 33] 🍀
* Avoid needing `[T; N]: Default with const-generics
This commit is contained in:
parent
46554393bf
commit
d3c1c6a56d
53
gen-array-impls.sh
Executable file
53
gen-array-impls.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
gen_impl() {
|
||||
local len=$1
|
||||
cat <<-END
|
||||
impl<T: Default> Array for [T; $len] {
|
||||
type Item = T;
|
||||
const CAPACITY: usize = $len;
|
||||
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
&*self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
||||
&mut *self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn default() -> Self {
|
||||
[
|
||||
$(for ((i = 0; i < $len; i += 6))
|
||||
do
|
||||
echo -n ' '
|
||||
for ((j = 0; j < 6 && j + i < $len; j++))
|
||||
do
|
||||
echo -n ' T::default(),'
|
||||
done
|
||||
echo
|
||||
done)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
END
|
||||
}
|
||||
|
||||
cat <<-END
|
||||
// Generated file, to regenerate run
|
||||
// ./gen-array-impls.sh > src/array/generated_impl.rs
|
||||
// from the repo root
|
||||
|
||||
use super::Array;
|
||||
|
||||
$(for ((i = 0; i <= 33; i++)); do gen_impl $i; done)
|
||||
|
||||
$(for ((i = 64; i <= 4096; i *= 2)); do gen_impl $i; done)
|
||||
END
|
||||
|
||||
# vim: noet
|
47
src/array.rs
47
src/array.rs
@ -34,49 +34,14 @@ pub trait Array {
|
||||
/// A correct implementation will return a slice with a length equal to the
|
||||
/// `CAPACITY` value.
|
||||
fn as_slice_mut(&mut self) -> &mut [Self::Item];
|
||||
|
||||
/// Create a default-initialized instance of ourself, similar to the [`Default`] trait, but
|
||||
/// implemented for the same range of sizes as [`Array`].
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly_const_generics")]
|
||||
impl<T: Default, const N: usize> Array for [T; N] {
|
||||
type Item = T;
|
||||
const CAPACITY: usize = N;
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
&*self
|
||||
}
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
||||
&mut *self
|
||||
}
|
||||
}
|
||||
mod const_generic_impl;
|
||||
|
||||
#[cfg(not(feature = "nightly_const_generics"))]
|
||||
macro_rules! impl_array_for_len {
|
||||
($($len:expr),+ $(,)?) => {
|
||||
$(impl<T: Default> Array for [T; $len] {
|
||||
type Item = T;
|
||||
const CAPACITY: usize = $len;
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
&*self
|
||||
}
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
||||
&mut *self
|
||||
}
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nightly_const_generics"))]
|
||||
impl_array_for_len! {
|
||||
0, /* The oft-forgotten 0-length array! */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, /* for luck */
|
||||
64, 128, 256, 512, 1024, 2048, 4096,
|
||||
}
|
||||
mod generated_impl;
|
||||
|
23
src/array/const_generic_impl.rs
Normal file
23
src/array/const_generic_impl.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use super::Array;
|
||||
|
||||
impl<T: Default, const N: usize> Array for [T; N] {
|
||||
type Item = T;
|
||||
const CAPACITY: usize = N;
|
||||
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
&*self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
||||
&mut *self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn default() -> Self {
|
||||
[(); N].map(|_| Default::default())
|
||||
}
|
||||
}
|
2415
src/array/generated_impl.rs
Normal file
2415
src/array/generated_impl.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,9 +15,6 @@ use serde::ser::{Serialize, SerializeSeq, Serializer};
|
||||
/// You specify the backing array type, and optionally give all the elements you
|
||||
/// want to initially place into the array.
|
||||
///
|
||||
/// As an unfortunate restriction, the backing array type must support `Default`
|
||||
/// for it to work with this macro.
|
||||
///
|
||||
/// ```rust
|
||||
/// use tinyvec::*;
|
||||
///
|
||||
@ -64,8 +61,7 @@ macro_rules! array_vec {
|
||||
///
|
||||
/// ## Construction
|
||||
///
|
||||
/// If the backing array supports Default (length 32 or less), then you can use
|
||||
/// the `array_vec!` macro similarly to how you might use the `vec!` macro.
|
||||
/// You can use the `array_vec!` macro similarly to how you might use the `vec!` macro.
|
||||
/// Specify the array type, then optionally give all the initial values you want
|
||||
/// to have.
|
||||
/// ```rust
|
||||
@ -99,12 +95,21 @@ macro_rules! array_vec {
|
||||
/// assert_eq!(more_ints.len(), 2);
|
||||
/// ```
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ArrayVec<A: Array> {
|
||||
len: u16,
|
||||
pub(crate) data: A,
|
||||
}
|
||||
|
||||
impl<A: Array> Default for ArrayVec<A> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
len: 0,
|
||||
data: A::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array> Deref for ArrayVec<A> {
|
||||
type Target = [A::Item];
|
||||
#[inline(always)]
|
||||
@ -160,7 +165,6 @@ where
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Deserialize<'de> for ArrayVec<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
@ -470,10 +474,7 @@ impl<A: Array> ArrayVec<A> {
|
||||
/// Makes a new, empty `ArrayVec`.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn new() -> Self
|
||||
where
|
||||
A: Default,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
@ -733,10 +734,7 @@ impl<A: Array> ArrayVec<A> {
|
||||
/// assert_eq!(&av2[..], [2, 3]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn split_off(&mut self, at: usize) -> Self
|
||||
where
|
||||
Self: Default,
|
||||
{
|
||||
pub fn split_off(&mut self, at: usize) -> Self {
|
||||
// FIXME: should this just use drain into the output?
|
||||
if at > self.len() {
|
||||
panic!(
|
||||
@ -1133,7 +1131,7 @@ impl<A: Array> From<A> for ArrayVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array + Default> FromIterator<A::Item> for ArrayVec<A> {
|
||||
impl<A: Array> FromIterator<A::Item> for ArrayVec<A> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
|
||||
@ -1550,7 +1548,6 @@ struct ArrayVecVisitor<A: Array>(PhantomData<A>);
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Visitor<'de> for ArrayVecVisitor<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
type Value = ArrayVec<A>;
|
||||
|
@ -4,7 +4,7 @@
|
||||
feature = "nightly_slice_partition_dedup",
|
||||
feature(slice_partition_dedup)
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly_const_generics", feature(min_const_generics))]
|
||||
#![cfg_attr(feature = "nightly_const_generics", feature(min_const_generics, array_map))]
|
||||
#![cfg_attr(docs_rs, feature(doc_cfg))]
|
||||
#![warn(clippy::missing_inline_in_public_items)]
|
||||
#![warn(clippy::must_use_candidate)]
|
||||
|
@ -17,9 +17,6 @@ use serde::ser::{Serialize, SerializeSeq, Serializer};
|
||||
/// You specify the backing array type, and optionally give all the elements you
|
||||
/// want to initially place into the array.
|
||||
///
|
||||
/// As an unfortunate restriction, the backing array type must support `Default`
|
||||
/// for it to work with this macro.
|
||||
///
|
||||
/// ```rust
|
||||
/// use tinyvec::*;
|
||||
///
|
||||
@ -98,7 +95,8 @@ pub enum TinyVec<A: Array> {
|
||||
#[allow(missing_docs)]
|
||||
Heap(Vec<A::Item>),
|
||||
}
|
||||
impl<A: Array + Default> Default for TinyVec<A> {
|
||||
|
||||
impl<A: Array> Default for TinyVec<A> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn default() -> Self {
|
||||
@ -164,7 +162,6 @@ where
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
@ -203,10 +200,7 @@ impl<A: Array> TinyVec<A> {
|
||||
/// tv.shrink_to_fit();
|
||||
/// assert!(tv.is_inline());
|
||||
/// ```
|
||||
pub fn shrink_to_fit(&mut self)
|
||||
where
|
||||
A: Default,
|
||||
{
|
||||
pub fn shrink_to_fit(&mut self) {
|
||||
let vec = match self {
|
||||
TinyVec::Inline(_) => return,
|
||||
TinyVec::Heap(h) => h,
|
||||
@ -336,10 +330,7 @@ impl<A: Array> TinyVec<A> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn with_capacity(cap: usize) -> Self
|
||||
where
|
||||
A: Default,
|
||||
{
|
||||
pub fn with_capacity(cap: usize) -> Self {
|
||||
if cap <= A::CAPACITY {
|
||||
TinyVec::Inline(ArrayVec::default())
|
||||
} else {
|
||||
@ -668,10 +659,7 @@ impl<A: Array> TinyVec<A> {
|
||||
/// Makes a new, empty vec.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn new() -> Self
|
||||
where
|
||||
A: Default,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
@ -778,10 +766,7 @@ impl<A: Array> TinyVec<A> {
|
||||
/// assert_eq!(tv2.as_slice(), &[2, 3][..]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn split_off(&mut self, at: usize) -> Self
|
||||
where
|
||||
A: Default,
|
||||
{
|
||||
pub fn split_off(&mut self, at: usize) -> Self {
|
||||
match self {
|
||||
TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)),
|
||||
TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)),
|
||||
@ -1104,7 +1089,7 @@ impl<A: Array> From<A> for TinyVec<A> {
|
||||
impl<T, A> From<&'_ [T]> for TinyVec<A>
|
||||
where
|
||||
T: Clone + Default,
|
||||
A: Array<Item = T> + Default,
|
||||
A: Array<Item = T>,
|
||||
{
|
||||
#[inline]
|
||||
#[must_use]
|
||||
@ -1123,7 +1108,7 @@ where
|
||||
impl<T, A> From<&'_ mut [T]> for TinyVec<A>
|
||||
where
|
||||
T: Clone + Default,
|
||||
A: Array<Item = T> + Default,
|
||||
A: Array<Item = T>,
|
||||
{
|
||||
#[inline]
|
||||
#[must_use]
|
||||
@ -1132,7 +1117,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array + Default> FromIterator<A::Item> for TinyVec<A> {
|
||||
impl<A: Array> FromIterator<A::Item> for TinyVec<A> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
|
||||
@ -1457,7 +1442,6 @@ struct TinyVecVisitor<A: Array>(PhantomData<A>);
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
type Value = TinyVec<A>;
|
||||
|
Loading…
Reference in New Issue
Block a user