use std::num::NonZeroUsize;
use smallvec::*;
use crate::non_empty_slice::*;
#[macro_export]
macro_rules! ne_smallvec {
($($item: expr),+ $(,)?) => {
unsafe { $crate::NonEmptySmallVec::from_buf_unchecked([$($item),+]) }
};
($item: expr; $amount: expr) => {
$crate::NonEmptySmallVec::from_elem($item, $amount)
};
() => {
compile_error!("Cannot make an empty NonEmptySmallVec");
}
}
#[repr(transparent)]
pub struct NonEmptySmallVec<A: Array>(pub(crate) SmallVec<A>);
impl<A: Array> NonEmptySmallVec<A> {
#[inline]
pub fn new(item: A::Item) -> NonEmptySmallVec<A> {
NonEmptySmallVec(smallvec![item])
}
#[inline]
pub fn with_capacity(item: A::Item, capacity: usize) -> NonEmptySmallVec<A> {
let mut vec = SmallVec::with_capacity(capacity);
vec.push(item);
NonEmptySmallVec(vec)
}
#[inline]
pub fn try_from_smallvec(smallvec: SmallVec<A>) -> Result<NonEmptySmallVec<A>, SmallVec<A>> {
if smallvec.is_empty() { Err(smallvec) }
else { Ok(NonEmptySmallVec(smallvec)) }
}
#[inline]
pub fn try_from_smallvec_ref_mut(smallvec: &mut SmallVec<A>) -> Option<NonEmptySmallVec<A>> {
if smallvec.is_empty() { None }
else {
let mut non_empty_vec = NonEmptySmallVec(SmallVec::new());
std::mem::swap(smallvec, &mut non_empty_vec.0);
Some(non_empty_vec)
}
}
#[inline]
pub unsafe fn from_smallvec_unchecked(smallvec: SmallVec<A>) -> NonEmptySmallVec<A> {
NonEmptySmallVec(smallvec)
}
#[inline]
pub unsafe fn from_buf_unchecked(buf: A) -> NonEmptySmallVec<A> {
NonEmptySmallVec(SmallVec::from_buf(buf))
}
#[inline]
pub fn get_smallvec(&self) -> &SmallVec<A> {
&self.0
}
#[inline]
pub fn into_smallvec(self) -> SmallVec<A> {
self.0
}
#[inline]
pub fn into_vec(self) -> Vec<A::Item> {
self.0.into_vec()
}
#[inline]
pub fn into_boxed_slice(self) -> Box<[A::Item]> {
self.0.into_boxed_slice()
}
#[inline]
pub fn into_inner(self) -> Result<A, smallvec::SmallVec<A>> {
self.0.into_inner()
}
#[inline]
pub fn capacity(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.0.capacity()) }
}
#[inline]
pub fn spilled(&self) -> bool {
self.0.spilled()
}
#[inline]
pub unsafe fn set_len(&mut self, new_len: NonZeroUsize) {
self.0.set_len(new_len.get())
}
#[inline]
pub fn drain<R: std::ops::RangeBounds<usize>>(&mut self, range: R) -> Option<smallvec::Drain<'_, A>> {
if range.contains(&0) && range.contains(&(self.len().get() - 1)) {
None
} else {
Some(self.0.drain(range))
}
}
#[inline]
pub unsafe fn drain_unchecked<R: std::ops::RangeBounds<usize>>(&mut self, range: R) -> smallvec::Drain<'_, A> {
self.0.drain(range)
}
#[inline]
pub fn push(&mut self, item: A::Item) {
self.0.push(item)
}
#[inline]
pub fn insert(&mut self, index: usize, element: A::Item) {
self.0.insert(index, element)
}
#[inline]
pub fn insert_many<I: IntoIterator<Item = A::Item>>(&mut self, index: usize, iterable: I) {
self.0.insert_many(index, iterable)
}
#[inline]
pub fn pop(&mut self) -> Option<A::Item> {
if self.has_just_1_element() {
None
} else {
self.0.pop()
}
}
#[inline]
pub fn append_smallvec(&mut self, other: &mut SmallVec<A>) {
self.0.append(other)
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional)
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
self.0.try_reserve(additional)
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional)
}
#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
self.0.try_reserve_exact(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
#[inline]
pub fn truncate(&mut self, len: NonZeroUsize) {
self.0.truncate(len.get())
}
#[inline]
pub fn as_slice(&self) -> &NonEmptySlice<A::Item> {
self
}
#[inline]
pub fn as_slice_mut(&mut self) -> &mut NonEmptySlice<A::Item> {
self
}
#[inline]
pub fn swap_remove(&mut self, index: NonZeroUsize) -> A::Item {
self.0.swap_remove(index.get())
}
#[inline]
pub fn try_swap_remove(&mut self, index: usize) -> Option<A::Item> {
if self.has_just_1_element() {
None
} else {
Some(self.0.swap_remove(index))
}
}
#[inline]
pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> A::Item {
self.0.swap_remove(index)
}
#[inline]
pub fn try_remove(&mut self, index: usize) -> Option<A::Item> {
if self.has_just_1_element(){
None
} else {
Some(self.0.remove(index))
}
}
#[inline]
pub unsafe fn remove_unchecked(&mut self, index: usize) -> A::Item {
self.0.remove(index)
}
#[inline]
pub fn dedup_by_key<F, K>(&mut self, key: F) where F: FnMut(&mut A::Item) -> K, K: PartialEq {
self.0.dedup_by_key(key)
}
#[inline]
pub fn dedup_by<F>(&mut self, same_bucket: F) where F: FnMut(&mut A::Item, &mut A::Item) -> bool {
self.0.dedup_by(same_bucket)
}
#[inline]
pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: NonZeroUsize, f: F) {
self.0.resize_with(new_len.get(), f)
}
#[inline]
pub unsafe fn from_raw_parts(ptr: *mut A::Item, length: NonZeroUsize, capacity: NonZeroUsize) -> NonEmptySmallVec<A> {
NonEmptySmallVec(SmallVec::from_raw_parts(ptr, length.get(), capacity.get()))
}
#[inline]
pub fn grow(&mut self, new_cap: NonZeroUsize) {
self.0.grow(new_cap.get())
}
#[inline]
pub fn try_grow(&mut self, new_cap: NonZeroUsize) -> Result<(), CollectionAllocErr> {
self.0.try_grow(new_cap.get())
}
}
impl<A: Array> NonEmptySmallVec<A> where A::Item: PartialEq {
#[inline]
pub fn dedup(&mut self) {
self.0.dedup()
}
}
impl<A: Array> NonEmptySmallVec<A> where A::Item: Copy {
#[inline]
pub fn from_slice(slice: &NonEmptySlice<A::Item>) -> NonEmptySmallVec<A> {
NonEmptySmallVec(SmallVec::from_slice(slice))
}
#[inline]
pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {
self.0.insert_from_slice(index, slice)
}
#[inline]
pub fn extend_from_slice(&mut self, slice: &[A::Item]) {
self.0.extend_from_slice(slice)
}
}
impl<A: Array> NonEmptySmallVec<A> where A::Item: Clone {
#[inline]
pub fn resize(&mut self, len: NonZeroUsize, value: A::Item) {
self.0.resize(len.get(), value)
}
#[inline]
pub fn from_elem(elem: A::Item, n: NonZeroUsize) -> NonEmptySmallVec<A> {
NonEmptySmallVec(SmallVec::from_elem(elem, n.get()))
}
}
impl<A: Array> std::ops::Deref for NonEmptySmallVec<A> {
type Target = NonEmptySlice<A::Item>;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { NonEmptySlice::from_slice_unchecked(&self.0) }
}
}
impl<A: Array> std::ops::DerefMut for NonEmptySmallVec<A> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { NonEmptySlice::from_slice_unchecked_mut(&mut self.0) }
}
}
impl<A: Array> Extend<A::Item> for NonEmptySmallVec<A> {
fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
self.0.extend(iter)
}
}
impl<A: Array> std::fmt::Debug for NonEmptySmallVec<A> where A::Item: std::fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl<A: Array> Clone for NonEmptySmallVec<A> where A::Item: Clone {
fn clone(&self) -> Self {
NonEmptySmallVec(self.0.clone())
}
fn clone_from(&mut self, source: &Self) {
self.0.clone_from(&source.0)
}
}
impl<A: Array, B: Array> PartialEq<NonEmptySmallVec<A>> for NonEmptySmallVec<B> where B::Item: PartialEq<A::Item> {
fn eq(&self, other: &NonEmptySmallVec<A>) -> bool {
self.0 == other.0
}
}
impl<A: Array> Eq for NonEmptySmallVec<A> where A::Item: Eq {}
impl<A: Array> PartialOrd for NonEmptySmallVec<A> where A::Item: PartialOrd {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<A: Array> Ord for NonEmptySmallVec<A> where A::Item: Ord {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl<A: Array> std::hash::Hash for NonEmptySmallVec<A> where A::Item: std::hash::Hash {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
impl<A: Array> std::iter::IntoIterator for NonEmptySmallVec<A> {
type IntoIter = smallvec::IntoIter<A>;
type Item = A::Item;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<A: Array> AsRef<[A::Item]> for NonEmptySmallVec<A> {
#[inline]
fn as_ref(&self) -> &[A::Item] {
self
}
}
impl<A: Array> AsMut<[A::Item]> for NonEmptySmallVec<A> {
#[inline]
fn as_mut(&mut self) -> &mut [A::Item] {
self
}
}
impl<A: Array> core::borrow::Borrow<[A::Item]> for NonEmptySmallVec<A> {
#[inline]
fn borrow(&self) -> &[A::Item] {
self
}
}
impl<A: Array> core::borrow::BorrowMut<[A::Item]> for NonEmptySmallVec<A> {
#[inline]
fn borrow_mut(&mut self) -> &mut [A::Item] {
self
}
}
impl<A: Array> AsRef<NonEmptySlice<A::Item>> for NonEmptySmallVec<A> {
#[inline]
fn as_ref(&self) -> &NonEmptySlice<A::Item> {
self
}
}
impl<A: Array> AsMut<NonEmptySlice<A::Item>> for NonEmptySmallVec<A> {
#[inline]
fn as_mut(&mut self) -> &mut NonEmptySlice<A::Item> {
self
}
}
impl<A: Array> core::borrow::Borrow<NonEmptySlice<A::Item>> for NonEmptySmallVec<A> {
#[inline]
fn borrow(&self) -> &NonEmptySlice<A::Item> {
self
}
}
impl<A: Array> core::borrow::BorrowMut<NonEmptySlice<A::Item>> for NonEmptySmallVec<A> {
#[inline]
fn borrow_mut(&mut self) -> &mut NonEmptySlice<A::Item> {
self
}
}
impl<A: Array> TryFrom<SmallVec<A>> for NonEmptySmallVec<A> {
type Error = SmallVec<A>;
#[inline]
fn try_from(small_vec: SmallVec<A>) -> Result<Self, Self::Error> {
NonEmptySmallVec::try_from_smallvec(small_vec)
}
}
impl<A: Array> From<NonEmptySmallVec<A>> for SmallVec<A> {
#[inline]
fn from(non_empty_small_vec: NonEmptySmallVec<A>) -> Self {
non_empty_small_vec.0
}
}
impl<T, const N: usize> NonEmptySmallVec<[T; N]> {
#[inline]
pub fn from_buf(buf: [T; N]) -> NonEmptySmallVec<[T; N]> {
const { assert!(N > 0, "Length of array must be non-zero to create NonEmptySmallVec."); }
NonEmptySmallVec(SmallVec::from_buf(buf))
}
#[inline]
pub fn from_buf_and_len(buf: [T; N], len: NonZeroUsize) -> NonEmptySmallVec<[T; N]> {
const { assert!(N > 0, "Length of array must be non-zero to create NonEmptySmallVec."); }
NonEmptySmallVec(SmallVec::from_buf_and_len(buf, len.get()))
}
#[inline]
pub unsafe fn from_buf_and_len_unchecked(buf: core::mem::MaybeUninit<[T; N]>, len: NonZeroUsize) -> NonEmptySmallVec<[T; N]> {
const { assert!(N > 0, "Length of array must be non-zero to create NonEmptySmallVec."); }
NonEmptySmallVec(SmallVec::from_buf_and_len_unchecked(buf, len.get()))
}
}
impl<T, const N: usize> From<[T; N]> for NonEmptySmallVec<[T; N]> {
fn from(buf: [T; N]) -> Self {
NonEmptySmallVec(SmallVec::from_buf(buf))
}
}
#[cfg(feature = "dep:smallvec/write")]
impl<A: Array<Item = u8>> std::io::Write for NonEmptySmallVec<A> {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.extend_from_slice(buf);
Ok(())
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}