September-october commit

- manual parser
- stl refinements
- all language constructs are now Send
This commit is contained in:
2023-10-11 18:27:50 +01:00
parent 56679dcc01
commit 86e520e8b8
127 changed files with 1666 additions and 1872 deletions

View File

@@ -1,7 +1,6 @@
use std::borrow::Borrow;
use std::cell::RefCell;
use std::hash::{BuildHasher, Hash};
use std::rc::Rc;
use std::sync::{RwLock, Arc};
use hashbrown::HashMap;
@@ -11,32 +10,32 @@ use super::token::Tok;
/// Lasso but much simpler, in part because not much can be known about the
/// type.
pub struct TypedInterner<T: 'static + Eq + Hash + Clone> {
tokens: RefCell<HashMap<Rc<T>, Tok<T>>>,
tokens: RwLock<HashMap<Arc<T>, Tok<T>>>,
}
impl<T: Eq + Hash + Clone> TypedInterner<T> {
/// Create a fresh interner instance
#[must_use]
pub fn new() -> Rc<Self> {
Rc::new(Self { tokens: RefCell::new(HashMap::new()) })
pub fn new() -> Arc<Self> {
Arc::new(Self { tokens: RwLock::new(HashMap::new()) })
}
/// Intern an object, returning a token
#[must_use]
pub fn i<Q: ?Sized + Eq + Hash + ToOwned<Owned = T>>(
self: &Rc<Self>,
self: &Arc<Self>,
q: &Q,
) -> Tok<T>
where
T: Borrow<Q>,
{
let mut tokens = self.tokens.borrow_mut();
let mut tokens = self.tokens.write().unwrap();
let hash = compute_hash(tokens.hasher(), q);
let raw_entry = tokens
.raw_entry_mut()
.from_hash(hash, |k| <T as Borrow<Q>>::borrow(k) == q);
let kv = raw_entry.or_insert_with(|| {
let keyrc = Rc::new(q.to_owned());
let token = Tok::<T>::new(keyrc.clone(), Rc::downgrade(self));
let keyrc = Arc::new(q.to_owned());
let token = Tok::<T>::new(keyrc.clone(), Arc::downgrade(self));
(keyrc, token)
});
kv.1.clone()

View File

@@ -2,7 +2,7 @@ use std::any::{Any, TypeId};
use std::borrow::Borrow;
use std::cell::{RefCell, RefMut};
use std::hash::Hash;
use std::rc::Rc;
use std::sync::Arc;
use hashbrown::HashMap;
@@ -13,7 +13,7 @@ use super::token::Tok;
/// that implements [ToOwned]. Objects of the same type are stored together in a
/// [TypedInterner].
pub struct Interner {
interners: RefCell<HashMap<TypeId, Rc<dyn Any>>>,
interners: RefCell<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
}
impl Interner {
/// Create a new interner
@@ -24,7 +24,7 @@ impl Interner {
#[must_use]
pub fn i<Q: ?Sized + Eq + Hash + ToOwned>(&self, q: &Q) -> Tok<Q::Owned>
where
Q::Owned: 'static + Eq + Hash + Clone + Borrow<Q>,
Q::Owned: 'static + Eq + Hash + Clone + Borrow<Q> + Send + Sync,
{
let mut interners = self.interners.borrow_mut();
let interner = get_interner(&mut interners);
@@ -44,9 +44,9 @@ impl Default for Interner {
/// Get or create an interner for a given type.
#[must_use]
fn get_interner<T: 'static + Eq + Hash + Clone>(
interners: &mut RefMut<HashMap<TypeId, Rc<dyn Any>>>,
) -> Rc<TypedInterner<T>> {
fn get_interner<T: 'static + Eq + Hash + Clone + Send + Sync>(
interners: &mut RefMut<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
) -> Arc<TypedInterner<T>> {
let boxed = interners
.raw_entry_mut()
.from_key(&TypeId::of::<T>())

View File

@@ -3,7 +3,7 @@ use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::num::NonZeroUsize;
use std::ops::Deref;
use std::rc::{Rc, Weak};
use std::sync::{Arc, Weak};
use super::TypedInterner;
@@ -13,13 +13,13 @@ use super::TypedInterner;
/// currently not enforced.
#[derive(Clone)]
pub struct Tok<T: Eq + Hash + Clone + 'static> {
data: Rc<T>,
data: Arc<T>,
interner: Weak<TypedInterner<T>>,
}
impl<T: Eq + Hash + Clone + 'static> Tok<T> {
/// Create a new token. Used exclusively by the interner
#[must_use]
pub(crate) fn new(data: Rc<T>, interner: Weak<TypedInterner<T>>) -> Self {
pub(crate) fn new(data: Arc<T>, interner: Weak<TypedInterner<T>>) -> Self {
Self { data, interner }
}
/// Take the ID number out of a token