use fnv::{FnvHashMap};
use smallvec::{SmallVec};
use std::{u8, u16, char};
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::cmp::{Ordering};
use std::collections::{hash_map, VecDeque};
use std::convert::{TryFrom};
use std::default::{Default};
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::iter::{FromIterator, FusedIterator, repeat};
use std::marker::{PhantomData};
use std::mem::{size_of};
use std::ops::{Bound, RangeBounds};
use super::engine::{glsp, Guard, Span, with_heap};
use super::error::{GError, GResult};
use super::gc::{Allocate, Header, Slot, Root, Visitor};
use super::iter::{GIter, GIterState};
use super::val::{Val};
use super::wrap::{FromVal, IntoVal};
pub trait DequeIndex: deque_index_private::Sealed {
#[doc(hidden)]
fn as_usize<A>(&self, arr: &A) -> GResult<usize> where A: DequeOps;
#[doc(hidden)]
fn as_usize_excluded<A: DequeOps>(&self, arr: &A) -> GResult<usize>;
}
mod deque_index_private {
pub trait Sealed { }
impl Sealed for u8 { }
impl Sealed for u16 { }
impl Sealed for u32 { }
impl Sealed for u64 { }
impl Sealed for u128 { }
impl Sealed for usize { }
impl Sealed for i8 { }
impl Sealed for i16 { }
impl Sealed for i32 { }
impl Sealed for i64 { }
impl Sealed for i128 { }
impl Sealed for isize { }
}
macro_rules! impl_arr_index_unsigned {
($type:ty) => (
impl DequeIndex for $type {
#[inline(always)]
fn as_usize<A>(&self, arr: &A) -> GResult<usize> where A: DequeOps {
ensure!((*self as usize) < arr.len(),
"out-of-bounds arr access: len is {}, index is {}",
arr.len(), *self);
Ok(*self as usize)
}
#[inline(always)]
fn as_usize_excluded<A>(&self, arr: &A) -> GResult<usize> where A: DequeOps {
ensure!((*self as usize) <= arr.len(),
"out-of-bounds arr access: len is {}, index is {}",
arr.len(), *self);
Ok(*self as usize)
}
}
);
}
impl_arr_index_unsigned!(u8);
impl_arr_index_unsigned!(u16);
impl_arr_index_unsigned!(u32);
impl_arr_index_unsigned!(u64);
impl_arr_index_unsigned!(u128);
impl_arr_index_unsigned!(usize);
macro_rules! impl_arr_index_signed {
($type:ty) => (
impl DequeIndex for $type {
#[inline(always)]
fn as_usize<A>(&self, arr: &A) -> GResult<usize> where A: DequeOps {
if *self >= 0 {
ensure!((*self as usize) < arr.len(),
"out-of-bounds arr access: len is {}, index is {}", arr.len(), *self);
Ok(*self as usize)
} else {
let index = arr.len() as isize + (*self as isize);
ensure!(index >= 0 && (index as usize) < arr.len(),
"out-of-bounds arr access: len is {}, index is {}", arr.len(), *self);
Ok(index as usize)
}
}
#[inline(always)]
fn as_usize_excluded<A>(&self, arr: &A) -> GResult<usize> where A: DequeOps {
if *self >= 0 {
ensure!(*self as usize <= arr.len(),
"out-of-bounds arr access: len is {}, index is {}", arr.len(), *self);
Ok(*self as usize)
} else {
let index = arr.len() as isize + (*self as isize);
ensure!(index >= 0 && index as usize <= arr.len(),
"out-of-bounds arr access: len is {}, index is {}", arr.len(), *self);
Ok(index as usize)
}
}
}
);
}
impl_arr_index_signed!(i8);
impl_arr_index_signed!(i16);
impl_arr_index_signed!(i32);
impl_arr_index_signed!(i64);
impl_arr_index_signed!(i128);
impl_arr_index_signed!(isize);
pub trait DequeRange<I: DequeIndex>: RangeBounds<I> + deque_range_private::Sealed<I> {
#[doc(hidden)]
fn as_range<A>(&self, arr: &A) -> GResult<(Bound<usize>, Bound<usize>)>
where A: DequeOps;
}
mod deque_range_private {
use std::ops::{RangeBounds};
use super::{DequeIndex};
pub trait Sealed<I> { }
impl<T, I> Sealed<I> for T where T: RangeBounds<I>, I: DequeIndex { }
}
impl<T, I> DequeRange<I> for T where T: RangeBounds<I>, I: DequeIndex {
fn as_range<A>(&self, arr: &A) -> GResult<(Bound<usize>, Bound<usize>)>
where
A: DequeOps
{
let start_bound = match self.start_bound() {
Bound::Included(index) => Bound::Included(index.as_usize(arr)?),
Bound::Excluded(index) => {
Bound::Excluded(index.as_usize(arr)?)
}
Bound::Unbounded => Bound::Unbounded
};
let end_bound = match self.end_bound() {
Bound::Included(index) => Bound::Included(index.as_usize(arr)?),
Bound::Excluded(index) => Bound::Excluded(index.as_usize_excluded(arr)?),
Bound::Unbounded => Bound::Unbounded
};
Ok((start_bound, end_bound))
}
}
pub trait IntoElement<T>: into_element_private::Sealed<T> {
fn into_element(self) -> GResult<T>;
}
mod into_element_private {
use crate::{gc::Slot, val::Val, wrap::IntoVal};
pub trait Sealed<T> { }
impl<T> Sealed<Slot> for T where T: IntoVal { }
impl Sealed<char> for char { }
impl Sealed<char> for &char { }
impl Sealed<char> for &mut char { }
impl Sealed<char> for Val { }
impl Sealed<char> for &Val { }
impl Sealed<char> for &mut Val { }
impl Sealed<char> for Slot { }
impl Sealed<char> for &Slot { }
impl Sealed<char> for &mut Slot { }
}
pub trait FromElement<T>: Sized + from_element_private::Sealed<T> {
fn from_element(item: &T) -> GResult<Self>;
}
mod from_element_private {
use crate::{gc::Slot, val::Val, wrap::FromVal};
pub trait Sealed<T> { }
impl<T> Sealed<Slot> for T where T: FromVal { }
impl Sealed<char> for char { }
impl Sealed<char> for Val { }
impl Sealed<char> for Slot { }
}
impl<T> IntoElement<Slot> for T where T: IntoVal {
#[inline(always)]
fn into_element(self) -> GResult<Slot> {
self.into_slot()
}
}
impl<T> FromElement<Slot> for T where T: FromVal {
#[inline(always)]
fn from_element(item: &Slot) -> GResult<Self> {
Self::from_slot(item)
}
}
impl IntoElement<char> for char {
#[inline(always)]
fn into_element(self) -> GResult<char> {
Ok(self)
}
}
impl IntoElement<char> for &char {
#[inline(always)]
fn into_element(self) -> GResult<char> {
Ok(*self)
}
}
impl IntoElement<char> for &mut char {
#[inline(always)]
fn into_element(self) -> GResult<char> {
Ok(*self)
}
}
impl IntoElement<char> for Val {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match self {
Val::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl IntoElement<char> for &Val {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match *self {
Val::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl IntoElement<char> for &mut Val {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match *self {
Val::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl IntoElement<char> for Slot {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match self {
Slot::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl IntoElement<char> for &Slot {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match *self {
Slot::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl IntoElement<char> for &mut Slot {
#[inline(always)]
fn into_element(self) -> GResult<char> {
match *self {
Slot::Char(ch) => Ok(ch),
_ => bail!("attempted to assign a {} to a str", self.type_name())
}
}
}
impl FromElement<char> for char {
#[inline(always)]
fn from_element(item: &char) -> GResult<Self> {
Ok(*item)
}
}
impl FromElement<char> for Val {
#[inline(always)]
fn from_element(item: &char) -> GResult<Self> {
Ok(Val::Char(*item))
}
}
impl FromElement<char> for Slot {
#[inline(always)]
fn from_element(item: &char) -> GResult<Self> {
Ok(Slot::Char(*item))
}
}
pub trait DequeOps: Sized + deque_ops_private::Sealed {
type Element;
type Item: FromElement<Self::Element>;
fn push<V: IntoElement<Self::Element>>(&self, val: V) -> GResult<()>;
fn pop<R: FromElement<Self::Element>>(&self) -> GResult<R>;
fn push_start<V: IntoElement<Self::Element>>(&self, val: V) -> GResult<()>;
fn pop_start<R: FromElement<Self::Element>>(&self) -> GResult<R>;
fn grow<V: IntoElement<Self::Element>>(
&self,
start_to_add: usize,
end_to_add: usize,
fill: V
) -> GResult<()>;
fn shrink(&self, start_to_remove: usize, end_to_remove: usize) -> GResult<()>;
fn append(&self, other: &Self) -> GResult<()>;
fn prepend(&self, other: &Self) -> GResult<()>;
fn resize<V: IntoElement<Self::Element>>(&self, new_len: usize, val: V) -> GResult<()>;
fn rotate_left(&self, mid: usize) -> GResult<()>;
fn rotate_right(&self, k: usize) -> GResult<()>;
fn swap<I1: DequeIndex, I2: DequeIndex>(&self, i: I1, j: I2) -> GResult<()>;
fn capacity(&self) -> usize;
fn len(&self) -> usize;
fn is_empty(&self) -> bool { self.len() == 0 }
fn reserve_exact(&self, additional: usize) -> GResult<()>;
fn reserve(&self, additional: usize) -> GResult<()>;
fn shrink_to_fit(&self) -> GResult<()>;
fn truncate(&self, len: usize) -> GResult<()>;
fn clear(&self) -> GResult<()>;
fn contains<V: IntoElement<Self::Element>>(&self, x: V) -> GResult<bool>;
fn sort(&self) -> GResult<()>;
fn sort_by<F>(&self, f: F) -> GResult<()>
where F: FnMut(&Self::Item, &Self::Item) -> GResult<Ordering>;
fn freeze(&self);
fn deep_freeze(&self);
fn is_frozen(&self) -> bool;
fn is_deep_frozen(&self) -> bool;
fn can_mutate(&self) -> bool;
#[doc(hidden)]
fn lock(&self) -> Lock;
fn iter<'a>(&'a self) -> IterDeque<'a, Self>
where
Self: DequeAccess<usize>
{
IterDeque::from(self)
}
fn iter_to<'a, R: FromElement<Self::Element>>(&'a self) -> IterDequeTo<'a, Self, R>
where
Self: DequeAccess<usize>
{
IterDequeTo::from(self)
}
fn extend<I, V>(&self, source: I) -> GResult<()>
where I: IntoIterator<Item = V>, V: IntoElement<Self::Element>;
}
mod deque_ops_private {
use super::{Arr, Deque, Str};
pub trait Sealed { }
impl Sealed for Arr { }
impl Sealed for Deque { }
impl Sealed for Str { }
}
pub trait DequeAccess<I: DequeIndex>: DequeOps {
fn get<R: FromElement<Self::Element>>(&self, index: I) -> GResult<R>;
fn set<V: IntoElement<Self::Element>>(&self, index: I, val: V) -> GResult<()>;
fn insert<V: IntoElement<Self::Element>>(&self, index: I, val: V) -> GResult<()>;
fn del(&self, index: I) -> GResult<()>;
fn remove<R: FromElement<Self::Element>>(&self, index: I) -> GResult<R>;
fn swap_remove<R: FromElement<Self::Element>>(&self, index: I) -> GResult<R>;
fn swap_remove_start<R: FromElement<Self::Element>>(&self, index: I) -> GResult<R>;
}
pub trait DequeAccessRange<I: DequeIndex, R: DequeRange<I> + Debug>: DequeAccess<I> {
fn del_slice(&self, range: R) -> GResult<()>;
}
fn generic_grow<T: Clone>(
vec: &mut VecDeque<T>,
start_to_add: usize,
end_to_add: usize,
fill: T
) {
vec.reserve(start_to_add + end_to_add);
vec.extend(repeat(fill.clone()).take(end_to_add));
for _ in 0 .. start_to_add {
vec.push_front(fill.clone());
}
}
fn generic_shrink<T>(
vec: &mut VecDeque<T>,
start_to_remove: usize,
end_to_remove: usize
) -> GResult<()> {
ensure!(start_to_remove + end_to_remove <= vec.len(),
"attempted to shrink a deque's len below 0");
vec.truncate(vec.len() - end_to_remove);
vec.drain(..start_to_remove);
Ok(())
}
pub struct Arr {
header: Header,
span: Cell<Span>,
vec: RefCell<VecDeque<Slot>>
}
impl Allocate for Arr {
fn header(&self) -> &Header {
&self.header
}
fn visit_raws<V: Visitor>(&self, visitor: &mut V) {
for slot in self.vec.borrow().iter() {
visitor.visit_slot(slot);
}
}
fn clear_raws(&self) {
self.vec.borrow_mut().clear()
}
fn owned_memory_usage(&self) -> usize {
(self.vec.borrow().capacity() + 1) * size_of::<Slot>()
}
}
impl Arr {
pub(crate) fn new() -> Arr {
Arr {
header: Header::new(),
span: Cell::new(Span::default()),
vec: RefCell::new(VecDeque::new())
}
}
pub(crate) fn with_capacity(capacity: usize) -> Arr {
Arr {
header: Header::new(),
span: Cell::new(Span::default()),
vec: RefCell::new(VecDeque::with_capacity(capacity))
}
}
#[allow(dead_code)]
pub(crate) fn from_elem<V: Clone + IntoVal>(elem: V, reps: usize) -> GResult<Arr> {
let mut vec = VecDeque::with_capacity(reps);
for _ in 0 .. reps {
vec.push_back(elem.clone().into_slot()?)
}
Ok(Arr {
header: Header::new(),
span: Cell::new(Span::default()),
vec: RefCell::new(vec)
})
}
pub(crate) fn from_iter<T, V>(source: T) -> GResult<Arr>
where
T: IntoIterator<Item = V>,
V: IntoVal
{
let iter = source.into_iter();
let mut vec = VecDeque::with_capacity(iter.size_hint().0);
for item in iter {
vec.push_back(item.into_slot()?);
}
Ok(Arr {
header: Header::new(),
span: Cell::new(Span::default()),
vec: RefCell::new(vec)
})
}
pub fn shallow_clone(&self) -> Root<Arr> {
let arr = glsp::arr_from_iter(self.iter()).unwrap();
arr.set_span(self.span());
arr
}
pub fn deep_clone(&self) -> GResult<Root<Arr>> {
let arr = glsp::arr_with_capacity(self.len());
for val in self.iter() {
arr.push(val.deep_clone()?).unwrap();
}
arr.set_span(self.span());
Ok(arr)
}
pub fn try_eq(&self, other: &Arr) -> GResult<bool> {
if self.len() != other.len() {
return Ok(false)
}
for (v0, v1) in self.iter().zip(other.iter()) {
if !v0.try_eq(&v1)? {
return Ok(false)
}
}
Ok(true)
}
pub fn access_giter(arr: &Root<Arr>, giter: &Root<GIter>) -> Root<GIter> {
glsp::giter(GIterState::AccessArr(arr.to_raw(), giter.to_raw()))
}
#[doc(hidden)]
pub fn span(&self) -> Span {
self.span.get()
}
#[doc(hidden)]
pub fn set_span(&self, span: Span) {
self.span.set(span)
}
pub(crate) fn borrow(&self) -> Ref<VecDeque<Slot>> {
self.vec.borrow()
}
pub(crate) fn borrow_mut(&self) -> GResult<RefMut<VecDeque<Slot>>> {
ensure!(!self.header.frozen(), "attempted to mutate a frozen arr");
match self.vec.try_borrow_mut() {
Ok(ref_mut) => Ok(ref_mut),
Err(_) => bail!("attempted to mutate a borrowed arr")
}
}
#[allow(dead_code)]
fn write_barrier_val(&self, val: &Val) {
with_heap(|heap| heap.write_barrier_val(self, val));
}
fn write_barrier_slot(&self, slot: &Slot) {
with_heap(|heap| heap.write_barrier_slot(self, slot));
}
fn memory_usage_barrier(&self, prev_usage: usize, cur_usage: usize) {
with_heap(|heap| heap.memory_usage_barrier(self, prev_usage, cur_usage));
}
fn borrow_mut_with_capacity_guard<R, F>(&self, f: F) -> GResult<R>
where
F: FnOnce(&mut RefMut<VecDeque<Slot>>) -> GResult<R>
{
let prev_usage = self.owned_memory_usage();
let _guard = Guard::new(|| {
let cur_usage = self.owned_memory_usage();
if prev_usage != cur_usage {
self.memory_usage_barrier(prev_usage, cur_usage);
}
});
let mut ref_mut = self.borrow_mut()?;
f(&mut ref_mut)
}
}
impl PartialEq<Arr> for Arr {
fn eq(&self, other: &Arr) -> bool {
self.try_eq(other).unwrap()
}
}
impl Eq for Arr { }
impl PartialOrd<Arr> for Arr {
fn partial_cmp(&self, other: &Arr) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl Hash for Arr {
fn hash<H: Hasher>(&self, state: &mut H) {
self.vec.borrow().hash(state)
}
}
impl DequeOps for Arr {
type Element = Slot;
type Item = Val;
fn freeze(&self) {
self.header.freeze()
}
fn deep_freeze(&self) {
self.freeze();
for element in self.iter() {
element.deep_freeze();
}
}
fn is_frozen(&self) -> bool {
self.header.frozen()
}
fn is_deep_frozen(&self) -> bool {
self.header.frozen() && self.iter().all(|val| val.is_deep_frozen())
}
fn can_mutate(&self) -> bool {
(!self.header.frozen()) && self.vec.try_borrow_mut().is_ok()
}
fn sort(&self) -> GResult<()> {
self.sort_by(|v0, v1| {
match v0.partial_cmp(v1) {
Some(ordering) => Ok(ordering),
None => bail!(
"attempted to compare incompatible types: {} and {}",
v0.a_type_name(),
v1.a_type_name()
)
}
})
}
fn sort_by<F>(&self, mut f: F) -> GResult<()>
where
F: FnMut(&Val, &Val) -> GResult<Ordering>
{
let mut vec = SmallVec::<[Val; 64]>::from_iter(self.iter());
let mut error: Option<GError> = None;
vec.sort_by(|a, b| {
if error.is_some() {
return Ordering::Equal
}
match f(a, b) {
Ok(ordering) => ordering,
Err(err) => {
error = Some(err);
Ordering::Equal
}
}
});
match error {
Some(error) => Err(error),
None => {
for (i, val) in vec.drain(..).enumerate() {
self.set(i, val).unwrap();
}
Ok(())
}
}
}
fn push<V: IntoElement<Slot>>(&self, val: V) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|vec| {
let val = val.into_element()?;
self.write_barrier_slot(&val);
vec.push_back(val);
Ok(())
})
}
fn pop<R: FromElement<Slot>>(&self) -> GResult<R> {
match self.borrow_mut()?.pop_back() {
Some(val) => R::from_element(&val),
None => bail!("attempted to pop from an arr of length 0")
}
}
fn push_start<V: IntoElement<Slot>>(&self, val: V) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|vec| {
let val = val.into_element()?;
self.write_barrier_slot(&val);
vec.push_front(val);
Ok(())
})
}
fn pop_start<R: FromElement<Slot>>(&self) -> GResult<R> {
match self.borrow_mut()?.pop_front() {
Some(val) => R::from_element(&val),
None => bail!("attempted to pop from the start of an arr of length 0")
}
}
fn grow<V: IntoElement<Slot>>(&self, start_to_add: usize,
end_to_add: usize, fill: V) -> GResult<()> {
if start_to_add + end_to_add > 0 {
self.borrow_mut_with_capacity_guard(|vec| {
let fill = fill.into_element()?;
self.write_barrier_slot(&fill);
generic_grow(vec, start_to_add, end_to_add, fill);
Ok(())
})
} else {
Ok(())
}
}
fn shrink(&self, start_to_remove: usize, end_to_remove: usize) -> GResult<()> {
generic_shrink(&mut *(self.borrow_mut()?), start_to_remove, end_to_remove)
}
fn append(&self, other: &Arr) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|self_vec| {
let other_vec = other.borrow();
self_vec.reserve(other_vec.len());
for slot in other_vec.iter() {
self_vec.push_back(slot.clone());
self.write_barrier_slot(slot);
}
Ok(())
})
}
fn prepend(&self, other: &Arr) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|self_vec| {
let other_vec = other.borrow();
self_vec.reserve(other_vec.len());
for slot in other_vec.iter().rev() {
self_vec.push_front(slot.clone());
self.write_barrier_slot(slot);
}
Ok(())
})
}
fn resize<V: IntoElement<Slot>>(&self, new_len: usize, fill: V) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|self_vec| {
let fill = fill.into_element()?;
let old_len = self_vec.len();
if new_len > old_len {
self.write_barrier_slot(&fill);
}
self_vec.resize(new_len, fill);
Ok(())
})
}
fn rotate_left(&self, mid: usize) -> GResult<()> {
self.borrow_mut()?.rotate_left(mid);
Ok(())
}
fn rotate_right(&self, k: usize) -> GResult<()> {
self.borrow_mut()?.rotate_right(k);
Ok(())
}
fn swap<I1, I2>(&self, index1: I1, index2: I2) -> GResult<()>
where
I1: DequeIndex,
I2: DequeIndex
{
let i1 = index1.as_usize(self)?;
let i2 = index2.as_usize(self)?;
self.borrow_mut()?.swap(i1, i2);
Ok(())
}
fn capacity(&self) -> usize {
self.borrow().capacity()
}
fn len(&self) -> usize {
self.borrow().len()
}
fn reserve_exact(&self, additional: usize) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|vec| {
vec.reserve_exact(additional);
Ok(())
})
}
fn reserve(&self, additional: usize) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|vec| {
vec.reserve(additional);
Ok(())
})
}
fn shrink_to_fit(&self) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|vec| {
vec.shrink_to_fit();
Ok(())
})
}
fn truncate(&self, len: usize) -> GResult<()> {
self.borrow_mut()?.truncate(len);
Ok(())
}
fn clear(&self) -> GResult<()> {
self.borrow_mut()?.clear();
Ok(())
}
fn contains<V: IntoElement<Slot>>(&self, x: V) -> GResult<bool> {
Ok(self.borrow().contains(&x.into_element()?))
}
fn extend<I, V>(&self, source: I) -> GResult<()>
where
I: IntoIterator<Item = V>,
V: IntoElement<Slot>
{
let iter = source.into_iter();
self.borrow_mut_with_capacity_guard(|vec| {
vec.reserve(iter.size_hint().0);
Ok(())
})?;
for val in iter {
let val = val.into_element()?;
self.write_barrier_slot(&val);
self.borrow_mut_with_capacity_guard(|vec| {
vec.push_back(val);
Ok(())
})?;
}
Ok(())
}
#[doc(hidden)]
fn lock(&self) -> Lock {
Lock::Arr(self.borrow())
}
}
impl<I: DequeIndex> DequeAccess<I> for Arr {
fn get<R: FromElement<Slot>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
R::from_element(&self.borrow()[i])
}
fn set<V: IntoElement<Slot>>(&self, index: I, val: V) -> GResult<()> {
let i = index.as_usize(self)?;
let val = val.into_element()?;
self.write_barrier_slot(&val);
self.borrow_mut()?[i] = val;
Ok(())
}
fn insert<V: IntoElement<Slot>>(&self, index: I, val: V) -> GResult<()> {
let i = index.as_usize_excluded(self)?;
self.borrow_mut_with_capacity_guard(|vec| {
let val = val.into_element()?;
self.write_barrier_slot(&val);
vec.insert(i, val);
Ok(())
})
}
fn del(&self, index: I) -> GResult<()> {
let i = index.as_usize(self)?;
self.borrow_mut()?.remove(i).unwrap();
Ok(())
}
fn remove<R: FromElement<Slot>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
let slot = self.borrow_mut()?.remove(i).unwrap();
R::from_element(&slot)
}
fn swap_remove<R: FromElement<Slot>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
let slot = self.borrow_mut()?.swap_remove_back(i).unwrap();
R::from_element(&slot)
}
fn swap_remove_start<R: FromElement<Slot>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
let slot = self.borrow_mut()?.swap_remove_front(i).unwrap();
R::from_element(&slot)
}
}
impl<I: DequeIndex, R: DequeRange<I> + Debug> DequeAccessRange<I, R> for Arr {
fn del_slice(&self, range: R) -> GResult<()> {
let r = range.as_range(self)?;
self.borrow_mut()?.drain(r);
Ok(())
}
}
pub trait Splay {
fn splay(&self, dst: &Arr) -> GResult<()>;
}
impl Splay for Arr {
fn splay(&self, dst: &Arr) -> GResult<()> {
dst.extend(self.iter())
}
}
impl Splay for Str {
fn splay(&self, dst: &Arr) -> GResult<()> {
dst.extend(self.iter())
}
}
impl Splay for Deque {
fn splay(&self, dst: &Arr) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.splay(dst),
Deque::Str(st) => st.splay(dst)
}
}
}
impl Splay for Val {
fn splay(&self, dst: &Arr) -> GResult<()> {
match *self {
Val::Arr(ref ar) => ar.splay(dst),
Val::Str(ref st) => st.splay(dst),
_ => bail!("attempted to splay {}", self.a_type_name())
}
}
}
impl<T> Splay for [T] where for<'a> &'a T: IntoVal {
fn splay(&self, dst: &Arr) -> GResult<()> {
dst.reserve(self.len())?;
for item in self {
dst.push(item)?;
}
Ok(())
}
}
impl<T> Splay for VecDeque<T> where for<'a> &'a T: IntoVal {
fn splay(&self, dst: &Arr) -> GResult<()> {
dst.reserve(self.len())?;
for item in self {
dst.push(item)?;
}
Ok(())
}
}
macro_rules! impl_splay_tuple {
($len:literal: $($t:ident $i:tt),+) => (
impl<$($t),+> Splay for ($($t,)+)
where
$( for<'a> &'a $t: IntoVal ),+
{
fn splay(&self, dst: &Arr) -> GResult<()> {
dst.reserve($len)?;
$(
dst.push(&(self.$i))?;
)+
Ok(())
}
}
);
}
impl_splay_tuple!( 1: A 0);
impl_splay_tuple!( 2: A 0, B 1);
impl_splay_tuple!( 3: A 0, B 1, C 2);
impl_splay_tuple!( 4: A 0, B 1, C 2, D 3);
impl_splay_tuple!( 5: A 0, B 1, C 2, D 3, E 4);
impl_splay_tuple!( 6: A 0, B 1, C 2, D 3, E 4, F 5);
impl_splay_tuple!( 7: A 0, B 1, C 2, D 3, E 4, F 5, G 6);
impl_splay_tuple!( 8: A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
impl_splay_tuple!( 9: A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
impl_splay_tuple!(10: A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
impl_splay_tuple!(11: A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
impl_splay_tuple!(12: A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11);
#[doc(hidden)]
#[macro_export]
macro_rules! try_arr_capacity {
(.. $splayed:expr) => (1);
($item:expr) => (1);
(.. $splayed:expr, $($token:tt)*) => (
1 + $crate::try_arr_capacity!($($token)*)
);
($item:expr, $($token:tt)*) => (
1 + $crate::try_arr_capacity!($($token)*)
);
}
#[doc(hidden)]
#[macro_export]
macro_rules! try_arr_clauses {
($arr:ident, .. $splayed:expr) => ({
use $crate::Splay;
match (&$splayed).splay(&$arr) {
Ok(()) => (),
Err(err) => break $crate::GResult::Err(err)
}
});
($arr:ident, $item:expr) => ({
match $arr.push($item) {
Ok(()) => (),
Err(err) => break $crate::GResult::Err(err)
}
});
($arr:ident, .. $splayed:expr, $($token:tt)*) => ({
$crate::try_arr_clauses!($arr, ..$splayed);
$crate::try_arr_clauses!($arr, $($token)*);
});
($arr:ident, $item:expr, $($token:tt)*) => ({
$crate::try_arr_clauses!($arr, $item);
$crate::try_arr_clauses!($arr, $($token)*);
});
}
#[macro_export]
macro_rules! try_arr {
($elem:expr; $n:expr) => (
$crate::arr_from_elem($elem, $n)
);
() => (
$crate::GResult::Ok($crate::arr())
);
($($token:tt)*) => (
{
loop {
let arr = $crate::arr_with_capacity(
$crate::try_arr_capacity!($($token)*)
);
$crate::try_arr_clauses!(arr, $($token)*);
break $crate::GResult::Ok(arr)
}
}
);
}
#[macro_export]
macro_rules! arr {
($elem:expr; $n:expr) => ($crate::try_arr![$elem; $n].unwrap());
($($token:tt)*) => ($crate::try_arr![$($token)*].unwrap());
}
#[doc(hidden)]
#[derive(Clone)]
pub enum StrStorage {
Str1(VecDeque<CharStorage<u8>>),
Str2(VecDeque<CharStorage<u16>>),
Str4(VecDeque<CharStorage<char>>)
}
impl StrStorage {
#[allow(dead_code)]
pub(crate) fn len(&self) -> usize {
match *self {
StrStorage::Str1(ref vec) => vec.len(),
StrStorage::Str2(ref vec) => vec.len(),
StrStorage::Str4(ref vec) => vec.len()
}
}
#[allow(dead_code)]
pub(crate) fn chars_eq(&self, other: &StrStorage) -> bool {
if self.len() != other.len() {
false
} else {
for i in 0 .. self.len() {
let self_ch = match *self {
StrStorage::Str1(ref vec) => vec[i].into_char(),
StrStorage::Str2(ref vec) => vec[i].into_char(),
StrStorage::Str4(ref vec) => vec[i].into_char()
};
let other_ch = match *other {
StrStorage::Str1(ref vec) => vec[i].into_char(),
StrStorage::Str2(ref vec) => vec[i].into_char(),
StrStorage::Str4(ref vec) => vec[i].into_char()
};
if self_ch != other_ch {
return false
}
}
true
}
}
fn widen(&mut self, new_width: usize) {
use StrStorage::*;
let new_self = match (self as &StrStorage, new_width) {
(&Str1(ref vec), 2) => {
Str2(VecDeque::from_iter(vec.iter().map(|ch| ch.widen())))
}
(&Str1(ref vec), 4) => {
Str4(VecDeque::from_iter(vec.iter().map(|ch| ch.widen())))
}
(&Str2(ref vec), 4) => {
Str4(VecDeque::from_iter(vec.iter().map(|ch| ch.widen())))
}
_ => panic!()
};
*self = new_self;
}
pub(crate) fn prepare_for_char(&mut self, ch: char) {
match (self as &StrStorage, ch as u32) {
(&StrStorage::Str1(_), ch) if ch > u16::MAX as u32 => self.widen(4),
(&StrStorage::Str1(_), ch) if ch > u8::MAX as u32 => self.widen(2),
(&StrStorage::Str2(_), ch) if ch > u16::MAX as u32 => self.widen(4),
_ => ()
}
}
fn prepare_for_chars(&mut self, other: &StrStorage) {
match (self as &StrStorage, other) {
(&StrStorage::Str1(_), StrStorage::Str4(_)) => self.widen(4),
(&StrStorage::Str1(_), StrStorage::Str2(_)) => self.widen(2),
(&StrStorage::Str2(_), StrStorage::Str4(_)) => self.widen(4),
_ => ()
}
}
pub(crate) fn append(&mut self, other: &StrStorage) {
self.prepare_for_chars(other);
match (self, other) {
(StrStorage::Str1(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
self_vec.extend(other_vec.iter().copied())
}
(StrStorage::Str2(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
for char_storage in other_vec.iter() {
self_vec.push_back(char_storage.widen())
}
}
(StrStorage::Str2(ref mut self_vec), StrStorage::Str2(ref other_vec)) => {
self_vec.extend(other_vec.iter().copied())
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
for char_storage in other_vec.iter() {
self_vec.push_back(char_storage.widen())
}
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str2(ref other_vec)) => {
for char_storage in other_vec.iter() {
self_vec.push_back(char_storage.widen())
}
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str4(ref other_vec)) => {
self_vec.extend(other_vec.iter().copied())
}
_ => unreachable!()
}
}
pub(crate) fn prepend(&mut self, other: &StrStorage) {
self.prepare_for_chars(other);
match (self, other) {
(StrStorage::Str1(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(*char_storage)
}
}
(StrStorage::Str2(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(char_storage.widen())
}
}
(StrStorage::Str2(ref mut self_vec), StrStorage::Str2(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(*char_storage)
}
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str1(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(char_storage.widen())
}
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str2(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(char_storage.widen())
}
}
(StrStorage::Str4(ref mut self_vec), StrStorage::Str4(ref other_vec)) => {
for char_storage in other_vec.iter().rev() {
self_vec.push_front(*char_storage)
}
}
_ => unreachable!()
}
}
}
macro_rules! with_str_storage {
($storage_expr:expr, $vec_name:ident, ($($ch_name:ident),*), $body_expr:expr) => (
{
match $storage_expr {
StrStorage::Str1(ref $vec_name) => {
$(let $ch_name = CharStorage::<u8>::from_char(*$ch_name);)*
$body_expr
}
StrStorage::Str2(ref $vec_name) => {
$(let $ch_name = CharStorage::<u16>::from_char(*$ch_name);)*
$body_expr
}
StrStorage::Str4(ref $vec_name) => {
$(let $ch_name = CharStorage::<char>::from_char(*$ch_name);)*
$body_expr
}
}
}
);
}
macro_rules! with_str_storage_mut {
($storage_expr:expr, $vec_name:ident, ($($ch_name:ident),*), $body_expr:expr) => (
{
let storage_ref: &mut StrStorage = $storage_expr;
$(storage_ref.prepare_for_char(*$ch_name);)*
match storage_ref {
StrStorage::Str1(ref mut $vec_name) => {
$(let $ch_name = CharStorage::<u8>::from_char(*$ch_name);)*
$body_expr
}
StrStorage::Str2(ref mut $vec_name) => {
$(let $ch_name = CharStorage::<u16>::from_char(*$ch_name);)*
$body_expr
}
StrStorage::Str4(ref mut $vec_name) => {
$(let $ch_name = CharStorage::<char>::from_char(*$ch_name);)*
$body_expr
}
}
}
);
}
#[doc(hidden)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct CharStorage<T: CoerceFromChar + Into<u32> + Copy + Eq + Ord>(T);
impl<T: CoerceFromChar + Into<u32> + Copy + Eq + Ord> CharStorage<T> {
pub(crate) fn into_char(&self) -> char {
let u: u32 = self.0.into();
char::try_from(u).unwrap()
}
pub(crate) fn from_char(ch: char) -> Self {
CharStorage(T::coerce_from_char(ch))
}
}
impl<T: Hash + Copy + CoerceFromChar + Into<u32> + Eq + Ord> Hash for CharStorage<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
#[doc(hidden)]
pub trait CoerceFromChar: Sized {
fn coerce_from_char(arg: char) -> Self;
}
impl CoerceFromChar for u8 {
fn coerce_from_char(arg: char) -> u8 {
arg as u32 as u8
}
}
impl CoerceFromChar for u16 {
fn coerce_from_char(arg: char) -> u16 {
arg as u32 as u16
}
}
impl CoerceFromChar for char {
fn coerce_from_char(arg: char) -> char {
arg
}
}
pub(crate) trait Widen<T> {
fn widen(self) -> T;
}
impl Widen<CharStorage<u16>> for CharStorage<u8> {
fn widen(self) -> CharStorage<u16> {
CharStorage(self.0 as u16)
}
}
impl Widen<CharStorage<char>> for CharStorage<u8> {
fn widen(self) -> CharStorage<char> {
CharStorage(self.0 as char)
}
}
impl Widen<CharStorage<char>> for CharStorage<u16> {
fn widen(self) -> CharStorage<char> {
CharStorage(char::try_from(self.0 as u32).unwrap())
}
}
pub struct Str {
header: Header,
storage: RefCell<StrStorage>
}
impl Allocate for Str {
fn header(&self) -> &Header {
&self.header
}
fn visit_raws<V: Visitor>(&self, _visitor: &mut V) {
}
fn clear_raws(&self) {
}
fn owned_memory_usage(&self) -> usize {
match *self.borrow() {
StrStorage::Str1(ref vec) => (vec.capacity() + 1),
StrStorage::Str2(ref vec) => (vec.capacity() + 1) * 2,
StrStorage::Str4(ref vec) => (vec.capacity() + 1) * 4
}
}
}
#[macro_export]
macro_rules! str {
($($arg:tt)*) => (
{
use std::fmt::Write;
let mut st = glsp::str();
write!(st, $($arg)*).unwrap();
st
}
);
}
impl Str {
pub(crate) fn new() -> Str {
Str {
header: Header::new(),
storage: RefCell::new(StrStorage::Str1(VecDeque::new()))
}
}
pub(crate) fn from_rust_str(st: &str) -> Str {
let max_char = st.chars().max().unwrap_or(0 as char);
let storage = match max_char as u32 {
0 ..= 0xff => {
StrStorage::Str1(VecDeque::from_iter(st.chars().map(|ch| {
CharStorage::<u8>::from_char(ch)
})))
}
0x100 ..= 0xffff => {
StrStorage::Str2(VecDeque::from_iter(st.chars().map(|ch| {
CharStorage::<u16>::from_char(ch)
})))
}
_ => {
StrStorage::Str4(VecDeque::from_iter(st.chars().map(|ch| {
CharStorage::<char>::from_char(ch)
})))
}
};
Str {
header: Header::new(),
storage: RefCell::new(storage)
}
}
pub(crate) fn from_iter<T>(iter: T) -> GResult<Str>
where
T: IntoIterator,
T::Item: IntoElement<char>
{
use StrStorage::*;
let mut storage = Str1(VecDeque::new());
for item in iter.into_iter() {
let ch = item.into_element()?;
storage.prepare_for_char(ch);
match storage {
Str1(ref mut vec) => vec.push_back(CharStorage::<u8>::from_char(ch)),
Str2(ref mut vec) => vec.push_back(CharStorage::<u16>::from_char(ch)),
Str4(ref mut vec) => vec.push_back(CharStorage::<char>::from_char(ch))
}
}
Ok(Str {
header: Header::new(),
storage: RefCell::new(storage)
})
}
pub(crate) fn with_capacity(capacity: usize) -> Str {
Str {
header: Header::new(),
storage: RefCell::new(StrStorage::Str1(VecDeque::with_capacity(capacity)))
}
}
pub(crate) fn to_rust_string(&self) -> String {
use StrStorage::*;
match *self.borrow() {
Str1(ref vec) => String::from_iter(vec.iter().map(|&ch| ch.into_char())),
Str2(ref vec) => String::from_iter(vec.iter().map(|&ch| ch.into_char())),
Str4(ref vec) => String::from_iter(vec.iter().map(|&ch| ch.into_char()))
}
}
pub(crate) fn to_escaped_string(&self) -> String {
with_str_storage!(&*self.borrow(), vec, (), {
let mut builder = String::new();
for ch in vec.iter().map(|item| item.into_char()) {
match ch {
'\n' => builder.push_str("\\n"),
'\t' => builder.push_str("\\t"),
'\r' => builder.push_str("\\r"),
'\\' => builder.push_str("\\\\"),
'"' => builder.push_str("\\\""),
'\0' => builder.push_str("\\0"),
'{' => builder.push_str("{{"),
'}' => builder.push_str("}}"),
ch => {
if (ch as u32) < 32 {
builder.push_str("\\x");
builder.push(char::from_digit((ch as u32) / 16, 2).unwrap());
builder.push(char::from_digit((ch as u32) & 0xf, 16).unwrap());
} else {
builder.push(ch)
}
}
}
}
builder
})
}
pub fn shallow_clone(&self) -> Root<Str> {
glsp::str_from_iter(self.iter()).unwrap()
}
pub fn access_giter(st: &Root<Str>, giter: &Root<GIter>) -> Root<GIter> {
glsp::giter(GIterState::AccessStr(st.to_raw(), giter.to_raw()))
}
pub fn push_rust_str(&self, s: &str) -> GResult<()> {
let mut max_ch = '\0';
let mut ch_count = 0;
for ch in s.chars() {
if ch > max_ch {
max_ch = ch;
}
ch_count += 1;
}
self.borrow_mut_with_capacity_guard(|storage| {
storage.prepare_for_char(max_ch);
with_str_storage_mut!(storage, vec, (), {
vec.reserve(ch_count);
for ch in s.chars() {
vec.push_back(CharStorage::from_char(ch));
}
});
Ok(())
})
}
fn borrow(&self) -> Ref<StrStorage> {
self.storage.borrow()
}
fn borrow_mut(&self) -> GResult<RefMut<StrStorage>> {
ensure!(!self.header.frozen(), "attempted to mutate a frozen str");
match self.storage.try_borrow_mut() {
Ok(ref_mut) => Ok(ref_mut),
Err(_) => bail!("attempted to mutate a borrowed str")
}
}
fn memory_usage_barrier(&self, prev_usage: usize, cur_usage: usize) {
with_heap(|heap| heap.memory_usage_barrier(self, prev_usage, cur_usage));
}
fn borrow_mut_with_capacity_guard<R, F>(&self, f: F) -> GResult<R>
where
F: FnOnce(&mut RefMut<StrStorage>) -> GResult<R>
{
let prev_usage = self.owned_memory_usage();
let _guard = Guard::new(|| {
let cur_usage = self.owned_memory_usage();
if prev_usage != cur_usage {
self.memory_usage_barrier(prev_usage, cur_usage);
}
});
let mut ref_mut = self.borrow_mut()?;
f(&mut ref_mut)
}
}
impl fmt::Write for Root<Str> {
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
match self.push_rust_str(s) {
Ok(()) => Ok(()),
Err(_) => Err(fmt::Error::default())
}
}
}
impl PartialEq<Str> for Str {
fn eq(&self, other: &Str) -> bool {
self.iter().eq(other.iter())
}
}
impl Eq for Str { }
impl PartialOrd<Str> for Str {
fn partial_cmp(&self, other: &Str) -> Option<Ordering> {
Some(self.iter().cmp(other.iter()))
}
}
impl Ord for Str {
fn cmp(&self, other: &Str) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl Hash for Str {
fn hash<H: Hasher>(&self, state: &mut H) {
match *self.borrow() {
StrStorage::Str1(ref vec) => vec.hash(state),
StrStorage::Str2(ref vec) => vec.hash(state),
StrStorage::Str4(ref vec) => vec.hash(state)
}
}
}
impl DequeOps for Str {
type Element = char;
type Item = char;
fn freeze(&self) {
self.header.freeze()
}
fn deep_freeze(&self) {
self.freeze();
}
fn is_frozen(&self) -> bool {
self.header.frozen()
}
fn is_deep_frozen(&self) -> bool {
self.is_frozen()
}
fn can_mutate(&self) -> bool {
(!self.header.frozen()) && self.storage.try_borrow_mut().is_ok()
}
fn sort(&self) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.make_contiguous().sort();
Ok(())
})
}
fn sort_by<F>(&self, mut f: F) -> GResult<()>
where
F: FnMut(&char, &char) -> GResult<Ordering>
{
let mut vec = SmallVec::<[char; 128]>::from_iter(self.iter());
let mut error: Option<GError> = None;
vec.sort_by(|a, b| {
if error.is_some() {
return Ordering::Equal
}
match f(a, b) {
Ok(ordering) => ordering,
Err(err) => {
error = Some(err);
Ordering::Equal
}
}
});
match error {
Some(error) => Err(error),
None => {
for (i, ch) in vec.drain(..).enumerate() {
self.set(i, ch).unwrap();
}
Ok(())
}
}
}
fn push<C: IntoElement<char>>(&self, ch: C) -> GResult<()> {
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec.push_back(ch);
});
Ok(())
})
}
fn pop<R: FromElement<char>>(&self) -> GResult<R> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
match vec.pop_back() {
Some(char_storage) => R::from_element(&char_storage.into_char()),
None => bail!("attempted to pop a char from an empty str")
}
})
}
fn push_start<C: IntoElement<char>>(&self, ch: C) -> GResult<()> {
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec.push_front(ch);
});
Ok(())
})
}
fn pop_start<R: FromElement<char>>(&self) -> GResult<R> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
match vec.pop_front() {
Some(char_storage) => R::from_element(&char_storage.into_char()),
None => bail!("attempted to pop from the start of an empty str")
}
})
}
fn grow<C: IntoElement<char>>(&self, start_to_add: usize,
end_to_add: usize, fill: C) -> GResult<()> {
let fill = fill.into_element()?;
let fill = &fill;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (fill), {
generic_grow(vec, start_to_add, end_to_add, fill);
});
Ok(())
})
}
fn shrink(&self, start_to_remove: usize, end_to_remove: usize) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
generic_shrink(vec, start_to_remove, end_to_remove)
})
}
fn append(&self, other: &Str) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|self_storage| {
self_storage.append(&other.borrow());
Ok(())
})
}
fn prepend(&self, other: &Str) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|self_storage| {
self_storage.prepend(&other.borrow());
Ok(())
})
}
fn resize<C: IntoElement<char>>(&self, new_len: usize, ch: C) -> GResult<()> {
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec.resize(new_len, ch);
});
Ok(())
})
}
fn rotate_left(&self, mid: usize) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.rotate_left(mid);
Ok(())
})
}
fn rotate_right(&self, k: usize) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.rotate_right(k);
Ok(())
})
}
fn swap<I1, I2>(&self, i_index: I1, j_index: I2) -> GResult<()>
where
I1: DequeIndex,
I2: DequeIndex
{
let i = i_index.as_usize(self)?;
let j = j_index.as_usize(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.swap(i, j);
Ok(())
})
}
fn capacity(&self) -> usize {
with_str_storage!(&*self.borrow(), vec, (), {
vec.capacity()
})
}
fn len(&self) -> usize {
with_str_storage!(&*self.borrow(), vec, (), {
vec.len()
})
}
fn reserve_exact(&self, additional: usize) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.reserve_exact(additional);
Ok(())
})
}
fn reserve(&self, additional: usize) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (), {
vec.reserve(additional);
});
Ok(())
})
}
fn shrink_to_fit(&self) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (), {
vec.shrink_to_fit();
});
Ok(())
})
}
fn truncate(&self, len: usize) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.truncate(len);
Ok(())
})
}
fn clear(&self) -> GResult<()> {
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.clear();
Ok(())
})
}
fn contains<C: IntoElement<char>>(&self, ch: C) -> GResult<bool> {
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
Ok(vec.contains(&ch))
})
})
}
#[doc(hidden)]
fn lock(&self) -> Lock {
Lock::Str(self.borrow())
}
fn extend<I, C>(&self, source: I) -> GResult<()>
where
I: IntoIterator<Item = C>,
C: IntoElement<char>
{
for ch in source.into_iter() {
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec.push_back(ch);
});
Ok(())
})?;
}
Ok(())
}
}
impl<I: DequeIndex> DequeAccess<I> for Str {
fn get<R: FromElement<char>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
with_str_storage!(&*self.borrow(), vec, (), {
R::from_element(&vec[i].into_char())
})
}
fn set<C: IntoElement<char>>(&self, index: I, ch: C) -> GResult<()> {
let i = index.as_usize(self)?;
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec[i] = ch;
});
Ok(())
})
}
fn insert<C: IntoElement<char>>(&self, index: I, ch: C) -> GResult<()> {
let i = index.as_usize_excluded(self)?;
let ch = ch.into_element()?;
let ch = &ch;
self.borrow_mut_with_capacity_guard(|storage| {
with_str_storage_mut!(storage, vec, (ch), {
vec.insert(i, ch);
});
Ok(())
})
}
fn del(&self, index: I) -> GResult<()> {
let i = index.as_usize(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.remove(i).unwrap();
});
Ok(())
}
fn remove<R: FromElement<char>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
R::from_element(&vec.remove(i).unwrap().into_char())
})
}
fn swap_remove<R: FromElement<char>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
R::from_element(&vec.swap_remove_back(i).unwrap().into_char())
})
}
fn swap_remove_start<R: FromElement<char>>(&self, index: I) -> GResult<R> {
let i = index.as_usize(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
R::from_element(&vec.swap_remove_front(i).unwrap().into_char())
})
}
}
impl<I: DequeIndex, R: DequeRange<I> + Debug> DequeAccessRange<I, R> for Str {
fn del_slice(&self, range: R) -> GResult<()> {
let r = range.as_range(self)?;
with_str_storage_mut!(&mut *self.borrow_mut()?, vec, (), {
vec.drain(r);
});
Ok(())
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum Deque {
Arr(Root<Arr>),
Str(Root<Str>)
}
impl Deque {
#[doc(hidden)]
pub fn new(base: &Deque) -> Deque {
match base {
Deque::Arr(_) => Deque::Arr(glsp::arr()),
Deque::Str(_) => Deque::Str(glsp::str())
}
}
#[doc(hidden)]
pub fn with_capacity(base: &Deque, cap: usize) -> Deque {
match base {
Deque::Arr(_) => Deque::Arr(glsp::arr_with_capacity(cap)),
Deque::Str(_) => Deque::Str(glsp::str_with_capacity(cap))
}
}
#[doc(hidden)]
pub fn from_iter<T>(base: &Deque, source: T) -> GResult<Deque>
where
T: IntoIterator,
T::Item: IntoVal + IntoElement<char>
{
match base {
Deque::Arr(_) => Ok(Deque::Arr(glsp::arr_from_iter(source)?)),
Deque::Str(_) => Ok(Deque::Str(glsp::str_from_iter(source)?))
}
}
#[doc(hidden)]
pub fn fill(&self) -> Val {
match self {
Deque::Arr(_) => Val::Nil,
Deque::Str(_) => Val::Char('\0')
}
}
pub fn same(&self, other: &Deque) -> bool {
match (self.clone(), other.clone()) {
(Deque::Arr(a0), Deque::Arr(a1)) => Val::Arr(a0).same(&Val::Arr(a1)),
(Deque::Str(s0), Deque::Str(s1)) => Val::Str(s0).same(&Val::Str(s1)),
_ => false
}
}
pub fn shallow_clone(&self) -> Deque {
match self {
Deque::Arr(ar) => Deque::Arr(ar.shallow_clone()),
Deque::Str(st) => Deque::Str(st.shallow_clone())
}
}
pub fn deep_clone(&self) -> GResult<Deque> {
match self {
Deque::Arr(ar) => Ok(Deque::Arr(ar.deep_clone()?)),
Deque::Str(st) => Ok(Deque::Str(st.shallow_clone()))
}
}
pub fn access_giter(&self, giter: &Root<GIter>) -> Root<GIter> {
match self {
Deque::Arr(ar) => Arr::access_giter(ar, giter),
Deque::Str(st) => Str::access_giter(st, giter)
}
}
}
impl DequeOps for Deque {
type Element = Slot;
type Item = Val;
fn freeze(&self) {
match self {
Deque::Arr(ar) => ar.freeze(),
Deque::Str(st) => st.freeze()
}
}
fn deep_freeze(&self) {
match self {
Deque::Arr(ar) => ar.deep_freeze(),
Deque::Str(st) => st.deep_freeze()
}
}
fn is_frozen(&self) -> bool {
match self {
Deque::Arr(ar) => ar.is_frozen(),
Deque::Str(st) => st.is_frozen()
}
}
fn is_deep_frozen(&self) -> bool {
match self {
Deque::Arr(ar) => ar.is_deep_frozen(),
Deque::Str(st) => st.is_deep_frozen()
}
}
fn sort(&self) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.sort(),
Deque::Str(st) => st.sort()
}
}
fn sort_by<F>(&self, mut f: F) -> GResult<()>
where
F: FnMut(&Val, &Val) -> GResult<Ordering>
{
match self {
Deque::Arr(ar) => ar.sort_by(f),
Deque::Str(st) => st.sort_by(|c0, c1| f(&Val::Char(*c0), &Val::Char(*c1)))
}
}
fn can_mutate(&self) -> bool {
match self {
Deque::Arr(ar) => ar.can_mutate(),
Deque::Str(st) => st.can_mutate()
}
}
fn swap<I1, I2>(&self, i: I1, j: I2) -> GResult<()> where I1: DequeIndex, I2: DequeIndex {
match self {
Deque::Arr(ar) => ar.swap(i, j),
Deque::Str(st) => st.swap(i, j)
}
}
fn len(&self) -> usize {
match self {
Deque::Arr(ar) => ar.len(),
Deque::Str(st) => st.len()
}
}
fn contains<V: IntoElement<Slot>>(&self, v: V) -> GResult<bool> {
match self {
Deque::Arr(ar) => ar.contains(v),
Deque::Str(st) => st.contains(v.into_element()?)
}
}
#[doc(hidden)]
fn lock(&self) -> Lock {
match self {
Deque::Arr(ar) => ar.lock(),
Deque::Str(st) => st.lock()
}
}
fn push<V: IntoElement<Slot>>(&self, v: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.push(v),
Deque::Str(st) => st.push(v.into_element()?)
}
}
fn pop<R: FromElement<Slot>>(&self) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.pop(),
Deque::Str(st) => R::from_element(&st.pop()?)
}
}
fn push_start<V: IntoElement<Slot>>(&self, v: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.push_start(v),
Deque::Str(st) => st.push_start(v.into_element()?)
}
}
fn pop_start<R: FromElement<Slot>>(&self) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.pop_start(),
Deque::Str(st) => R::from_element(&st.pop_start()?)
}
}
fn grow<V: IntoElement<Slot>>(&self, start: usize, end: usize, fill: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.grow(start, end, fill),
Deque::Str(st) => st.grow(start, end, fill.into_element()?)
}
}
fn shrink(&self, start: usize, end: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.shrink(start, end),
Deque::Str(st) => st.shrink(start, end)
}
}
fn append(&self, _other: &Self) -> GResult<()> {
todo!("this should accept &T: DequeOps, rather than &Self")
}
fn prepend(&self, _other: &Self) -> GResult<()> {
todo!("this should accept &T: DequeOps, rather than &Self")
}
fn resize<V: IntoElement<Slot>>(&self, new_len: usize, fill: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.resize(new_len, fill),
Deque::Str(st) => st.resize(new_len, fill.into_element()?)
}
}
fn rotate_left(&self, mid: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.rotate_left(mid),
Deque::Str(st) => st.rotate_left(mid)
}
}
fn rotate_right(&self, k: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.rotate_right(k),
Deque::Str(st) => st.rotate_right(k)
}
}
fn capacity(&self) -> usize {
match self {
Deque::Arr(ar) => ar.capacity(),
Deque::Str(st) => st.capacity()
}
}
fn reserve_exact(&self, additional: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.reserve_exact(additional),
Deque::Str(st) => st.reserve_exact(additional)
}
}
fn reserve(&self, additional: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.reserve(additional),
Deque::Str(st) => st.reserve(additional)
}
}
fn shrink_to_fit(&self) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.shrink_to_fit(),
Deque::Str(st) => st.shrink_to_fit()
}
}
fn truncate(&self, len: usize) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.truncate(len),
Deque::Str(st) => st.truncate(len)
}
}
fn clear(&self) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.clear(),
Deque::Str(st) => st.clear()
}
}
fn extend<I, C>(&self, source: I) -> GResult<()>
where
I: IntoIterator<Item = C>,
C: IntoElement<Slot>
{
match self {
Deque::Arr(ar) => ar.extend(source),
Deque::Str(st) => st.extend(source.into_iter().map(|c| c.into_element().unwrap()))
}
}
}
impl<I: DequeIndex> DequeAccess<I> for Deque {
fn get<R: FromElement<Slot>>(&self, i: I) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.get(i),
Deque::Str(st) => R::from_element(&st.get(i)?)
}
}
fn set<V: IntoElement<Slot>>(&self, i: I, v: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.set(i, v),
Deque::Str(st) => st.set(i, v.into_element()?)
}
}
fn insert<V: IntoElement<Slot>>(&self, i: I, v: V) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.insert(i, v),
Deque::Str(st) => st.insert(i, v.into_element()?)
}
}
fn del(&self, i: I) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.del(i),
Deque::Str(st) => st.del(i)
}
}
fn remove<R: FromElement<Slot>>(&self, i: I) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.remove(i),
Deque::Str(st) => R::from_element(&st.remove(i)?)
}
}
fn swap_remove<R: FromElement<Slot>>(&self, i: I) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.swap_remove(i),
Deque::Str(st) => R::from_element(&st.swap_remove(i)?)
}
}
fn swap_remove_start<R: FromElement<Slot>>(&self, i: I) -> GResult<R> {
match self {
Deque::Arr(ar) => ar.swap_remove_start(i),
Deque::Str(st) => R::from_element(&st.swap_remove_start(i)?)
}
}
}
impl<I, R> DequeAccessRange<I, R> for Deque
where
I: DequeIndex,
R: DequeRange<I> + Debug
{
fn del_slice(&self, r: R) -> GResult<()> {
match self {
Deque::Arr(ar) => ar.del_slice(r),
Deque::Str(st) => st.del_slice(r)
}
}
}
#[doc(hidden)]
pub enum Lock<'a> {
Arr(Ref<'a, VecDeque<Slot>>),
Str(Ref<'a, StrStorage>)
}
impl<'a> Clone for Lock<'a> {
fn clone(&self) -> Lock<'a> {
match self {
Lock::Arr(rf) => Lock::Arr(Ref::clone(rf)),
Lock::Str(rf) => Lock::Str(Ref::clone(rf))
}
}
}
pub struct IterDeque<'a, T: DequeAccess<usize>> {
deq: &'a T,
_lock: Lock<'a>,
start_index: usize,
past_the_end_index: usize
}
impl<'a, T: DequeAccess<usize>,> IterDeque<'a, T> {
fn from(deq: &'a T) -> IterDeque<'a, T> {
let lock = deq.lock();
IterDeque {
deq,
_lock: lock,
start_index: 0,
past_the_end_index: deq.len()
}
}
}
impl<'a, T: DequeAccess<usize>> Iterator for IterDeque<'a, T> {
type Item = T::Item;
fn next(&mut self) -> Option<T::Item> {
if self.start_index < self.past_the_end_index {
let i = self.start_index;
self.start_index += 1;
Some(self.deq.get(i).unwrap())
} else {
None
}
}
fn nth(&mut self, n: usize) -> Option<T::Item> {
self.start_index += n;
self.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.past_the_end_index.saturating_sub(self.start_index);
(size, Some(size))
}
}
impl<'a, T: DequeAccess<usize>> DoubleEndedIterator for IterDeque<'a, T> {
fn next_back(&mut self) -> Option<T::Item> {
if self.past_the_end_index > self.start_index {
let i = self.past_the_end_index - 1;
self.past_the_end_index -= 1;
Some(self.deq.get(i).unwrap())
} else {
None
}
}
}
impl<'a, T: DequeAccess<usize>> ExactSizeIterator for IterDeque<'a, T> { }
impl<'a> IntoIterator for &'a Arr {
type Item = Val;
type IntoIter = IterDeque<'a, Arr>;
fn into_iter(self) -> IterDeque<'a, Arr> {
IterDeque::from(self)
}
}
impl<'a> IntoIterator for &'a Root<Arr> {
type Item = Val;
type IntoIter = IterDeque<'a, Arr>;
fn into_iter(self) -> IterDeque<'a, Arr> {
IterDeque::from(&**self)
}
}
impl<'a> IntoIterator for &'a mut Root<Arr> {
type Item = Val;
type IntoIter = IterDeque<'a, Arr>;
fn into_iter(self) -> IterDeque<'a, Arr> {
IterDeque::from(&**self)
}
}
impl<'a> IntoIterator for &'a Str {
type Item = char;
type IntoIter = IterDeque<'a, Str>;
fn into_iter(self) -> IterDeque<'a, Str> {
IterDeque::from(self)
}
}
impl<'a> IntoIterator for &'a Root<Str> {
type Item = char;
type IntoIter = IterDeque<'a, Str>;
fn into_iter(self) -> IterDeque<'a, Str> {
IterDeque::from(&**self)
}
}
impl<'a> IntoIterator for &'a mut Root<Str> {
type Item = char;
type IntoIter = IterDeque<'a, Str>;
fn into_iter(self) -> IterDeque<'a, Str> {
IterDeque::from(&**self)
}
}
pub struct IterDequeTo<'a, T: DequeAccess<usize>, R: FromElement<T::Element>> {
deq: &'a T,
_lock: Lock<'a>,
start_index: usize,
past_the_end_index: usize,
phantom: PhantomData<R>
}
impl<'a, T: DequeAccess<usize>, R: FromElement<T::Element>> IterDequeTo<'a, T, R> {
fn from(deq: &'a T) -> IterDequeTo<'a, T, R> {
let lock = deq.lock();
IterDequeTo {
deq,
_lock: lock,
start_index: 0,
past_the_end_index: deq.len(),
phantom: PhantomData
}
}
}
impl<'a, T: DequeAccess<usize>, R: FromElement<T::Element>> Iterator for IterDequeTo<'a, T, R> {
type Item = GResult<R>;
fn next(&mut self) -> Option<GResult<R>> {
if self.start_index < self.past_the_end_index {
let i = self.start_index;
self.start_index += 1;
Some(self.deq.get(i))
} else {
None
}
}
fn nth(&mut self, n: usize) -> Option<GResult<R>> {
self.start_index += n;
self.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.past_the_end_index.saturating_sub(self.start_index);
(size, Some(size))
}
}
impl<'a, T: DequeAccess<usize>, R: FromElement<T::Element>> DoubleEndedIterator for IterDequeTo<'a, T, R> {
fn next_back(&mut self) -> Option<GResult<R>> {
if self.past_the_end_index > self.start_index {
let i = self.past_the_end_index - 1;
self.past_the_end_index -= 1;
Some(self.deq.get(i))
} else {
None
}
}
}
impl<'a, T: DequeAccess<usize>, R: FromElement<T::Element>> ExactSizeIterator for IterDequeTo<'a, T, R> { }
pub struct Tab {
header: Header,
map: RefCell<FnvHashMap<Slot, Slot>>
}
impl Allocate for Tab {
fn header(&self) -> &Header {
&self.header
}
fn visit_raws<V: Visitor>(&self, visitor: &mut V) {
for (internal_key, internal_value) in self.map.borrow().iter() {
visitor.visit_slot(internal_key);
visitor.visit_slot(internal_value);
}
}
fn clear_raws(&self) {
self.map.borrow_mut().clear()
}
fn owned_memory_usage(&self) -> usize {
let cap = self.map.borrow().capacity();
let buckets = if cap < 8 {
cap + 1
} else {
(cap * 8) / 7
};
buckets.next_power_of_two() * (1 + size_of::<(Slot, Slot)>())
}
}
#[macro_export]
macro_rules! try_tab {
() => ($crate::GResult::Ok($crate::tab()));
($(($key:expr, $value:expr),)* ..$base:expr) => (
{
loop {
let tab = $base.shallow_clone();
$(
if let Err(err) = tab.set($key, $value) {
break $crate::GResult::Err(err)
}
)*
break $crate::GResult::Ok(tab)
}
}
);
($(($key:expr, $value:expr),)*) => (
{
loop {
let tab = $crate::tab();
$(
if let Err(err) = tab.set($key, $value) {
break $crate::GResult::Err(err)
}
)*
break $crate::GResult::Ok(tab)
}
}
);
($(($key:expr, $value:expr)),*) => (
$crate::try_tab! {
$($key => $value,)*
}
);
}
#[macro_export]
macro_rules! tab {
() => ($crate::try_tab!{}.unwrap());
($(($key:expr, $value:expr),)* ..$base:expr) => (
$crate::try_tab! {
$(($key, $value),)*
..$base
}.unwrap()
);
($(($key:expr, $value:expr),)*) => (
$crate::try_tab! {
$(($key, $value),)*
}.unwrap()
);
($(($key:expr, $value:expr)),*) => (
$crate::try_tab! {
$(($key, $value),)*
}.unwrap()
);
}
impl Tab {
pub(crate) fn new() -> Tab {
Tab {
header: Header::new(),
map: RefCell::new(FnvHashMap::default())
}
}
pub(crate) fn from_iter<T, K, V>(t: T) -> GResult<Tab>
where
T: IntoIterator<Item = (K, V)>,
K: IntoVal,
V: IntoVal
{
let iter = t.into_iter();
let mut map = FnvHashMap::with_capacity_and_hasher(iter.size_hint().0, Default::default());
for (key, value) in iter {
map.insert(key.into_slot()?, value.into_slot()?);
}
Ok(Tab {
header: Header::new(),
map: RefCell::new(map)
})
}
pub(crate) fn with_capacity(capacity: usize) -> Tab {
Tab {
header: Header::new(),
map: RefCell::new(FnvHashMap::with_capacity_and_hasher(capacity, Default::default()))
}
}
pub(crate) fn borrow(&self) -> Ref<FnvHashMap<Slot, Slot>> {
self.map.borrow()
}
pub(crate) fn borrow_mut(&self) -> GResult<RefMut<FnvHashMap<Slot, Slot>>> {
ensure!(!self.header.frozen(), "attempted to mutate a frozen tab");
match self.map.try_borrow_mut() {
Ok(ref_mut) => Ok(ref_mut),
Err(_) => bail!("attempted to mutate a borrowed tab")
}
}
pub fn shallow_clone(&self) -> Root<Tab> {
glsp::tab_from_iter(self.entries().iter()).unwrap()
}
pub fn deep_clone(&self) -> GResult<Root<Tab>> {
let tab = glsp::tab_with_capacity(self.len());
for (k, v) in self.entries().iter() {
tab.set(k.deep_clone()?, v.deep_clone()?)?;
}
Ok(tab)
}
pub fn try_eq(&self, other: &Tab) -> GResult<bool> {
if self.len() != other.len() {
return Ok(false)
}
for (k0, v0) in self.entries().iter() {
let v1: Option<Val> = other.get_if_present(&k0).unwrap();
if v1.is_none() || !v1.unwrap().try_eq(&v0)? {
return Ok(false)
}
}
Ok(true)
}
#[allow(dead_code)]
fn write_barrier_val(&self, val: &Val) {
with_heap(|heap| heap.write_barrier_val(self, val));
}
fn write_barrier_slot(&self, slot: &Slot) {
with_heap(|heap| heap.write_barrier_slot(self, slot));
}
fn memory_usage_barrier(&self, prev_usage: usize, cur_usage: usize) {
with_heap(|heap| heap.memory_usage_barrier(self, prev_usage, cur_usage));
}
fn borrow_mut_with_capacity_guard<R, F>(&self, f: F) -> GResult<R>
where
F: FnOnce(&mut RefMut<FnvHashMap<Slot, Slot>>) -> GResult<R>
{
let prev_usage = self.owned_memory_usage();
let _guard = Guard::new(|| {
let cur_usage = self.owned_memory_usage();
if prev_usage != cur_usage {
self.memory_usage_barrier(prev_usage, cur_usage);
}
});
let mut ref_mut = self.borrow_mut()?;
f(&mut ref_mut)
}
pub fn get<K: IntoVal, V: FromVal>(&self, key: K) -> GResult<V> {
let key = key.into_slot()?;
match self.borrow().get(&key) {
Some(value) => V::from_slot(value),
None => bail!("missing tab field {:?}", key)
}
}
pub fn get_if_present<K: IntoVal, V: FromVal>(&self, key: K) -> GResult<Option<V>> {
match self.borrow().get(&key.into_slot()?) {
Some(value) => Ok(Some(V::from_slot(value)?)),
None => Ok(None)
}
}
pub fn set<K, V>(&self, key: K, value: V) -> GResult<()>
where
K: IntoVal,
V: IntoVal
{
let key = key.into_slot()?;
let value = value.into_slot()?;
self.borrow_mut_with_capacity_guard(|map| {
self.write_barrier_slot(&key);
self.write_barrier_slot(&value);
map.insert(key, value);
Ok(())
})
}
pub fn set_if_present<K, V>(&self, key: K, value: V) -> GResult<bool>
where
K: IntoVal,
V: IntoVal
{
let key = key.into_slot()?;
let value = value.into_slot()?;
self.borrow_mut_with_capacity_guard(|map| {
match map.get_mut(&key) {
Some(dst_value) => {
self.write_barrier_slot(&key);
self.write_barrier_slot(&value);
*dst_value = value;
Ok(true)
}
None => Ok(false)
}
})
}
pub fn has<K: IntoVal>(&self, key: K) -> GResult<bool> {
let key = key.into_slot()?;
Ok(self.borrow().contains_key(&key))
}
pub fn del<K: IntoVal>(&self, key: K) -> GResult<()> {
let key = key.into_slot()?;
match self.borrow_mut()?.remove(&key) {
Some(_) => Ok(()),
None => bail!("attempted to delete nonexistent tab field {}", key)
}
}
pub fn del_if_present<K: IntoVal>(&self, key: K) -> GResult<bool> {
let key = key.into_slot()?;
Ok(self.borrow_mut()?.remove(&key).is_some())
}
pub fn remove<K: IntoVal, V: FromVal>(&self, key: K) -> GResult<V> {
let key = key.into_slot()?;
match self.borrow_mut()?.remove(&key) {
Some(value) => V::from_slot(&value),
None => bail!("attempted to remove nonexistent tab field {}", key)
}
}
pub fn remove_if_present<K: IntoVal, V: FromVal>(&self, key: K) -> GResult<Option<V>> {
let key = key.into_slot()?;
match self.borrow_mut()?.remove(&key) {
Some(value) => Ok(Some(V::from_slot(&value)?)),
None => Ok(None)
}
}
pub fn len(&self) -> usize {
self.borrow().len()
}
pub fn capacity(&self) -> usize {
self.borrow().capacity()
}
pub fn reserve(&self, additional: usize) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|map| {
map.reserve(additional);
Ok(())
})
}
pub fn shrink_to_fit(&self) -> GResult<()> {
self.borrow_mut_with_capacity_guard(|map| {
map.shrink_to_fit();
Ok(())
})
}
pub fn clear(&self) -> GResult<()> {
self.borrow_mut()?.clear();
Ok(())
}
pub fn entries<'a>(&'a self) -> TabEntries<'a> {
TabEntries(self.borrow())
}
pub fn gkeys(&self) -> Root<GIter> {
let arr = glsp::arr_with_capacity(self.len());
for key in self.entries().keys_to::<Slot>() {
arr.push(key.unwrap()).unwrap();
}
glsp::giter(GIterState::TabKeys(arr.to_raw()))
}
pub fn gvalues(&self) -> Root<GIter> {
let arr = glsp::arr_with_capacity(self.len());
for value in self.entries().values_to::<Slot>() {
arr.push(value.unwrap()).unwrap();
}
glsp::giter(GIterState::TabValues(arr.to_raw()))
}
pub fn extend<T, K, V>(&mut self, iter_source: T) -> GResult<()>
where
T: IntoIterator<Item = (K, V)>,
K: IntoVal,
V: IntoVal
{
let iter = iter_source.into_iter();
self.borrow_mut_with_capacity_guard(|map| {
map.reserve(iter.size_hint().0);
Ok(())
})?;
for (key, value) in iter {
let key = key.into_slot()?;
let value = value.into_slot()?;
self.write_barrier_slot(&key);
self.write_barrier_slot(&value);
self.borrow_mut()?.insert(key, value);
}
Ok(())
}
pub fn freeze(&self) {
self.header.freeze()
}
pub fn deep_freeze(&self) {
self.freeze();
for (key, value) in self.entries().iter() {
key.deep_freeze();
value.deep_freeze();
}
}
pub fn is_frozen(&self) -> bool {
self.header.frozen()
}
pub fn is_deep_frozen(&self) -> bool {
self.is_frozen() && self.entries().iter().all(|(key, value)| {
key.is_deep_frozen() && value.is_deep_frozen()
})
}
pub fn can_mutate(&self) -> bool {
(!self.header.frozen()) && self.map.try_borrow_mut().is_ok()
}
}
impl PartialEq<Tab> for Tab {
fn eq(&self, other: &Tab) -> bool {
self.try_eq(other).unwrap()
}
}
impl Eq for Tab { }
pub struct TabEntries<'a>(Ref<'a, FnvHashMap<Slot, Slot>>);
impl<'a> TabEntries<'a> {
pub fn iter<'b>(&'b self) -> IterTab<'a, 'b> {
IterTab::from(self)
}
pub fn iter_to<'b, K: FromVal, V: FromVal>(&'b self) -> IterTabTo<'a, 'b, K, V> {
IterTabTo::from(self)
}
pub fn keys<'b>(&'b self) -> IterTabKeys<'a, 'b> {
IterTabKeys::from(self)
}
pub fn keys_to<'b, K: FromVal>(&'b self) -> IterTabKeysTo<'a, 'b, K> {
IterTabKeysTo::from(self)
}
pub fn values<'b>(&'b self) -> IterTabValues<'a, 'b> {
IterTabValues::from(self)
}
pub fn values_to<'b, V: FromVal>(&'b self) -> IterTabValuesTo<'a, 'b, V> {
IterTabValuesTo::from(self)
}
}
impl<'a, 'b> IntoIterator for &'b TabEntries<'a> {
type Item = (Val, Val);
type IntoIter = IterTab<'a, 'b>;
fn into_iter(self) -> IterTab<'a, 'b> {
IterTab::from(self)
}
}
pub struct IterTab<'a, 'b> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Iter<'b, Slot, Slot>
}
impl<'a, 'b> IterTab<'a, 'b> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTab {
entries: PhantomData,
iter: (entries.0).iter()
}
}
}
impl<'a, 'b> Iterator for IterTab<'a, 'b> {
type Item = (Val, Val);
fn next(&mut self) -> Option<(Val, Val)> {
self.iter.next().map(|(key, value)| {
(key.root(), value.root())
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b> ExactSizeIterator for IterTab<'a, 'b> { }
impl<'a, 'b> FusedIterator for IterTab<'a, 'b> { }
pub struct IterTabTo<'a, 'b, K: FromVal, V: FromVal> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Iter<'b, Slot, Slot>,
phantom: PhantomData<(K, V)>
}
impl<'a, 'b, K: FromVal, V: FromVal> IterTabTo<'a, 'b, K, V> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTabTo {
entries: PhantomData,
iter: (entries.0).iter(),
phantom: PhantomData
}
}
}
impl<'a, 'b, K: FromVal, V: FromVal> Iterator for IterTabTo<'a, 'b, K, V> {
type Item = GResult<(K, V)>;
fn next(&mut self) -> Option<GResult<(K, V)>> {
self.iter.next().map(|(internal_key, internal_value)| {
let key = K::from_slot(internal_key)?;
let value = V::from_slot(internal_value)?;
Ok((key, value))
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b, K: FromVal, V: FromVal> ExactSizeIterator for IterTabTo<'a, 'b, K, V> { }
impl<'a, 'b, K: FromVal, V: FromVal> FusedIterator for IterTabTo<'a, 'b, K, V> { }
pub struct IterTabKeys<'a, 'b> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Keys<'b, Slot, Slot>
}
impl<'a, 'b> IterTabKeys<'a, 'b> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTabKeys {
entries: PhantomData,
iter: (entries.0).keys()
}
}
}
impl<'a, 'b> Iterator for IterTabKeys<'a, 'b> {
type Item = Val;
fn next(&mut self) -> Option<Val> {
self.iter.next().map(|internal_key| internal_key.root())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b> ExactSizeIterator for IterTabKeys<'a, 'b> { }
impl<'a, 'b> FusedIterator for IterTabKeys<'a, 'b> { }
pub struct IterTabKeysTo<'a, 'b, K: FromVal> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Keys<'b, Slot, Slot>,
phantom: PhantomData<K>
}
impl<'a, 'b, K: FromVal> IterTabKeysTo<'a, 'b, K> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTabKeysTo {
entries: PhantomData,
iter: (entries.0).keys(),
phantom: PhantomData
}
}
}
impl<'a, 'b, K: FromVal> Iterator for IterTabKeysTo<'a, 'b, K> {
type Item = GResult<K>;
fn next(&mut self) -> Option<GResult<K>> {
self.iter.next().map(|internal_key| {
K::from_slot(internal_key)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b, K: FromVal> ExactSizeIterator for IterTabKeysTo<'a, 'b, K> { }
impl<'a, 'b, K: FromVal> FusedIterator for IterTabKeysTo<'a, 'b, K> { }
pub struct IterTabValues<'a, 'b> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Values<'b, Slot, Slot>
}
impl<'a, 'b> IterTabValues<'a, 'b> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTabValues {
entries: PhantomData,
iter: (entries.0).values()
}
}
}
impl<'a, 'b> Iterator for IterTabValues<'a, 'b> {
type Item = Val;
fn next(&mut self) -> Option<Val> {
self.iter.next().map(|internal_value| internal_value.root())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b> ExactSizeIterator for IterTabValues<'a, 'b> { }
impl<'a, 'b> FusedIterator for IterTabValues<'a, 'b> { }
pub struct IterTabValuesTo<'a, 'b, V: FromVal> {
entries: PhantomData<&'b TabEntries<'a>>,
iter: hash_map::Values<'b, Slot, Slot>,
phantom: PhantomData<V>
}
impl<'a, 'b, V: FromVal> IterTabValuesTo<'a, 'b, V> {
fn from(entries: &'b TabEntries<'a>) -> Self {
IterTabValuesTo {
entries: PhantomData,
iter: (entries.0).values(),
phantom: PhantomData
}
}
}
impl<'a, 'b, V: FromVal> Iterator for IterTabValuesTo<'a, 'b, V> {
type Item = GResult<V>;
fn next(&mut self) -> Option<GResult<V>> {
self.iter.next().map(|internal_value| {
V::from_slot(internal_value)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'b, V: FromVal> ExactSizeIterator for IterTabValuesTo<'a, 'b, V> { }
impl<'a, 'b, V: FromVal> FusedIterator for IterTabValuesTo<'a, 'b, V> { }