-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add infrastructure to generate
src/arrayvec_copy.rs
It works by replacing a couple of strings in `src/arrayvec.rs` and then applying a small patch. Check that the patch is up-to-date in CI.
- Loading branch information
Showing
3 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env bash | ||
set -o errexit | ||
set -o nounset | ||
set -o pipefail | ||
|
||
sed \ | ||
-e "s/\\<ArrayVec\\>/ArrayVecCopy/g" \ | ||
-e "s/\\<ArrayVecVisitor\\>/ArrayVecCopyVisitor/g" \ | ||
-e "s/impl<\\('a, \\)\\?T:/impl<\\1T: Copy +/g" \ | ||
-e "s/impl<\\('a, \\)\\?T,/impl<\\1T: Copy,/g" \ | ||
-e "s/struct \\([A-Za-z_]*\\)<\\('a, \\)\\?T:/struct \\1<\\2T: Copy +/g" \ | ||
-e "s/struct \\([A-Za-z_]*\\)<\\('a, \\)\\?T,/struct \\1<\\2T: Copy,/g" \ | ||
-e "s/fn \\([A-Za-z_]*\\)<\\('a, \\)\\?T:/fn \\1<\\2T: Copy +/g" \ | ||
-e "s/fn \\([A-Za-z_]*\\)<\\('a, \\)\\?T,/fn \\1<\\2T: Copy,/g" \ | ||
src/arrayvec.rs \ | ||
> src/arrayvec_copy_generated.rs | ||
|
||
trap "rm src/arrayvec_copy_generated.rs" EXIT | ||
|
||
if [ -e src/arrayvec_copy.patch ]; then | ||
if [ -e src/arrayvec_copy.rs ]; then | ||
echo "Both src/arrayvec_copy.patch and src/arrayvec_copy.rs exist." > /dev/stderr | ||
echo "Delete one of them and start again." > /dev/stderr | ||
exit 1 | ||
else | ||
patch -o src/arrayvec_copy.rs src/arrayvec_copy_generated.rs src/arrayvec_copy.patch > /dev/null | ||
fi | ||
else | ||
if [ -e src/arrayvec_copy.rs ]; then | ||
git diff --no-index src/arrayvec_copy_generated.rs src/arrayvec_copy.rs > src/arrayvec_copy.patch | ||
else | ||
echo "Both src/arrayvec_copy.patch and src/arrayvec_copy.rs are missing." > /dev/stderr | ||
echo "One of them is needed to generate the other." > /dev/stderr | ||
exit 1 | ||
fi | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
diff --git a/src/arrayvec_copy_generated.rs b/src/arrayvec_copy.rs | ||
index 2c32eed..ada0728 100644 | ||
--- a/src/arrayvec_copy_generated.rs | ||
+++ b/src/arrayvec_copy.rs | ||
@@ -14,7 +14,6 @@ use std::fmt; | ||
#[cfg(feature="std")] | ||
use std::io; | ||
|
||
-use std::mem::ManuallyDrop; | ||
use std::mem::MaybeUninit; | ||
|
||
#[cfg(feature="serde")] | ||
@@ -25,7 +24,7 @@ use crate::errors::CapacityError; | ||
use crate::arrayvec_impl::ArrayVecImpl; | ||
use crate::utils::MakeMaybeUninit; | ||
|
||
-/// A vector with a fixed capacity. | ||
+/// A vector with a fixed capacity which implements `Copy` and its elemenents are constrained to also be `Copy`. | ||
/// | ||
/// The `ArrayVecCopy` is a vector backed by a fixed size array. It keeps track of | ||
/// the number of initialized elements. The `ArrayVecCopy<T, CAP>` is parameterized | ||
@@ -46,14 +45,6 @@ pub struct ArrayVecCopy<T: Copy, const CAP: usize> { | ||
xs: [MaybeUninit<T>; CAP], | ||
} | ||
|
||
-impl<T: Copy, const CAP: usize> Drop for ArrayVecCopy<T, CAP> { | ||
- fn drop(&mut self) { | ||
- self.clear(); | ||
- | ||
- // MaybeUninit inhibits array's drop | ||
- } | ||
-} | ||
- | ||
macro_rules! panic_oob { | ||
($method_name:expr, $index:expr, $len:expr) => { | ||
panic!(concat!("ArrayVecCopy::", $method_name, ": index {} is out of bounds in vector of length {}"), | ||
@@ -231,8 +222,7 @@ impl<T: Copy, const CAP: usize> ArrayVecCopy<T, CAP> { | ||
ArrayVecImpl::push_unchecked(self, element) | ||
} | ||
|
||
- /// Shortens the vector, keeping the first `len` elements and dropping | ||
- /// the rest. | ||
+ /// Shortens the vector, keeping the first `len` elements. | ||
/// | ||
/// If `len` is greater than the vector’s current length this has no | ||
/// effect. | ||
@@ -499,7 +489,7 @@ impl<T: Copy, const CAP: usize> ArrayVecCopy<T, CAP> { | ||
let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; | ||
|
||
#[inline(always)] | ||
- fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>( | ||
+ fn process_one<T: Copy, F: FnMut(&mut T) -> bool, const CAP: usize, const DELETED: bool>( | ||
f: &mut F, | ||
g: &mut BackshiftOnDrop<'_, T, CAP> | ||
) -> bool { | ||
@@ -507,7 +497,6 @@ impl<T: Copy, const CAP: usize> ArrayVecCopy<T, CAP> { | ||
if !f(unsafe { &mut *cur }) { | ||
g.processed_len += 1; | ||
g.deleted_cnt += 1; | ||
- unsafe { ptr::drop_in_place(cur) }; | ||
return false; | ||
} | ||
if DELETED { | ||
@@ -522,20 +511,20 @@ impl<T: Copy, const CAP: usize> ArrayVecCopy<T, CAP> { | ||
|
||
// Stage 1: Nothing was deleted. | ||
while g.processed_len != original_len { | ||
- if !process_one::<F, T, CAP, false>(&mut f, &mut g) { | ||
+ if !process_one::<T, F, CAP, false>(&mut f, &mut g) { | ||
break; | ||
} | ||
} | ||
|
||
// Stage 2: Some elements were deleted. | ||
while g.processed_len != original_len { | ||
- process_one::<F, T, CAP, true>(&mut f, &mut g); | ||
+ process_one::<T, F, CAP, true>(&mut f, &mut g); | ||
} | ||
|
||
drop(g); | ||
} | ||
|
||
- /// Set the vector’s length without dropping or moving out elements | ||
+ /// Set the vector’s length without moving out elements | ||
/// | ||
/// This method is `unsafe` because it changes the notion of the | ||
/// number of “valid” elements in the vector. Use with care. | ||
@@ -668,8 +657,7 @@ impl<T: Copy, const CAP: usize> ArrayVecCopy<T, CAP> { | ||
/// This operation is safe if and only if length equals capacity. | ||
pub unsafe fn into_inner_unchecked(self) -> [T; CAP] { | ||
debug_assert_eq!(self.len(), self.capacity()); | ||
- let self_ = ManuallyDrop::new(self); | ||
- let array = ptr::read(self_.as_ptr() as *const [T; CAP]); | ||
+ let array = ptr::read(self.as_ptr() as *const [T; CAP]); | ||
array | ||
} | ||
|
||
@@ -755,10 +743,9 @@ impl<T: Copy, const CAP: usize> DerefMut for ArrayVecCopy<T, CAP> { | ||
impl<T: Copy, const CAP: usize> From<[T; CAP]> for ArrayVecCopy<T, CAP> { | ||
#[track_caller] | ||
fn from(array: [T; CAP]) -> Self { | ||
- let array = ManuallyDrop::new(array); | ||
let mut vec = <ArrayVecCopy<T, CAP>>::new(); | ||
unsafe { | ||
- (&*array as *const [T; CAP] as *const [MaybeUninit<T>; CAP]) | ||
+ (&array as *const [T; CAP] as *const [MaybeUninit<T>; CAP]) | ||
.copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<T>; CAP], 1); | ||
vec.set_len(CAP); | ||
} | ||
@@ -929,21 +916,6 @@ impl<T: Copy, const CAP: usize> DoubleEndedIterator for IntoIter<T, CAP> { | ||
|
||
impl<T: Copy, const CAP: usize> ExactSizeIterator for IntoIter<T, CAP> { } | ||
|
||
-impl<T: Copy, const CAP: usize> Drop for IntoIter<T, CAP> { | ||
- fn drop(&mut self) { | ||
- // panic safety: Set length to 0 before dropping elements. | ||
- let index = self.index; | ||
- let len = self.v.len(); | ||
- unsafe { | ||
- self.v.set_len(0); | ||
- let elements = slice::from_raw_parts_mut( | ||
- self.v.get_unchecked_ptr(index), | ||
- len - index); | ||
- ptr::drop_in_place(elements); | ||
- } | ||
- } | ||
-} | ||
- | ||
impl<T: Copy, const CAP: usize> Clone for IntoIter<T, CAP> | ||
where T: Clone, | ||
{ | ||
@@ -1029,7 +1001,7 @@ impl<'a, T: Copy + 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { | ||
} | ||
} | ||
|
||
-struct ScopeExitGuard<T: Copy, Data, F> | ||
+struct ScopeExitGuard<T, Data, F> | ||
where F: FnMut(&Data, &mut T) | ||
{ | ||
value: T, | ||
@@ -1037,7 +1009,7 @@ struct ScopeExitGuard<T: Copy, Data, F> | ||
f: F, | ||
} | ||
|
||
-impl<T: Copy, Data, F> Drop for ScopeExitGuard<T, Data, F> | ||
+impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F> | ||
where F: FnMut(&Data, &mut T) | ||
{ | ||
fn drop(&mut self) { |