use std::any::{TypeId, type_name};
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use std::{fmt, mem, ptr, slice};
struct RawVec {
ptr: *mut u8,
length: usize,
cap: usize,
}
impl RawVec {
fn new_dangling() -> Self {
Self {
ptr: ptr::dangling_mut(),
length: 0,
cap: 0,
}
}
fn from_vec<T>(vec: Vec<T>) -> Self {
let (ptr, length, cap) = vec.into_raw_parts();
Self {
ptr: ptr.cast(),
length,
cap,
}
}
unsafe fn update_from<T>(&mut self, vec: &mut ManuallyDrop<Vec<T>>) {
self.ptr = vec.as_mut_ptr().cast();
self.length = vec.len();
self.cap = vec.capacity();
}
unsafe fn as_slice<T>(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self.ptr.cast(), self.length)
}
}
unsafe fn into_vec<T>(self) -> Vec<T> {
unsafe { Vec::from_raw_parts(self.ptr.cast(), self.length, self.cap) }
}
unsafe fn as_manually_drop_vec<T>(&self) -> ManuallyDrop<Vec<T>> {
unsafe { ManuallyDrop::new(Vec::from_raw_parts(self.ptr.cast(), self.length, self.cap)) }
}
}
unsafe fn drop_raw_vec<T>(raw_vec: RawVec) {
let vec = unsafe { raw_vec.into_vec::<T>() };
drop(vec);
}
pub struct AnyVec {
raw_vec: RawVec,
type_id: TypeId,
type_name: &'static str,
drop: unsafe fn(RawVec),
}
unsafe impl Send for AnyVec {}
unsafe impl Sync for AnyVec {}
impl AnyVec {
pub fn new<T: 'static + Send + Sync>() -> Self {
Self::from_vec(Vec::<T>::new())
}
pub fn new_with_capacity<T: 'static + Send + Sync>(capacity: usize) -> Self {
Self::from_vec(Vec::<T>::with_capacity(capacity))
}
pub fn from_vec<T: 'static + Send + Sync>(vec: Vec<T>) -> Self {
Self {
raw_vec: RawVec::from_vec(vec),
type_id: TypeId::of::<T>(),
type_name: type_name::<T>(),
drop: drop_raw_vec::<T>,
}
}
pub fn elem_type_id(&self) -> TypeId {
self.type_id
}
pub fn type_name(&self) -> &'static str {
self.type_name
}
pub fn get<T: 'static>(&self) -> Option<&[T]> {
if self.type_id == TypeId::of::<T>() {
unsafe {
Some(self.get_unchecked::<T>())
}
} else {
None
}
}
pub unsafe fn get_unchecked<T: 'static>(&self) -> &[T] {
unsafe { self.raw_vec.as_slice::<T>() }
}
pub fn get_ref<T: 'static>(&self) -> Option<AnyVecRef<'_, T>> {
if self.type_id == TypeId::of::<T>() {
unsafe {
Some(AnyVecRef::new(self))
}
} else {
None
}
}
pub unsafe fn get_ref_unchecked<T: 'static>(&self) -> AnyVecRef<'_, T> {
unsafe { AnyVecRef::new(self) }
}
pub fn get_mut<T: 'static>(&mut self) -> Option<AnyVecMutRef<'_, T>> {
if self.type_id == TypeId::of::<T>() {
unsafe {
Some(AnyVecMutRef::new(self))
}
} else {
None
}
}
pub unsafe fn get_mut_unchecked<T: 'static>(&mut self) -> AnyVecMutRef<'_, T> {
unsafe { AnyVecMutRef::new(self) }
}
pub fn len(&self) -> usize {
self.raw_vec.length
}
pub fn is_empty(&self) -> bool {
self.raw_vec.length == 0
}
pub fn try_into_vec<T: 'static>(self) -> Result<Vec<T>, Self> {
if self.type_id == TypeId::of::<T>() {
Ok(unsafe { self.into_vec_unchecked::<T>() })
} else {
Err(self)
}
}
pub unsafe fn into_vec_unchecked<T: 'static>(mut self) -> Vec<T> {
let raw_vec = mem::replace(&mut self.raw_vec, RawVec::new_dangling());
mem::forget(self); unsafe {
raw_vec.into_vec::<T>()
}
}
}
impl fmt::Debug for AnyVec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AnyVec")
.field("type", &self.type_name)
.field("length", &self.raw_vec.length)
.finish()
}
}
impl Drop for AnyVec {
fn drop(&mut self) {
let inner = mem::replace(&mut self.raw_vec, RawVec::new_dangling());
unsafe {
(self.drop)(inner);
}
}
}
pub struct AnyVecRef<'a, T> {
raw: &'a AnyVec,
vec: ManuallyDrop<Vec<T>>,
}
pub struct AnyVecMutRef<'a, T> {
raw: &'a mut AnyVec,
vec: ManuallyDrop<Vec<T>>,
}
unsafe impl<'a, T: Send> Send for AnyVecRef<'a, T> {}
unsafe impl<'a, T: Sync> Sync for AnyVecRef<'a, T> {}
unsafe impl<'a, T: Send> Send for AnyVecMutRef<'a, T> {}
unsafe impl<'a, T: Sync> Sync for AnyVecMutRef<'a, T> {}
impl<'a, T> AnyVecRef<'a, T> {
unsafe fn new(raw: &'a AnyVec) -> Self {
let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
Self { raw, vec }
}
}
impl<'a, T> AnyVecMutRef<'a, T> {
unsafe fn new(raw: &'a mut AnyVec) -> Self {
let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
Self { raw, vec }
}
}
impl<'a, T> Clone for AnyVecRef<'a, T> {
fn clone(&self) -> Self {
unsafe {
Self::new(self.raw)
}
}
}
impl<'a, T> Deref for AnyVecRef<'a, T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.vec
}
}
impl<'a, T> Deref for AnyVecMutRef<'a, T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.vec
}
}
impl<'a, T> DerefMut for AnyVecMutRef<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.vec
}
}
impl<'a, T: fmt::Debug> fmt::Debug for AnyVecRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.vec.fmt(f)
}
}
impl<'a, T: fmt::Debug> fmt::Debug for AnyVecMutRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.vec.fmt(f)
}
}
impl<'a, T> Drop for AnyVecMutRef<'a, T> {
fn drop(&mut self) {
unsafe {
self.raw.raw_vec.update_from(&mut self.vec);
}
}
}