use std::iter::FromIterator;
pub use columnation::*;
use crate::PushInto;
pub struct TimelyStack<T: Columnation> {
local: Vec<T>,
inner: T::InnerRegion,
}
impl<T: Columnation> TimelyStack<T> {
pub fn with_capacity(capacity: usize) -> Self {
Self {
local: Vec::with_capacity(capacity),
inner: T::InnerRegion::default(),
}
}
#[inline(always)]
pub fn reserve_items<'a, I>(&mut self, items: I)
where
I: Iterator<Item= &'a T>+Clone,
T: 'a,
{
self.local.reserve(items.clone().count());
self.inner.reserve_items(items);
}
#[inline(always)]
pub fn reserve_regions<'a, I>(&mut self, regions: I)
where
Self: 'a,
I: Iterator<Item= &'a Self>+Clone,
{
self.local.reserve(regions.clone().map(|cs| cs.local.len()).sum());
self.inner.reserve_regions(regions.map(|cs| &cs.inner));
}
pub fn copy(&mut self, item: &T) {
unsafe {
self.local.push(self.inner.copy(item));
}
}
pub fn clear(&mut self) {
unsafe {
self.local.set_len(0);
self.inner.clear();
}
}
pub fn retain_from<P: FnMut(&T) -> bool>(&mut self, index: usize, mut predicate: P) {
let mut write_position = index;
for position in index..self.local.len() {
if predicate(&self[position]) {
self.local.swap(position, write_position);
write_position += 1;
}
}
unsafe {
self.local.set_len(write_position);
}
}
pub unsafe fn local(&mut self) -> &mut [T] {
&mut self.local[..]
}
#[inline]
pub fn heap_size(&self, mut callback: impl FnMut(usize, usize)) {
let size_of = std::mem::size_of::<T>();
callback(self.local.len() * size_of, self.local.capacity() * size_of);
self.inner.heap_size(callback);
}
#[inline]
pub fn summed_heap_size(&self) -> (usize, usize) {
let (mut length, mut capacity) = (0, 0);
self.heap_size(|len, cap| {
length += len;
capacity += cap
});
(length, capacity)
}
#[inline]
pub fn len(&self) -> usize {
self.local.len()
}
#[inline]
pub fn capacity(&self) -> usize {
self.local.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.local.reserve(additional)
}
}
impl<A: Columnation, B: Columnation> TimelyStack<(A, B)> {
pub fn copy_destructured(&mut self, t1: &A, t2: &B) {
unsafe {
self.local.push(self.inner.copy_destructured(t1, t2));
}
}
}
impl<A: Columnation, B: Columnation, C: Columnation> TimelyStack<(A, B, C)> {
pub fn copy_destructured(&mut self, r0: &A, r1: &B, r2: &C) {
unsafe {
self.local.push(self.inner.copy_destructured(r0, r1, r2));
}
}
}
impl<T: Columnation> std::ops::Deref for TimelyStack<T> {
type Target = [T];
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.local[..]
}
}
impl<T: Columnation> Drop for TimelyStack<T> {
fn drop(&mut self) {
self.clear();
}
}
impl<T: Columnation> Default for TimelyStack<T> {
fn default() -> Self {
Self {
local: Vec::new(),
inner: T::InnerRegion::default(),
}
}
}
impl<'a, A: 'a + Columnation> FromIterator<&'a A> for TimelyStack<A> {
fn from_iter<T: IntoIterator<Item = &'a A>>(iter: T) -> Self {
let iter = iter.into_iter();
let mut c = TimelyStack::<A>::with_capacity(iter.size_hint().0);
for element in iter {
c.copy(element);
}
c
}
}
impl<T: Columnation + PartialEq> PartialEq for TimelyStack<T> {
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(&self[..], &other[..])
}
}
impl<T: Columnation + Eq> Eq for TimelyStack<T> {}
impl<T: Columnation + std::fmt::Debug> std::fmt::Debug for TimelyStack<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self[..].fmt(f)
}
}
impl<T: Columnation> Clone for TimelyStack<T> {
fn clone(&self) -> Self {
let mut new: Self = Default::default();
for item in &self[..] {
new.copy(item);
}
new
}
fn clone_from(&mut self, source: &Self) {
self.clear();
for item in &source[..] {
self.copy(item);
}
}
}
impl<T: Columnation> PushInto<T> for TimelyStack<T> {
#[inline]
fn push_into(&mut self, item: T) {
self.copy(&item);
}
}
impl<T: Columnation> PushInto<&T> for TimelyStack<T> {
#[inline]
fn push_into(&mut self, item: &T) {
self.copy(item);
}
}
impl<T: Columnation> PushInto<&&T> for TimelyStack<T> {
#[inline]
fn push_into(&mut self, item: &&T) {
self.copy(*item);
}
}
mod serde {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::columnation::{Columnation, TimelyStack};
impl<T: Columnation + Serialize> Serialize for TimelyStack<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.local.len()))?;
for element in &self[..] {
seq.serialize_element(element)?;
}
seq.end()
}
}
impl<'a, T: Columnation + Deserialize<'a>> Deserialize<'a> for TimelyStack<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'a>,
{
use serde::de::{SeqAccess, Visitor};
use std::fmt;
use std::marker::PhantomData;
struct TimelyStackVisitor<T> {
marker: PhantomData<T>,
}
impl<'de, T: Columnation> Visitor<'de> for TimelyStackVisitor<T>
where
T: Deserialize<'de>,
{
type Value = TimelyStack<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let local = Vec::with_capacity(
seq.size_hint()
.unwrap_or(crate::buffer::default_capacity::<T>()),
);
let mut stack = TimelyStack {
local,
inner: T::InnerRegion::default(),
};
while let Some(value) = seq.next_element()? {
stack.copy(&value);
}
Ok(stack)
}
}
let visitor = TimelyStackVisitor {
marker: PhantomData,
};
deserializer.deserialize_seq(visitor)
}
}
}
mod container {
use std::ops::Deref;
use crate::{Container, SizableContainer};
use crate::columnation::{Columnation, TimelyStack};
impl<T: Columnation> Container for TimelyStack<T> {
type ItemRef<'a> = &'a T where Self: 'a;
type Item<'a> = &'a T where Self: 'a;
fn len(&self) -> usize {
self.local.len()
}
fn is_empty(&self) -> bool {
self.local.is_empty()
}
fn clear(&mut self) {
TimelyStack::clear(self)
}
type Iter<'a> = std::slice::Iter<'a, T> where Self: 'a;
fn iter(&self) -> Self::Iter<'_> {
self.deref().iter()
}
type DrainIter<'a> = std::slice::Iter<'a, T> where Self: 'a;
fn drain(&mut self) -> Self::DrainIter<'_> {
(*self).iter()
}
}
impl<T: Columnation> SizableContainer for TimelyStack<T> {
fn at_capacity(&self) -> bool {
self.len() == self.capacity()
}
fn ensure_capacity(&mut self, stash: &mut Option<Self>) {
if self.capacity() == 0 {
*self = stash.take().unwrap_or_default();
self.clear();
}
let preferred = crate::buffer::default_capacity::<T>();
if self.capacity() < preferred {
self.reserve(preferred - self.capacity());
}
}
}
}
mod flatcontainer {
use columnation::Columnation;
use flatcontainer::{Push, Region, ReserveItems};
use crate::columnation::TimelyStack;
#[derive(Debug, Clone)]
struct ColumnationRegion<T: Columnation> {
inner: TimelyStack<T>,
}
impl<T: Columnation> Default for ColumnationRegion<T> {
fn default() -> Self {
Self { inner: Default::default() }
}
}
impl<T: Columnation + Clone> Region for ColumnationRegion<T> {
type Owned = T;
type ReadItem<'a> = &'a T where Self: 'a;
type Index = usize;
fn merge_regions<'a>(regions: impl Iterator<Item=&'a Self> + Clone) -> Self where Self: 'a {
let mut inner = TimelyStack::default();
inner.reserve_regions(regions.map(|r| &r.inner));
Self { inner}
}
fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
&self.inner[index]
}
fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, I: Iterator<Item=&'a Self> + Clone {
self.inner.reserve_regions(regions.map(|r| &r.inner));
}
fn clear(&mut self) {
self.inner.clear();
}
fn heap_size<F: FnMut(usize, usize)>(&self, callback: F) {
self.inner.heap_size(callback);
}
fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> where Self: 'a {
item
}
}
impl<T: Columnation + Clone> Push<T> for ColumnationRegion<T> {
fn push(&mut self, item: T) -> Self::Index {
self.inner.copy(&item);
self.inner.len() - 1
}
}
impl<T: Columnation + Clone> Push<&T> for ColumnationRegion<T> {
fn push(&mut self, item: &T) -> Self::Index {
self.inner.copy(item);
self.inner.len() - 1
}
}
impl<T: Columnation + Clone> Push<&&T> for ColumnationRegion<T> {
fn push(&mut self, item: &&T) -> Self::Index {
self.inner.copy(*item);
self.inner.len() - 1
}
}
impl<'a, T: Columnation + Clone + 'a> ReserveItems<&'a T> for ColumnationRegion<T> {
fn reserve_items<I>(&mut self, items: I) where I: Iterator<Item=&'a T> + Clone {
self.inner.reserve_items(items);
}
}
}