use std::{mem::ManuallyDrop, ptr};
use crate::Position;
pub unsafe trait Storage {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
type Item;
type Key;
fn key(item: &Self::Item) -> &Self::Key;
fn get(&self, pos: Position) -> &Self::Item;
fn get_mut(&mut self, pos: Position) -> &mut Self::Item;
fn get_key(&self, pos: Position) -> &Self::Key {
Self::key(self.get(pos))
}
type Slot;
fn slot_key(item: &Self::Slot) -> &Self::Key;
unsafe fn load(&self, pos: Position) -> ManuallyDrop<Self::Slot>;
unsafe fn store(&mut self, pos: Position, item: &mut ManuallyDrop<Self::Slot>);
unsafe fn move_element(&mut self, src: Position, dst: Position);
}
unsafe impl<T> Storage for [T] {
fn len(&self) -> usize {
self.len()
}
type Item = T;
type Key = T;
fn key(item: &Self::Item) -> &Self::Key {
item
}
fn get(&self, pos: Position) -> &Self::Item {
&self[pos]
}
fn get_mut(&mut self, pos: Position) -> &mut Self::Item {
&mut self[pos]
}
type Slot = Self::Item;
fn slot_key(item: &Self::Slot) -> &Self::Key {
Self::key(item)
}
unsafe fn load(&self, pos: Position) -> ManuallyDrop<Self::Item> {
let data = unsafe { ptr::read(&self[pos]) };
ManuallyDrop::new(data)
}
unsafe fn store(&mut self, pos: Position, item: &mut ManuallyDrop<Self::Item>) {
let item = unsafe { ManuallyDrop::take(item) };
unsafe { ptr::write(&mut self[pos], item) };
}
unsafe fn move_element(&mut self, src: Position, dst: Position) {
unsafe { ptr::copy_nonoverlapping(&self[src], &mut self[dst], 1) };
}
}
unsafe impl<T> Storage for Vec<T> {
fn len(&self) -> usize {
self.as_slice().len()
}
type Item = T;
type Key = <[T] as Storage>::Key;
fn key(item: &Self::Item) -> &Self::Key {
<[T]>::key(item)
}
fn get(&self, pos: Position) -> &Self::Item {
Storage::get(self.as_slice(), pos)
}
fn get_mut(&mut self, pos: Position) -> &mut Self::Item {
Storage::get_mut(self.as_mut_slice(), pos)
}
fn get_key(&self, pos: Position) -> &Self::Key {
self.as_slice().get_key(pos)
}
type Slot = <[T] as Storage>::Slot;
fn slot_key(item: &Self::Slot) -> &Self::Key {
<[T]>::slot_key(item)
}
unsafe fn load(&self, pos: Position) -> ManuallyDrop<Self::Item> {
unsafe { self.as_slice().load(pos) }
}
unsafe fn store(&mut self, pos: Position, item: &mut ManuallyDrop<Self::Item>) {
unsafe { self.as_mut_slice().store(pos, item) }
}
unsafe fn move_element(&mut self, src: Position, dst: Position) {
unsafe { self.as_mut_slice().move_element(src, dst) }
}
}