use std::ops::Deref;
use std::ops::DerefMut;
use std::pin::Pin;
mod deref; pub use deref::*;
mod index; pub use index::*;
mod iter; pub use iter::*;
#[derive(Debug)]
pub struct AutoVec<T> {
raw: Pin<Box<RawAutoVec<T>>>
}
#[derive(Debug)]
pub struct RawAutoVec<T> {
children: Vec<*const RawAutoChild<T>>,
}
#[derive(Debug)]
pub struct RawAutoChild<T> {
parent: *const RawAutoVec<T>,
index: usize,
pub child: T,
}
#[derive(Debug)]
pub struct AutoChild<T> {
raw: Pin<Box<RawAutoChild<T>>>
}
impl<T> AutoChild<T> {
pub fn new(child: T) -> Self {
Self {
raw: Box::pin(
RawAutoChild {
parent: 0 as _, index: 0,
child,
}
)
}
}
}
impl<T> Drop for AutoChild<T> {
fn drop(&mut self) {
if self.parent!= 0 as _ {
unsafe {&mut*(self.parent as *mut RawAutoVec<T>)}.called_remove(self);
}
}
}
impl<T> Drop for AutoVec<T> {
fn drop(&mut self) {
for i in &self.children {
unsafe {&mut*(*i as *mut RawAutoChild<T>)}.parent = 0 as _;
}
}
}
impl<T> RawAutoVec<T> {
fn len(&self) -> usize{
self.children.len()
}
#[inline]
fn called_remove(&mut self, child: &RawAutoChild<T>) {
self.children.swap_remove(child.index);
}
}
impl<T> AutoVec<T> {
#[inline]
pub fn new() -> Self {
Self {
raw: Box::pin(
RawAutoVec {
children: Vec::new(),
}
)
}
}
pub fn append(&mut self, other: &mut AutoVec<T>) {
let other = &mut other.raw as &mut RawAutoVec<T>;
for i in 0..other.len() {
let child = unsafe {&mut*(other.children[i] as *mut RawAutoChild<T>)};
child.parent = &self.raw as &RawAutoVec<T> as _;
child.index = i + self.len();
}
self.children.append(&mut other.children);
}
pub fn add(&mut self, child: &mut RawAutoChild<T>) {
if child.parent == 0 as _ {
child.parent = &self.raw as &RawAutoVec<T> as _;
child.index = self.children.len();
self.children.push(child as *const _ as *const RawAutoChild<T>);
} else {
if child.parent != &self.raw as &RawAutoVec<T> as _ {
unsafe {(child.parent as *mut AutoVec<T>).as_mut().unwrap().called_remove(&child)};
child.parent = &self.raw as &RawAutoVec<T> as _;
child.index = self.children.len();
self.children.push(child as *const _ as *const RawAutoChild<T>);
}
}
}
pub fn remove(&mut self, child: &mut RawAutoChild<T>) {
self.children.swap_remove(child.index);
child.parent = 0 as _;
}
pub fn clear(&mut self) {
for i in 0..self.children.len() {
unsafe {(&mut*(self.children[i] as *mut RawAutoChild<T>)).parent = 0 as _};
}
self.children.clear();
}
#[inline]
pub fn len(&self) -> usize {
self.children.len()
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.children.shrink_to(min_capacity);
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.children.shrink_to_fit();
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
raw: Box::pin(
RawAutoVec {
children: Vec::with_capacity(capacity)
}
)
}
}
}