use {
crate::{
Allocator,
DropGuard,
IntoIter,
SmallVec
},
core::ptr::copy_nonoverlapping
};
pub trait SpecFromElem<T> {
unsafe fn spec_from_elem(elem: T, n: usize) -> Self;
}
impl<T: Clone, const N: usize> SpecFromElem<T> for SmallVec<T, N> {
#[inline]
default unsafe fn spec_from_elem(elem: T, n: usize) -> Self {
unsafe { SmallVec::from_elem_fallback(elem, n) }
}
}
impl<T: Copy, const N: usize> SpecFromElem<T> for SmallVec<T, N> {
unsafe fn spec_from_elem(elem: T, n: usize) -> Self {
let mut result = Self::new();
if n > 0 {
let ptr = result.raw.as_mut_ptr_inline();
unsafe {
for i in 0..n {
ptr.add(i).write(elem);
}
}
}
unsafe {
result.set_len(n);
}
result
}
}
pub trait SpecExtend<T, I> {
fn spec_extend(&mut self, iter: I);
}
impl<T, I, const N: usize, A: Allocator> SpecExtend<T, I> for SmallVec<T, N, A>
where I: Iterator<Item = T>
{
#[inline]
default fn spec_extend(&mut self, iter: I) {
self.extend_fallback(iter);
}
}
impl<T, I, const N: usize, A: Allocator> SpecExtend<T, I> for SmallVec<T, N, A>
where I: core::iter::TrustedLen<Item = T>
{
fn spec_extend(&mut self, iter: I) {
let (_, Some(additional)) = iter.size_hint() else {
panic!("capacity overflow")
};
self.reserve(additional);
unsafe {
let length = self.len();
let ptr = self.as_mut_ptr().add(length);
let mut guard = DropGuard {
ptr,
length: 0
};
for x in iter {
ptr.add(guard.length).write(x);
guard.length += 1;
}
self.set_len(length + guard.length);
core::mem::forget(guard);
}
}
}
impl<T, const N: usize, const M: usize, A: Allocator> SpecExtend<T, IntoIter<T, M, A>>
for SmallVec<T, N, A>
{
fn spec_extend(&mut self, mut iter: IntoIter<T, M, A>) {
let slice = iter.as_slice();
let length = slice.len();
let old_len = self.len();
self.reserve(length);
unsafe {
let destination = self.as_mut_ptr().add(old_len);
let source = slice.as_ptr();
copy_nonoverlapping(source, destination, length);
}
unsafe {
self.set_len(old_len + length);
}
iter.mark_consumed();
}
}
impl<'a, T: 'a, const N: usize, I, A: Allocator> SpecExtend<&'a T, I> for SmallVec<T, N, A>
where
I: Iterator<Item = &'a T>,
T: Clone
{
#[inline]
default fn spec_extend(&mut self, iterator: I) {
self.spec_extend(iterator.cloned())
}
}
impl<'a, T: 'a, const N: usize, A: Allocator> SpecExtend<&'a T, core::slice::Iter<'a, T>>
for SmallVec<T, N, A>
where T: Copy
{
fn spec_extend(&mut self, iter: core::slice::Iter<'a, T>) {
let slice = iter.as_slice();
let length = slice.len();
let old_len = self.len();
self.reserve(length);
unsafe {
let destination = self.as_mut_ptr().add(old_len);
let source = slice.as_ptr();
copy_nonoverlapping(source, destination, length);
}
unsafe {
self.set_len(old_len + length);
}
}
}
pub trait SpecExtendFromWithin<T> {
unsafe fn spec_extend_from_within(&mut self, source: core::ops::Range<usize>);
}
impl<T: Clone, const N: usize, A: Allocator> SpecExtendFromWithin<T> for SmallVec<T, N, A> {
default unsafe fn spec_extend_from_within(&mut self, source: core::ops::Range<usize>) {
unsafe {
self.extend_from_within_fallback(source);
}
}
}
impl<T: Copy, const N: usize, A: Allocator> SpecExtendFromWithin<T> for SmallVec<T, N, A> {
unsafe fn spec_extend_from_within(&mut self, source: core::ops::Range<usize>) {
let old_len = self.len();
let start = source.start;
let length = source.len();
unsafe {
let ptr = self.as_mut_ptr();
let destination = ptr.add(old_len);
let source = ptr.add(start);
copy_nonoverlapping(source, destination, length);
}
unsafe {
self.set_len(old_len + length);
}
}
}
pub trait SpecFromIterator<T, I> {
fn spec_from_iter(iter: I) -> Self;
}
impl<T, I, const N: usize> SpecFromIterator<T, I> for SmallVec<T, N>
where I: Iterator<Item = T>
{
#[inline]
default fn spec_from_iter(iter: I) -> Self {
Self::from_iter_fallback(iter)
}
}
impl<T, I, const N: usize> SpecFromIterator<T, I> for SmallVec<T, N>
where I: core::iter::TrustedLen<Item = T>
{
fn spec_from_iter(iter: I) -> Self {
let mut v = match iter.size_hint() {
(_, Some(upper)) => SmallVec::with_capacity(upper),
_ => panic!("capacity overflow")
};
v.spec_extend(iter);
v
}
}
pub trait SpecCloneFrom<T> {
fn spec_clone_from(&mut self, source: &[T]);
}
impl<T: Clone, const N: usize, A: Allocator> SpecCloneFrom<T> for SmallVec<T, N, A> {
#[inline]
default fn spec_clone_from(&mut self, source: &[T]) {
self.clone_from_fallback(source);
}
}
impl<T: Copy, const N: usize, A: Allocator> SpecCloneFrom<T> for SmallVec<T, N, A> {
fn spec_clone_from(&mut self, source: &[T]) {
self.clear();
self.extend_from_slice(source);
}
}
pub trait SpecFromSlice<T> {
unsafe fn spec_from(slice: &[T]) -> Self;
}
impl<T: Clone, const N: usize> SpecFromSlice<T> for SmallVec<T, N> {
default unsafe fn spec_from(slice: &[T]) -> Self {
unsafe { Self::from_slice_fallback(slice) }
}
}
impl<T: Copy, const N: usize> SpecFromSlice<T> for SmallVec<T, N> {
unsafe fn spec_from(slice: &[T]) -> Self {
let mut v = Self::new();
let source = slice.as_ptr();
let length = slice.len();
let destination = v.as_mut_ptr();
unsafe {
copy_nonoverlapping(source, destination, length);
}
unsafe {
v.set_len(length);
}
v
}
}