use {
super::{
DropGuard,
SmallVec,
allocator::{
Allocator,
global::Global
},
iterators::intoiter::IntoIter
},
core::{
iter::TrustedLen,
mem::forget,
ops::Range,
ptr::copy_nonoverlapping,
slice::Iter
}
};
pub trait SpecFromElem<Item> {
unsafe fn spec_from_elem(elem: Item, n: usize) -> Self;
}
impl<Item: Clone, const INLINE: usize> SpecFromElem<Item> for SmallVec<Item, INLINE, Global> {
#[inline]
default unsafe fn spec_from_elem(elem: Item, n: usize) -> Self {
unsafe { SmallVec::from_elem_fallback(elem, n) }
}
}
impl<Item: Copy, const INLINE: usize> SpecFromElem<Item> for SmallVec<Item, INLINE, Global> {
unsafe fn spec_from_elem(elem: Item, 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<Item, I> {
fn spec_extend(&mut self, iter: I);
}
impl<Item, I, const INLINE: usize, Heap: Allocator> SpecExtend<Item, I>
for SmallVec<Item, INLINE, Heap>
where I: Iterator<Item = Item>
{
#[inline]
default fn spec_extend(&mut self, iter: I) {
self.extend_fallback(iter);
}
}
impl<Item, I, const INLINE: usize, Heap: Allocator> SpecExtend<Item, I>
for SmallVec<Item, INLINE, Heap>
where I: TrustedLen<Item = Item>
{
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);
forget(guard);
}
}
}
impl<Item, const INLINE: usize, const M: usize, Heap: Allocator>
SpecExtend<Item, IntoIter<Item, M, Heap>> for SmallVec<Item, INLINE, Heap>
{
fn spec_extend(&mut self, mut iter: IntoIter<Item, M, Heap>) {
let slice = iter.as_ref();
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<'valid, Item: 'valid, const INLINE: usize, I, Heap: Allocator> SpecExtend<&'valid Item, I>
for SmallVec<Item, INLINE, Heap>
where
I: Iterator<Item = &'valid Item>,
Item: Clone
{
#[inline]
default fn spec_extend(&mut self, iterator: I) {
self.spec_extend(iterator.cloned())
}
}
impl<'valid, Item: 'valid, const INLINE: usize, Heap: Allocator>
SpecExtend<&'valid Item, Iter<'valid, Item>> for SmallVec<Item, INLINE, Heap>
where Item: Copy
{
fn spec_extend(&mut self, iter: Iter<'valid, Item>) {
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<Item> {
unsafe fn spec_extend_from_within(&mut self, source: Range<usize>);
}
impl<Item: Clone, const INLINE: usize, Heap: Allocator> SpecExtendFromWithin<Item>
for SmallVec<Item, INLINE, Heap>
{
default unsafe fn spec_extend_from_within(&mut self, source: Range<usize>) {
unsafe {
self.extend_from_within_fallback(source);
}
}
}
impl<Item: Copy, const INLINE: usize, Heap: Allocator> SpecExtendFromWithin<Item>
for SmallVec<Item, INLINE, Heap>
{
unsafe fn spec_extend_from_within(&mut self, source: 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<Item, I> {
fn spec_from_iter(iter: I) -> Self;
}
impl<Item, I, const INLINE: usize> SpecFromIterator<Item, I> for SmallVec<Item, INLINE, Global>
where I: Iterator<Item = Item>
{
#[inline]
default fn spec_from_iter(iter: I) -> Self {
Self::from_iter_fallback(iter)
}
}
impl<Item, I, const INLINE: usize> SpecFromIterator<Item, I> for SmallVec<Item, INLINE, Global>
where I: TrustedLen<Item = Item>
{
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<Item> {
fn spec_clone_from(&mut self, source: &[Item]);
}
impl<Item: Clone, const INLINE: usize, Heap: Allocator> SpecCloneFrom<Item>
for SmallVec<Item, INLINE, Heap>
{
#[inline]
default fn spec_clone_from(&mut self, source: &[Item]) {
self.clone_from_fallback(source);
}
}
impl<Item: Copy, const INLINE: usize, Heap: Allocator> SpecCloneFrom<Item>
for SmallVec<Item, INLINE, Heap>
{
fn spec_clone_from(&mut self, source: &[Item]) {
self.clear();
self.extend(source);
}
}
pub trait SpecFromSlice<Item> {
unsafe fn spec_from(slice: &[Item]) -> Self;
}
impl<Item: Clone, const INLINE: usize> SpecFromSlice<Item> for SmallVec<Item, INLINE, Global> {
default unsafe fn spec_from(slice: &[Item]) -> Self {
unsafe { Self::from_slice_fallback(slice) }
}
}
impl<Item: Copy, const INLINE: usize> SpecFromSlice<Item> for SmallVec<Item, INLINE, Global> {
unsafe fn spec_from(slice: &[Item]) -> 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
}
}