diff --git a/CHANGELOG.md b/CHANGELOG.md
index 470ebb3..80e2720 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 0.14.0
+### Removed
+- Helpers `any_value::move_out`, `any_value::move_out_w_size` removed as redundant.
+
## 0.13.0
### Added
- `AnyVec` now can work with `AnyValueSizeless`.
diff --git a/src/any_value/mod.rs b/src/any_value/mod.rs
index 2ea9a3f..243f6d5 100644
--- a/src/any_value/mod.rs
+++ b/src/any_value/mod.rs
@@ -26,7 +26,7 @@ mod lazy_clone;
pub use lazy_clone::LazyClone;
pub use wrapper::AnyValueWrapper;
-pub use raw::{AnyValueRaw, AnyValueTypelessRaw, AnyValueSizelessRaw};
+pub use raw::{AnyValueRaw, AnyValueSizelessRaw, AnyValueTypelessRaw};
use std::any::TypeId;
use std::{mem, ptr};
@@ -80,48 +80,19 @@ pub trait AnyValueSizeless {
///
/// # Safety
///
- /// `bytes_size` must be correct object size.
- /// `out` must have at least `bytes_size` bytes.
- /// `KnownType` must be correct object type or [Unknown].
- ///
- /// # Helpers
- ///
- /// Due to Rust limitations in generic department, you may found
- /// useful helpers [move_out] and [move_out_w_size].
+ /// - `bytes_size` must be correct object size.
+ /// - `out` must not overlap with `self`.
+ /// - `out` must have at least `bytes_size` bytes.
+ /// - `KnownType` must be correct object type or [Unknown].
#[inline]
unsafe fn move_into(self, out: *mut u8, bytes_size: usize)
where Self: Sized
{
- copy_bytes::(self.as_bytes_ptr(), out, bytes_size);
+ crate::copy_nonoverlapping_value::(self.as_bytes_ptr(), out, bytes_size);
mem::forget(self);
}
}
-/// Wrapper for AnyValueTypeless around [move_into].
-///
-/// You may need this because of Rust's generics limitations.
-///
-/// [move_into]: AnyValueSizeless::move_into
-#[inline]
-pub unsafe fn move_out(this: T, out: *mut u8) {
- let size = this.size();
- this.move_into::(out, size);
-}
-
-/// Wrapper for AnyValueSizeless around [move_into].
-///
-/// You may need this because of Rust's generics limitations.
-///
-/// N.B. For moving out values of [Unknown] type, of the same size, in tight loops -
-/// this may perform faster then [move_out], since compiler will be
-/// able to optimize better, knowing that all values have the same size.
-///
-/// [move_into]: AnyValueSizeless::move_into
-#[inline]
-pub unsafe fn move_out_w_size(this: T, out: *mut u8, bytes_size: usize) {
- this.move_into::(out, bytes_size);
-}
-
/// [AnyValue] that doesn't know it's type, but know it's size.
pub trait AnyValueTypeless: AnyValueSizeless {
/// Aligned.
@@ -164,26 +135,6 @@ pub trait AnyValue: AnyValueTypeless {
}
}
-/// Helper function, which utilize type knowledge.
-#[inline(always)]
-pub(crate) unsafe fn copy_bytes(
- input: *const u8, out: *mut u8, bytes_size: usize
-) {
- if !Unknown::is::() {
- ptr::copy_nonoverlapping(
- input as *const KnownType,
- out as *mut KnownType,
- 1
- );
- } else {
- ptr::copy_nonoverlapping(
- input,
- out,
- bytes_size
- );
- }
-}
-
/// Mutable [AnyValueSizeless].
pub trait AnyValueSizelessMut: AnyValueSizeless {
// Rust MIRI requires mut pointer to actually come from mut self.
diff --git a/src/element.rs b/src/element.rs
index 4e07f84..ba8f876 100644
--- a/src/element.rs
+++ b/src/element.rs
@@ -21,7 +21,8 @@ use crate::traits::{Cloneable, None, Trait};
/// # Consuming
///
/// Whenever you have `ElementPointer` as a value (from destructive [`AnyVec`] operations),
-/// you can safely take pointed value, with [`AnyValue::downcast`] or [`any_value::move_out`].
+/// you can safely take pointed value with [`AnyValue::downcast`], or unsafely
+/// take its content with [`AnyValue::move_into`].
/// Otherwise, it will be destructed with destruction of [`Element`].
///
/// # Notes
diff --git a/src/lib.rs b/src/lib.rs
index 04f95fe..6f19169 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -144,9 +144,9 @@ mod any_vec_typed;
mod iter;
use std::any::TypeId;
-pub use crate::any_vec::{AnyVec, AnyVecMut, AnyVecRef, SatisfyTraits, traits, RawParts};
+pub use crate::any_vec::{AnyVec, AnyVecMut, AnyVecRef, RawParts, SatisfyTraits, traits};
pub use any_vec_typed::AnyVecTyped;
-pub use iter::{ElementIterator, Iter, IterRef, IterMut};
+pub use iter::{ElementIterator, Iter, IterMut, IterRef};
pub mod mem;
pub mod any_value;
@@ -155,11 +155,13 @@ pub mod element;
use std::ptr;
use std::ops::{Bound, Range, RangeBounds};
+use crate::any_value::Unknown;
-// TODO: remove
-// This is faster then ptr::copy,
-// when count is runtime value, and count is small.
-#[inline]
+/// This is faster then ptr::copy,
+/// when count is runtime value, and count is small.
+///
+/// Last time benchmarked on nightly 1.80
+#[inline(always)]
unsafe fn copy_bytes(src: *const u8, dst: *mut u8, count: usize){
// MIRI hack
if cfg!(miri)
@@ -174,6 +176,26 @@ unsafe fn copy_bytes(src: *const u8, dst: *mut u8, count: usize){
}
}
+/// One element copy_nonoverlapping, that utilize type knowledge.
+#[inline(always)]
+pub(crate) unsafe fn copy_nonoverlapping_value(
+ input: *const u8, out: *mut u8, value_size: usize
+) {
+ if !Unknown::is::() {
+ ptr::copy_nonoverlapping(
+ input as *const KnownType,
+ out as *mut KnownType,
+ 1
+ );
+ } else {
+ ptr::copy_nonoverlapping(
+ input,
+ out,
+ value_size
+ );
+ }
+}
+
#[inline]
fn into_range(
len: usize,
@@ -197,4 +219,4 @@ fn into_range(
#[inline]
fn assert_types_equal(t1: TypeId, t2: TypeId){
assert_eq!(t1, t2, "Type mismatch!");
-}
+}
\ No newline at end of file
diff --git a/src/ops/remove.rs b/src/ops/remove.rs
index b7e4361..e7210ec 100644
--- a/src/ops/remove.rs
+++ b/src/ops/remove.rs
@@ -45,12 +45,12 @@ impl<'a, AnyVecPtr: IAnyVecRawPtr> Operation for Remove<'a, AnyVecPtr>{
if !Unknown::is::() {
let dst = self.bytes() as *mut AnyVecPtr::Element;
let src = dst.add(1);
- ptr::copy(src, dst,self.last_index - self.index);
+ ptr::copy(src, dst, self.last_index - self.index);
} else {
let size = self.any_vec_ptr.any_vec_raw().element_layout().size();
let dst = self.bytes() as *mut u8;
let src = dst.add(size);
- crate::copy_bytes(src, dst,size * (self.last_index - self.index));
+ crate::copy_bytes(src, dst, size * (self.last_index - self.index));
}
// 3. shrink len `self.any_vec.len -= 1`
diff --git a/src/ops/splice.rs b/src/ops/splice.rs
index dfc9789..75e925b 100644
--- a/src/ops/splice.rs
+++ b/src/ops/splice.rs
@@ -1,6 +1,6 @@
use crate::any_vec_ptr::IAnyVecRawPtr;
use crate::{any_vec_ptr, assert_types_equal, Iter};
-use crate::any_value::{AnyValue, move_out_w_size};
+use crate::any_value::{AnyValue, AnyValueSizeless};
use crate::ops::iter::Iterable;
pub struct Splice<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator>
@@ -105,7 +105,9 @@ where
let mut ptr = element_mut_ptr_at(any_vec_ptr, self.start);
while let Some(replace_element) = self.replace_with.next() {
assert_types_equal(type_id, replace_element.value_typeid());
- move_out_w_size(replace_element, ptr, element_size);
+ replace_element.move_into::<
+ ::Type
+ >(ptr, element_size);
ptr = ptr.add(element_size);
}
}
diff --git a/src/ops/swap_remove.rs b/src/ops/swap_remove.rs
index 789bdb6..07b240e 100644
--- a/src/ops/swap_remove.rs
+++ b/src/ops/swap_remove.rs
@@ -1,5 +1,5 @@
use std::marker::PhantomData;
-use crate::any_value::copy_bytes;
+use crate::copy_nonoverlapping_value;
use crate::any_vec_ptr::IAnyVecRawPtr;
use crate::any_vec_ptr::utils::{element_mut_ptr_at, element_ptr_at};
use crate::any_vec_raw::AnyVecRaw;
@@ -47,7 +47,7 @@ impl<'a, AnyVecPtr: IAnyVecRawPtr> Operation for SwapRemove<'a, AnyVecPtr>{
let any_vec_raw = self.any_vec_ptr.any_vec_raw_mut();
if self.element as *const u8 != last_element {
- copy_bytes::(
+ copy_nonoverlapping_value::(
last_element,
self.element,
any_vec_raw.element_layout().size()
diff --git a/src/ops/temp.rs b/src/ops/temp.rs
index 28144b6..a54794e 100644
--- a/src/ops/temp.rs
+++ b/src/ops/temp.rs
@@ -1,9 +1,9 @@
use std::any::TypeId;
use std::{mem, ptr};
-use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, Unknown, AnyValueSizeless, copy_bytes, AnyValueSizelessMut};
+use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueSizeless, AnyValueSizelessMut, AnyValueTypeless, AnyValueTypelessMut, Unknown};
use crate::any_vec_raw::AnyVecRaw;
use crate::any_vec_ptr::{IAnyVecPtr, IAnyVecRawPtr};
-use crate::AnyVec;
+use crate::{AnyVec, copy_nonoverlapping_value};
use crate::traits::Cloneable;
pub trait Operation {
@@ -58,7 +58,7 @@ impl AnyValueSizeless for TempValue {
#[inline]
unsafe fn move_into(mut self, out: *mut u8, bytes_size: usize) {
- copy_bytes::(self.as_bytes_ptr(), out, bytes_size);
+ copy_nonoverlapping_value::(self.as_bytes_ptr(), out, bytes_size);
self.op.consume();
mem::forget(self);
}