use std::ptr::NonNull;
use std::{borrow, cmp, fmt, hash, iter, mem, ops, ptr, slice, u32, vec};
pub struct Vec32<T> {
ptr: ptr::NonNull<T>,
cap: u32,
len: u32,
}
impl<T> Vec32<T> {
pub fn new() -> Vec32<T> {
Vec32 {
ptr: NonNull::dangling(),
cap: if mem::size_of::<T>() == 0 {
u32::MAX
} else {
0
},
len: 0,
}
}
pub fn with_capacity(cap: u32) -> Vec32<T> {
let mut v = Vec::with_capacity(cap as usize);
let ptr = NonNull::new(v.as_mut_ptr()).unwrap();
mem::forget(v);
Vec32 { ptr, cap, len: 0 }
}
pub fn push(&mut self, value: T) {
if self.len == self.cap {
self.reserve(1);
}
unsafe {
let end = self.ptr.as_ptr().add(self.len as _);
ptr::write(end, value);
self.len += 1;
}
}
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 {
None
} else {
unsafe {
self.len -= 1;
Some(ptr::read(self.ptr.as_ptr().add(self.len as _)))
}
}
}
pub fn remove(&mut self, index: u32) -> T {
let len = self.len;
assert!(index < len);
unsafe {
let ptr = self.as_mut_ptr().offset(index as isize);
let ret = ptr::read(ptr);
ptr::copy(ptr.offset(1), ptr, (len - index - 1) as usize);
self.len -= 1;
ret
}
}
pub fn insert(&mut self, index: u32, element: T) {
let len = self.len;
assert!(index <= len);
if len == self.cap {
self.reserve(1);
}
unsafe {
let p = self.as_mut_ptr().offset(index as isize);
ptr::copy(p, p.offset(1), (len - index) as usize);
ptr::write(p, element);
self.len += 1;
}
}
pub fn reserve(&mut self, additional: u32) {
let min_cap = self.len.checked_add(additional).expect("capacity overflow");
if min_cap <= self.cap {
return;
}
let double_cap = self.cap.saturating_mul(2);
let new_cap = cmp::max(min_cap, double_cap);
let additional = new_cap - self.len;
self.reserve_exact(additional);
}
pub fn reserve_exact(&mut self, additional: u32) {
self.as_vec(|v| v.reserve_exact(additional as usize));
}
pub fn shrink_to_fit(&mut self) {
self.as_vec(|v| v.shrink_to_fit());
}
pub fn from_vec(mut vec: Vec<T>) -> Vec32<T> {
let len = vec.len();
assert!(len <= u32::MAX as usize);
if vec.capacity() > u32::MAX as usize {
vec.shrink_to_fit();
}
let cap = if mem::size_of::<T>() == 0 {
u32::MAX
} else {
vec.capacity() as u32
};
let ptr = NonNull::new(vec.as_mut_ptr()).unwrap();
mem::forget(vec);
Vec32 {
ptr,
cap,
len: len as u32,
}
}
pub fn into_vec(self) -> Vec<T> {
unsafe {
let v = Vec::from_raw_parts(self.ptr.as_ptr(), self.len as usize, self.cap as usize);
mem::forget(self);
v
}
}
pub fn as_vec<F>(&mut self, f: F)
where
F: FnOnce(&mut Vec<T>),
{
let mut vec = mem::replace(self, Vec32::new()).into_vec();
f(&mut vec);
*self = Vec32::from_vec(vec);
}
pub fn capacity(&self) -> u32 {
self.cap
}
pub fn clear(&mut self) {
self.truncate(0)
}
pub fn truncate(&mut self, len: u32) {
unsafe {
while len < self.len {
self.len -= 1;
let len = self.len as usize;
ptr::drop_in_place(self.get_unchecked_mut(len));
}
}
}
}
#[macro_export]
macro_rules! vec32 {
($elem:expr; $n:expr) => (
$crate::Vec32::from_vec(vec![$elem; $n])
);
($($x:expr),*) => (
$crate::Vec32::from_vec(vec![$($x),*])
);
($($x:expr,)*) => (vec32![$($x),*])
}
impl<T> AsMut<Vec32<T>> for Vec32<T> {
fn as_mut(&mut self) -> &mut Vec32<T> {
self
}
}
impl<T> AsMut<[T]> for Vec32<T> {
fn as_mut(&mut self) -> &mut [T] {
self
}
}
impl<T> AsRef<Vec32<T>> for Vec32<T> {
fn as_ref(&self) -> &Vec32<T> {
self
}
}
impl<T> AsRef<[T]> for Vec32<T> {
fn as_ref(&self) -> &[T] {
self
}
}
impl<T> borrow::Borrow<[T]> for Vec32<T> {
fn borrow(&self) -> &[T] {
&self[..]
}
}
impl<T> borrow::BorrowMut<[T]> for Vec32<T> {
fn borrow_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}
impl<T> Default for Vec32<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Drop for Vec32<T> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(&mut self[..]);
Vec::from_raw_parts(self.ptr.as_ptr(), 0, self.cap as usize);
}
}
}
impl<T, I: slice::SliceIndex<[T]>> ops::Index<I> for Vec32<T> {
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
ops::Index::index(&**self, index)
}
}
impl<T, I: slice::SliceIndex<[T]>> ops::IndexMut<I> for Vec32<T> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
ops::IndexMut::index_mut(&mut **self, index)
}
}
unsafe impl<T: Sync> Sync for Vec32<T> {}
unsafe impl<T: Send> Send for Vec32<T> {}
impl<T: Clone> Clone for Vec32<T> {
fn clone(&self) -> Self {
Vec32::from_vec(self[..].to_vec())
}
}
impl<T> ops::Deref for Vec32<T> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len as usize) }
}
}
impl<T> ops::DerefMut for Vec32<T> {
fn deref_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len as usize) }
}
}
impl<T> IntoIterator for Vec32<T> {
type Item = T;
type IntoIter = vec::IntoIter<T>;
fn into_iter(self) -> vec::IntoIter<T> {
self.into_vec().into_iter()
}
}
impl<'a, T> IntoIterator for &'a Vec32<T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> slice::Iter<'a, T> {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Vec32<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> slice::IterMut<'a, T> {
self.iter_mut()
}
}
impl<T> Extend<T> for Vec32<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let iterator = iter.into_iter();
let (lower, _) = iterator.size_hint();
assert!(lower < u32::MAX as usize);
self.reserve(lower as u32);
for i in iterator {
self.push(i);
}
}
}
impl<T> iter::FromIterator<T> for Vec32<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec32<T> {
let iterator = iter.into_iter();
let (lower, _) = iterator.size_hint();
assert!(lower < u32::MAX as usize);
let mut v = Vec32::with_capacity(lower as u32);
for i in iterator {
v.push(i);
}
v
}
}
impl<T: fmt::Debug> fmt::Debug for Vec32<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self[..], f)
}
}
impl<T: PartialOrd> PartialOrd for Vec32<T> {
fn partial_cmp(&self, other: &Vec32<T>) -> Option<cmp::Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<T: Ord> Ord for Vec32<T> {
fn cmp(&self, other: &Vec32<T>) -> cmp::Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<T: Eq> Eq for Vec32<T> {}
impl<T, U> PartialEq<U> for Vec32<T>
where
U: for<'a> PartialEq<&'a [T]>,
{
fn eq(&self, other: &U) -> bool {
*other == &self[..]
}
fn ne(&self, other: &U) -> bool {
*other != &self[..]
}
}
impl<T: hash::Hash> hash::Hash for Vec32<T> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
(&**self).hash(state)
}
}
#[cfg(test)]
mod tests {
use super::Vec32;
#[test]
fn singledrop() {
struct SingleDrop(bool);
impl Drop for SingleDrop {
fn drop(&mut self) {
assert!(self.0);
self.0 = false
}
}
let mut v = vec32![SingleDrop(true)];
v.push(SingleDrop(true));
}
#[test]
fn it_works() {
let mut v = vec32![1, 2, 3];
assert_eq!(v.pop(), Some(3));
v.push(4);
assert_eq!(v, vec![1, 2, 4]);
}
#[test]
fn test_size() {
use std::mem::size_of;
#[cfg(target_pointer_width = "64")]
assert_eq!(size_of::<Vec32<()>>(), 16);
#[cfg(target_pointer_width = "32")]
assert_eq!(size_of::<Vec32<()>>(), 12);
}
#[test]
fn test_hash() {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hash1 = DefaultHasher::new();
let mut hash2 = DefaultHasher::new();
let v1 = vec32![1, 2, 3];
let v2 = vec![1, 2, 3];
v1.hash(&mut hash1);
v2.hash(&mut hash2);
assert_eq!(hash1.finish(), hash2.finish());
}
}