remove interning contexts
This commit is contained in:
parent
44ca1a607a
commit
f12322aa2a
|
@ -686,7 +686,7 @@ impl ToTokens for ParsedBundle {
|
||||||
let __retval = #mask_type_match_variant_ident {
|
let __retval = #mask_type_match_variant_ident {
|
||||||
#(#match_variant_body_fields)*
|
#(#match_variant_body_fields)*
|
||||||
};
|
};
|
||||||
::fayalite::intern::Interned::<_>::into_inner(::fayalite::intern::Intern::intern_sized(__retval))
|
::fayalite::intern::Interned::into_inner(::fayalite::intern::Intern::intern_sized(__retval))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
@ -761,7 +761,7 @@ impl ToTokens for ParsedBundle {
|
||||||
let __retval = #match_variant_ident {
|
let __retval = #match_variant_ident {
|
||||||
#(#match_variant_body_fields)*
|
#(#match_variant_body_fields)*
|
||||||
};
|
};
|
||||||
::fayalite::intern::Interned::<_>::into_inner(::fayalite::intern::Intern::intern_sized(__retval))
|
::fayalite::intern::Interned::into_inner(::fayalite::intern::Intern::intern_sized(__retval))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2718,7 +2718,7 @@ impl ParsedGenerics {
|
||||||
type Output = #next_target #next_type_generics;
|
type Output = #next_target #next_type_generics;
|
||||||
|
|
||||||
fn index(&self, #param_token: #index_type) -> &Self::Output {
|
fn index(&self, #param_token: #index_type) -> &Self::Output {
|
||||||
::fayalite::intern::Interned::<_>::into_inner(
|
::fayalite::intern::Interned::into_inner(
|
||||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2778,7 +2778,7 @@ impl ParsedGenerics {
|
||||||
type Output = #next_target #next_target_args;
|
type Output = #next_target #next_target_args;
|
||||||
|
|
||||||
fn index(&self, #param_token: #param_ident) -> &Self::Output {
|
fn index(&self, #param_token: #param_ident) -> &Self::Output {
|
||||||
::fayalite::intern::Interned::<_>::into_inner(
|
::fayalite::intern::Interned::into_inner(
|
||||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2848,7 +2848,7 @@ impl ParsedGenerics {
|
||||||
type Output = #next_target #next_target_args;
|
type Output = #next_target #next_target_args;
|
||||||
|
|
||||||
fn index(&self, #param_token: __Param) -> &Self::Output {
|
fn index(&self, #param_token: __Param) -> &Self::Output {
|
||||||
::fayalite::intern::Interned::<_>::into_inner(
|
::fayalite::intern::Interned::into_inner(
|
||||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ impl<T: Type, Len: Size> TypeWithDeref for ArrayType<T, Len> {
|
||||||
let base = Expr::as_dyn_array(*this);
|
let base = Expr::as_dyn_array(*this);
|
||||||
let base_ty = Expr::ty(base);
|
let base_ty = Expr::ty(base);
|
||||||
let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr()));
|
let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr()));
|
||||||
Interned::<_>::into_inner(Intern::intern_sized(
|
Interned::into_inner(Intern::intern_sized(
|
||||||
Len::ArrayMatch::<T>::try_from(retval)
|
Len::ArrayMatch::<T>::try_from(retval)
|
||||||
.ok()
|
.ok()
|
||||||
.expect("unreachable"),
|
.expect("unreachable"),
|
||||||
|
@ -202,7 +202,7 @@ impl<T: Type> Index<T> for ArrayWithoutGenerics {
|
||||||
type Output = ArrayWithoutLen<T>;
|
type Output = ArrayWithoutLen<T>;
|
||||||
|
|
||||||
fn index(&self, element: T) -> &Self::Output {
|
fn index(&self, element: T) -> &Self::Output {
|
||||||
Interned::<_>::into_inner(Intern::intern_sized(ArrayWithoutLen { element }))
|
Interned::into_inner(Intern::intern_sized(ArrayWithoutLen { element }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +215,6 @@ impl<T: Type, L: SizeType> Index<L> for ArrayWithoutLen<T> {
|
||||||
type Output = ArrayType<T, L::Size>;
|
type Output = ArrayType<T, L::Size>;
|
||||||
|
|
||||||
fn index(&self, len: L) -> &Self::Output {
|
fn index(&self, len: L) -> &Self::Output {
|
||||||
Interned::<_>::into_inner(Intern::intern_sized(ArrayType::new(self.element, len)))
|
Interned::into_inner(Intern::intern_sized(ArrayType::new(self.element, len)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,7 +377,7 @@ macro_rules! impl_tuples {
|
||||||
impl<$($T: Type,)*> TypeWithDeref for ($($T,)*) {
|
impl<$($T: Type,)*> TypeWithDeref for ($($T,)*) {
|
||||||
fn expr_deref(this: &Expr<Self>) -> &Self::MatchVariant {
|
fn expr_deref(this: &Expr<Self>) -> &Self::MatchVariant {
|
||||||
let _ = this;
|
let _ = this;
|
||||||
Interned::<_>::into_inner(($(Expr::field(*this, stringify!($num)),)*).intern_sized())
|
Interned::into_inner(($(Expr::field(*this, stringify!($num)),)*).intern_sized())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<$($T: StaticType,)*> StaticType for ($($T,)*) {
|
impl<$($T: StaticType,)*> StaticType for ($($T,)*) {
|
||||||
|
|
|
@ -2057,7 +2057,7 @@ impl<ElementType: Type, Len: Size> ExprIndex<usize> for ArrayType<ElementType, L
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn expr_index(this: &Expr<Self>, index: usize) -> &Expr<Self::Output> {
|
fn expr_index(this: &Expr<Self>, index: usize) -> &Expr<Self::Output> {
|
||||||
Interned::<_>::into_inner(
|
Interned::into_inner(
|
||||||
ArrayIndex::<ElementType>::new(Expr::as_dyn_array(*this), index)
|
ArrayIndex::<ElementType>::new(Expr::as_dyn_array(*this), index)
|
||||||
.to_expr()
|
.to_expr()
|
||||||
.intern_sized(),
|
.intern_sized(),
|
||||||
|
@ -2154,7 +2154,7 @@ impl<ElementType: Type, Len: Size, Width: Size> ExprIndex<Expr<UIntType<Width>>>
|
||||||
type Output = ElementType;
|
type Output = ElementType;
|
||||||
|
|
||||||
fn expr_index(this: &Expr<Self>, index: Expr<UIntType<Width>>) -> &Expr<Self::Output> {
|
fn expr_index(this: &Expr<Self>, index: Expr<UIntType<Width>>) -> &Expr<Self::Output> {
|
||||||
Interned::<_>::into_inner(
|
Interned::into_inner(
|
||||||
DynArrayIndex::<ElementType>::new(Expr::as_dyn_array(*this), Expr::as_dyn_int(index))
|
DynArrayIndex::<ElementType>::new(Expr::as_dyn_array(*this), Expr::as_dyn_int(index))
|
||||||
.to_expr()
|
.to_expr()
|
||||||
.intern_sized(),
|
.intern_sized(),
|
||||||
|
@ -2279,7 +2279,7 @@ macro_rules! impl_int_slice {
|
||||||
let base = Expr::as_dyn_int(*this);
|
let base = Expr::as_dyn_int(*this);
|
||||||
let base_ty = Expr::ty(base);
|
let base_ty = Expr::ty(base);
|
||||||
let range = base_ty.slice_index_to_range(index);
|
let range = base_ty.slice_index_to_range(index);
|
||||||
Interned::<_>::into_inner($name::new(base, range).to_expr().intern_sized())
|
Interned::into_inner($name::new(base, range).to_expr().intern_sized())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2291,7 +2291,7 @@ macro_rules! impl_int_slice {
|
||||||
let base = Expr::as_dyn_int(*this);
|
let base = Expr::as_dyn_int(*this);
|
||||||
let base_ty = Expr::ty(base);
|
let base_ty = Expr::ty(base);
|
||||||
assert!(index < base_ty.width());
|
assert!(index < base_ty.width());
|
||||||
Interned::<_>::into_inner(
|
Interned::into_inner(
|
||||||
$name::new(base, index..(index + 1))
|
$name::new(base, index..(index + 1))
|
||||||
.to_expr()
|
.to_expr()
|
||||||
.cast_to_static::<Bool>()
|
.cast_to_static::<Bool>()
|
||||||
|
|
|
@ -301,7 +301,7 @@ macro_rules! impl_int {
|
||||||
type Output = $name<Width::Size>;
|
type Output = $name<Width::Size>;
|
||||||
|
|
||||||
fn index(&self, width: Width) -> &Self::Output {
|
fn index(&self, width: Width) -> &Self::Output {
|
||||||
Interned::<_>::into_inner(Intern::intern_sized($name::new(width)))
|
Interned::into_inner(Intern::intern_sized($name::new(width)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
use crate::{
|
use crate::intern::type_map::TypeIdMap;
|
||||||
intern::type_map::TypeIdMap,
|
|
||||||
util::{ConstBool, GenericConstBool},
|
|
||||||
};
|
|
||||||
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
|
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
|
||||||
use hashbrown::{hash_map::RawEntryMut, HashMap, HashTable};
|
use hashbrown::{hash_map::RawEntryMut, HashMap, HashTable};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -297,221 +294,94 @@ impl InternedCompare for str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InternContext: 'static + Send + Sync + Hash + Ord + fmt::Debug + Clone {
|
pub trait Intern: Any + Send + Sync {
|
||||||
type InternedImpl<T: ?Sized + 'static + Send + Sync>: 'static + Send + Sync + Clone;
|
fn intern(&self) -> Interned<Self>;
|
||||||
type InternedGuardImpl<T: ?Sized + 'static + Send + Sync>: 'static
|
fn intern_sized(self) -> Interned<Self>
|
||||||
+ Send
|
where
|
||||||
+ Sync
|
Self: Clone,
|
||||||
+ Clone
|
{
|
||||||
+ Borrow<T>;
|
Self::intern_owned(self)
|
||||||
type AllContextsAreIdentical: GenericConstBool;
|
|
||||||
fn interned_compare_key<T: InternedCompare + ?Sized + 'static + Send + Sync>(
|
|
||||||
v: &Self::InternedImpl<T>,
|
|
||||||
) -> T::InternedCompareKey {
|
|
||||||
T::interned_compare_key_ref(Self::guard(v).borrow())
|
|
||||||
}
|
}
|
||||||
fn guard<T: ?Sized + 'static + Send + Sync>(
|
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self>
|
||||||
v: &Self::InternedImpl<T>,
|
where
|
||||||
) -> Self::InternedGuardImpl<T>;
|
Self: ToOwned,
|
||||||
fn try_guard<T: ?Sized + 'static + Send + Sync>(
|
{
|
||||||
v: &Self::InternedImpl<T>,
|
Self::intern_cow(Cow::Owned(this))
|
||||||
) -> Option<Self::InternedGuardImpl<T>>;
|
|
||||||
fn into_guard<T: ?Sized + 'static + Send + Sync>(
|
|
||||||
v: Self::InternedImpl<T>,
|
|
||||||
) -> Self::InternedGuardImpl<T> {
|
|
||||||
Self::guard(&v)
|
|
||||||
}
|
}
|
||||||
fn unguard<T: ?Sized + 'static + Send + Sync>(
|
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self>
|
||||||
v: &Self::InternedGuardImpl<T>,
|
where
|
||||||
) -> Self::InternedImpl<T>;
|
Self: ToOwned,
|
||||||
fn unguard_move<T: ?Sized + 'static + Send + Sync>(
|
{
|
||||||
v: Self::InternedGuardImpl<T>,
|
this.intern()
|
||||||
) -> Self::InternedImpl<T> {
|
|
||||||
Self::unguard(&v)
|
|
||||||
}
|
}
|
||||||
fn alloc_str(&self, value: Cow<'_, str>) -> Self::InternedGuardImpl<str>;
|
|
||||||
fn alloc_slice<T: Clone + Send + Sync + 'static>(
|
|
||||||
&self,
|
|
||||||
value: Cow<'_, [T]>,
|
|
||||||
) -> Self::InternedGuardImpl<[T]>;
|
|
||||||
fn alloc_sized<T: Clone + Send + Sync + 'static>(
|
|
||||||
&self,
|
|
||||||
value: Cow<'_, T>,
|
|
||||||
) -> Self::InternedGuardImpl<T>;
|
|
||||||
fn interner<T: ?Sized + Send + Sync + 'static>(&self) -> &Interner<T, Self>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BitSliceInternContext: InternContext {
|
pub struct Interner<T: ?Sized + 'static + Send + Sync> {
|
||||||
fn alloc_bit_slice(&self, value: Cow<'_, BitSlice>) -> Self::InternedGuardImpl<BitSlice>;
|
map: Mutex<HashMap<&'static T, ()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
|
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
|
||||||
pub struct GlobalContext;
|
fn get() -> &'static Interner<T> {
|
||||||
|
|
||||||
impl InternContext for GlobalContext {
|
|
||||||
type InternedImpl<T: ?Sized + 'static + Send + Sync> = &'static T;
|
|
||||||
type InternedGuardImpl<T: ?Sized + 'static + Send + Sync> = &'static T;
|
|
||||||
type AllContextsAreIdentical = ConstBool<true>;
|
|
||||||
|
|
||||||
fn guard<T: ?Sized + 'static + Send + Sync>(
|
|
||||||
v: &Self::InternedImpl<T>,
|
|
||||||
) -> Self::InternedGuardImpl<T> {
|
|
||||||
*v
|
|
||||||
}
|
|
||||||
fn try_guard<T: ?Sized + 'static + Send + Sync>(
|
|
||||||
v: &Self::InternedImpl<T>,
|
|
||||||
) -> Option<Self::InternedGuardImpl<T>> {
|
|
||||||
Some(*v)
|
|
||||||
}
|
|
||||||
fn unguard<T: ?Sized + 'static + Send + Sync>(
|
|
||||||
v: &Self::InternedGuardImpl<T>,
|
|
||||||
) -> Self::InternedImpl<T> {
|
|
||||||
*v
|
|
||||||
}
|
|
||||||
fn alloc_str(&self, value: Cow<'_, str>) -> Self::InternedGuardImpl<str> {
|
|
||||||
value.into_owned().leak()
|
|
||||||
}
|
|
||||||
fn alloc_slice<T: Clone + Send + Sync + 'static>(
|
|
||||||
&self,
|
|
||||||
value: Cow<'_, [T]>,
|
|
||||||
) -> Self::InternedGuardImpl<[T]> {
|
|
||||||
value.into_owned().leak()
|
|
||||||
}
|
|
||||||
fn alloc_sized<T: Clone + Send + Sync + 'static>(
|
|
||||||
&self,
|
|
||||||
value: Cow<'_, T>,
|
|
||||||
) -> Self::InternedGuardImpl<T> {
|
|
||||||
Box::leak(Box::new(value.into_owned()))
|
|
||||||
}
|
|
||||||
fn interner<T: ?Sized + 'static + Send + Sync>(&self) -> &Interner<T, Self> {
|
|
||||||
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
||||||
TYPE_ID_MAP.get_or_insert_default()
|
TYPE_ID_MAP.get_or_insert_default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitSliceInternContext for GlobalContext {
|
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
|
||||||
fn alloc_bit_slice(&self, value: Cow<'_, BitSlice>) -> Self::InternedGuardImpl<BitSlice> {
|
|
||||||
value.into_owned().leak()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Intern<C: InternContext = GlobalContext>: Any + Send + Sync {
|
|
||||||
fn intern_with_ctx(&self, context: &C) -> Interned<Self, C>;
|
|
||||||
fn intern_sized_with_ctx(self, context: &C) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: Clone,
|
|
||||||
{
|
|
||||||
Self::intern_owned_with_ctx(self, context)
|
|
||||||
}
|
|
||||||
fn intern_owned_with_ctx(this: <Self as ToOwned>::Owned, context: &C) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: ToOwned,
|
|
||||||
{
|
|
||||||
Self::intern_cow_with_ctx(Cow::Owned(this), context)
|
|
||||||
}
|
|
||||||
fn intern_cow_with_ctx(this: Cow<'_, Self>, context: &C) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: ToOwned,
|
|
||||||
{
|
|
||||||
this.intern_with_ctx(context)
|
|
||||||
}
|
|
||||||
fn intern(&self) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
{
|
|
||||||
self.intern_with_ctx(&C::default())
|
|
||||||
}
|
|
||||||
fn intern_sized(self) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: Clone,
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
{
|
|
||||||
self.intern_sized_with_ctx(&C::default())
|
|
||||||
}
|
|
||||||
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: ToOwned,
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
{
|
|
||||||
Self::intern_owned_with_ctx(this, &C::default())
|
|
||||||
}
|
|
||||||
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self, C>
|
|
||||||
where
|
|
||||||
Self: ToOwned,
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
{
|
|
||||||
Self::intern_cow_with_ctx(this, &C::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Interner<T: ?Sized + 'static + Send + Sync, C: InternContext> {
|
|
||||||
map: Mutex<HashMap<C::InternedGuardImpl<T>, ()>>,
|
|
||||||
_phantom: PhantomData<fn(&C)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Default for Interner<T, C> {
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
map: Default::default(),
|
map: Default::default(),
|
||||||
_phantom: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned, C: InternContext> Interner<T, C> {
|
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
|
||||||
fn intern<F: FnOnce(Cow<'_, T>) -> C::InternedGuardImpl<T>>(
|
fn intern<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
||||||
&self,
|
&self,
|
||||||
alloc: F,
|
alloc: F,
|
||||||
value: Cow<'_, T>,
|
value: Cow<'_, T>,
|
||||||
) -> Interned<T, C> {
|
) -> Interned<T> {
|
||||||
let mut map = self.map.lock().unwrap();
|
let mut map = self.map.lock().unwrap();
|
||||||
let hasher = map.hasher().clone();
|
let hasher = map.hasher().clone();
|
||||||
let hash = hasher.hash_one(&*value);
|
let hash = hasher.hash_one(&*value);
|
||||||
let inner = match map
|
let inner = match map.raw_entry_mut().from_hash(hash, |k| **k == *value) {
|
||||||
.raw_entry_mut()
|
RawEntryMut::Occupied(entry) => *entry.key(),
|
||||||
.from_hash(hash, |k| k.borrow() == &*value)
|
RawEntryMut::Vacant(entry) => {
|
||||||
{
|
*entry
|
||||||
RawEntryMut::Occupied(entry) => C::unguard(entry.key()),
|
.insert_with_hasher(hash, alloc(value), (), |k| hasher.hash_one(&**k))
|
||||||
RawEntryMut::Vacant(entry) => C::unguard(
|
.0
|
||||||
entry
|
}
|
||||||
.insert_with_hasher(hash, alloc(value), (), |k| hasher.hash_one(k.borrow()))
|
|
||||||
.0,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
Interned {
|
Interned { inner }
|
||||||
inner,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq, C: InternContext> Interner<T, C> {
|
|
||||||
fn intern_sized(&self, context: &C, value: Cow<'_, T>) -> Interned<T, C> {
|
|
||||||
self.intern(|value| context.alloc_sized(value), value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq, C: InternContext> Interner<[T], C> {
|
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<T> {
|
||||||
fn intern_slice(&self, context: &C, value: Cow<'_, [T]>) -> Interned<[T], C> {
|
fn intern_sized(&self, value: Cow<'_, T>) -> Interned<T> {
|
||||||
self.intern(|value| context.alloc_slice(value), value)
|
self.intern(|value| Box::leak(Box::new(value.into_owned())), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: BitSliceInternContext> Interner<BitSlice, C> {
|
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<[T]> {
|
||||||
fn intern_bit_slice(&self, context: &C, value: Cow<'_, BitSlice>) -> Interned<BitSlice, C> {
|
fn intern_slice(&self, value: Cow<'_, [T]>) -> Interned<[T]> {
|
||||||
self.intern(|value| context.alloc_bit_slice(value), value)
|
self.intern(|value| value.into_owned().leak(), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: InternContext> Interner<str, C> {
|
impl Interner<BitSlice> {
|
||||||
fn intern_str(&self, context: &C, value: Cow<'_, str>) -> Interned<str, C> {
|
fn intern_bit_slice(&self, value: Cow<'_, BitSlice>) -> Interned<BitSlice> {
|
||||||
self.intern(|value| context.alloc_str(value), value)
|
self.intern(|value| value.into_owned().leak(), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Interned<T: ?Sized + 'static + Send + Sync, C: InternContext = GlobalContext> {
|
impl Interner<str> {
|
||||||
inner: C::InternedImpl<T>,
|
fn intern_str(&self, value: Cow<'_, str>) -> Interned<str> {
|
||||||
_phantom: PhantomData<&'static C>,
|
self.intern(|value| value.into_owned().leak(), value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Interned<T: ?Sized + 'static + Send + Sync> {
|
||||||
|
inner: &'static T,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! forward_fmt_trait {
|
macro_rules! forward_fmt_trait {
|
||||||
|
@ -522,23 +392,9 @@ macro_rules! forward_fmt_trait {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + fmt::$Tr, C: InternContext> fmt::$Tr
|
impl<T: ?Sized + 'static + Send + Sync + fmt::$Tr> fmt::$Tr for Interned<T> {
|
||||||
for Interned<T, C>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if let Some(guard) = C::try_guard(&self.inner) {
|
self.inner.fmt(f)
|
||||||
guard.borrow().fmt(f)
|
|
||||||
} else {
|
|
||||||
write!(f, "<Expired>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + fmt::$Tr, C: InternContext> fmt::$Tr
|
|
||||||
for Guard<T, C>
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
self.inner.borrow().fmt(f)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -554,18 +410,16 @@ forward_fmt_trait!(UpperExp);
|
||||||
forward_fmt_trait!(UpperHex);
|
forward_fmt_trait!(UpperHex);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InternedSliceIter<T: Clone + 'static + Send + Sync, C: InternContext> {
|
pub struct InternedSliceIter<T: Clone + 'static + Send + Sync> {
|
||||||
slice: Interned<[T], C>,
|
slice: Interned<[T]>,
|
||||||
index: std::ops::Range<usize>,
|
index: std::ops::Range<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync, C: InternContext> Iterator for InternedSliceIter<T, C> {
|
impl<T: Clone + 'static + Send + Sync> Iterator for InternedSliceIter<T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.index
|
self.index.next().map(|index| self.slice[index].clone())
|
||||||
.next()
|
|
||||||
.map(|index| self.slice.guard()[index].clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
@ -573,233 +427,186 @@ impl<T: Clone + 'static + Send + Sync, C: InternContext> Iterator for InternedSl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync, C: InternContext> DoubleEndedIterator
|
impl<T: Clone + 'static + Send + Sync> DoubleEndedIterator for InternedSliceIter<T> {
|
||||||
for InternedSliceIter<T, C>
|
|
||||||
{
|
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
self.index
|
self.index
|
||||||
.next_back()
|
.next_back()
|
||||||
.map(|index| self.slice.guard()[index].clone())
|
.map(|index| self.slice[index].clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync, C: InternContext> FusedIterator for InternedSliceIter<T, C> {}
|
impl<T: Clone + 'static + Send + Sync> FusedIterator for InternedSliceIter<T> {}
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync, C: InternContext> ExactSizeIterator
|
impl<T: Clone + 'static + Send + Sync> ExactSizeIterator for InternedSliceIter<T> {}
|
||||||
for InternedSliceIter<T, C>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + 'static + Send + Sync, C: InternContext> IntoIterator for Interned<[T], C> {
|
impl<T: Clone + 'static + Send + Sync> IntoIterator for Interned<[T]> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
type IntoIter = InternedSliceIter<T, C>;
|
type IntoIter = InternedSliceIter<T>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
InternedSliceIter {
|
InternedSliceIter {
|
||||||
index: 0..self.guard().len(),
|
index: 0..self.len(),
|
||||||
slice: self,
|
slice: self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'static + Send + Sync, C: InternContext> IntoIterator for &'a Interned<[T], C>
|
impl<'a, T: 'static + Send + Sync> IntoIterator for &'a Interned<[T]> {
|
||||||
where
|
|
||||||
C::InternedImpl<[T]>: Borrow<[T]>,
|
|
||||||
{
|
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
type IntoIter = std::slice::Iter<'a, T>;
|
type IntoIter = std::slice::Iter<'a, T>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.inner.borrow().iter()
|
self.inner.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'static + Send + Sync, C: InternContext> IntoIterator for &'a mut Interned<[T], C>
|
impl<'a, T: 'static + Send + Sync> IntoIterator for &'a mut Interned<[T]> {
|
||||||
where
|
|
||||||
C::InternedImpl<[T]>: Borrow<[T]>,
|
|
||||||
{
|
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
type IntoIter = std::slice::Iter<'a, T>;
|
type IntoIter = std::slice::Iter<'a, T>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.inner.borrow().iter()
|
self.inner.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Clone, C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default>
|
impl<I: Clone> FromIterator<I> for Interned<[I]>
|
||||||
FromIterator<I> for Interned<[I], C>
|
|
||||||
where
|
where
|
||||||
[I]: Intern<C>,
|
[I]: Intern,
|
||||||
{
|
{
|
||||||
fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
|
||||||
Intern::intern_owned(Vec::from_iter(iter))
|
Intern::intern_owned(Vec::from_iter(iter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static + Clone + Send + Sync, C: InternContext> From<Interned<[T], C>> for Vec<T> {
|
impl<T: 'static + Clone + Send + Sync> From<Interned<[T]>> for Vec<T> {
|
||||||
fn from(value: Interned<[T], C>) -> Self {
|
fn from(value: Interned<[T]>) -> Self {
|
||||||
Vec::from(&*value.guard())
|
Vec::from(&*value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static + Clone + Send + Sync, C: InternContext> From<Interned<[T], C>> for Box<[T]> {
|
impl<T: 'static + Clone + Send + Sync> From<Interned<[T]>> for Box<[T]> {
|
||||||
fn from(value: Interned<[T], C>) -> Self {
|
fn from(value: Interned<[T]>) -> Self {
|
||||||
Box::from(&*value.guard())
|
Box::from(&*value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: InternContext> From<Interned<str, C>> for String {
|
impl From<Interned<str>> for String {
|
||||||
fn from(value: Interned<str, C>) -> Self {
|
fn from(value: Interned<str>) -> Self {
|
||||||
String::from(&*value.guard())
|
String::from(&*value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default> Default
|
impl<I> Default for Interned<[I]>
|
||||||
for Interned<[I], C>
|
|
||||||
where
|
where
|
||||||
[I]: Intern<C>,
|
[I]: Intern,
|
||||||
{
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
[][..].intern()
|
[][..].intern()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default> Default
|
impl Default for Interned<str> {
|
||||||
for Interned<str, C>
|
|
||||||
where
|
|
||||||
str: Intern<C>,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
"".intern()
|
"".intern()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: BitSliceInternContext<AllContextsAreIdentical = ConstBool<true>> + Default> Default
|
impl Default for Interned<BitSlice> {
|
||||||
for Interned<BitSlice, C>
|
|
||||||
where
|
|
||||||
BitSlice: Intern<C>,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
<&BitSlice>::default().intern()
|
<&BitSlice>::default().intern()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Clone + Default, C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default>
|
impl<I: Clone + Default> Default for Interned<I>
|
||||||
Default for Interned<I, C>
|
|
||||||
where
|
where
|
||||||
I: Intern<C>,
|
I: Intern,
|
||||||
{
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
I::default().intern()
|
I::default().intern()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Interned<T, C> {
|
impl<T: ?Sized + 'static + Send + Sync> Interned<T> {
|
||||||
pub fn cast_unchecked<U: ?Sized + 'static + Send + Sync>(
|
pub fn cast_unchecked<U: ?Sized + 'static + Send + Sync>(
|
||||||
this: Self,
|
this: Self,
|
||||||
f: impl FnOnce(C::InternedImpl<T>) -> C::InternedImpl<U>,
|
f: impl FnOnce(&'static T) -> &'static U,
|
||||||
) -> Interned<U, C> {
|
) -> Interned<U> {
|
||||||
Interned {
|
Interned {
|
||||||
inner: f(this.inner),
|
inner: f(this.inner),
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn try_cast_unchecked<U: ?Sized + 'static + Send + Sync, E>(
|
pub fn try_cast_unchecked<U: ?Sized + 'static + Send + Sync, E>(
|
||||||
this: Self,
|
this: Self,
|
||||||
f: impl FnOnce(C::InternedImpl<T>) -> Result<C::InternedImpl<U>, E>,
|
f: impl FnOnce(&'static T) -> Result<&'static U, E>,
|
||||||
) -> Result<Interned<U, C>, E> {
|
) -> Result<Interned<U>, E> {
|
||||||
Ok(Interned {
|
Ok(Interned {
|
||||||
inner: f(this.inner)?,
|
inner: f(this.inner)?,
|
||||||
_phantom: PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn into_inner(this: Self) -> C::InternedImpl<T> {
|
pub fn into_inner(this: Self) -> &'static T {
|
||||||
this.inner
|
this.inner
|
||||||
}
|
}
|
||||||
pub fn get_ref(this: &Self) -> &C::InternedImpl<T> {
|
pub fn get_ref(this: &Self) -> &&'static T {
|
||||||
&this.inner
|
&this.inner
|
||||||
}
|
}
|
||||||
pub fn guard(&self) -> Guard<T, C> {
|
|
||||||
Guard {
|
|
||||||
inner: C::guard(&self.inner),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Clone for Interned<T, C> {
|
impl<T: ?Sized + 'static + Send + Sync> Clone for Interned<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Interned {
|
*self
|
||||||
inner: self.inner.clone(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Copy for Interned<T, C> where
|
impl<T: ?Sized + 'static + Send + Sync> Copy for Interned<T> where &'static T: Copy {}
|
||||||
C::InternedImpl<T>: Copy
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Deref for Interned<T, C>
|
impl<T: ?Sized + 'static + Send + Sync> Deref for Interned<T>
|
||||||
where
|
where
|
||||||
C::InternedImpl<T>: Borrow<T>,
|
&'static T: Borrow<T>,
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.inner.borrow()
|
self.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> PartialEq
|
impl<T: ?Sized + 'static + Send + Sync + InternedCompare> PartialEq for Interned<T> {
|
||||||
for Interned<T, C>
|
|
||||||
{
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
<C as InternContext>::interned_compare_key(&self.inner)
|
T::interned_compare_key_ref(self.inner) == T::interned_compare_key_ref(other.inner)
|
||||||
== <C as InternContext>::interned_compare_key(&other.inner)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Eq for Interned<T, C> {}
|
impl<T: ?Sized + 'static + Send + Sync + InternedCompare> Eq for Interned<T> {}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> PartialOrd
|
impl<T: ?Sized + 'static + Send + Sync + InternedCompare> PartialOrd for Interned<T> {
|
||||||
for Interned<T, C>
|
|
||||||
{
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Ord for Interned<T, C> {
|
impl<T: ?Sized + 'static + Send + Sync + InternedCompare> Ord for Interned<T> {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
<C as InternContext>::interned_compare_key(&self.inner)
|
T::interned_compare_key_ref(self.inner).cmp(&T::interned_compare_key_ref(other.inner))
|
||||||
.cmp(&<C as InternContext>::interned_compare_key(&other.inner))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Hash
|
impl<T: ?Sized + 'static + Send + Sync + InternedCompare> Hash for Interned<T> {
|
||||||
for Interned<T, C>
|
|
||||||
{
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
<C as InternContext>::interned_compare_key(&self.inner).hash(state);
|
T::interned_compare_key_ref(self.inner).hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + Serialize, C: InternContext> Serialize for Interned<T, C> {
|
impl<T: ?Sized + 'static + Send + Sync + Serialize> Serialize for Interned<T> {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
self.guard().serialize(serializer)
|
T::serialize(self, serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<'de, T: 'static + Send + Sync + Deserialize<'de> + Clone + Intern> Deserialize<'de>
|
||||||
'de,
|
for Interned<T>
|
||||||
T: 'static + Send + Sync + Deserialize<'de> + Clone + Intern<C>,
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
> Deserialize<'de> for Interned<T, C>
|
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
|
@ -809,13 +616,9 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<'de, T: 'static + Send + Sync + Clone> Deserialize<'de> for Interned<[T]>
|
||||||
'de,
|
|
||||||
T: 'static + Send + Sync + Clone,
|
|
||||||
C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default,
|
|
||||||
> Deserialize<'de> for Interned<[T], C>
|
|
||||||
where
|
where
|
||||||
[T]: Intern<C>,
|
[T]: Intern,
|
||||||
Vec<T>: Deserialize<'de>,
|
Vec<T>: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
@ -826,11 +629,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, C: BitSliceInternContext<AllContextsAreIdentical = ConstBool<true>> + Default>
|
impl<'de> Deserialize<'de> for Interned<BitSlice> {
|
||||||
Deserialize<'de> for Interned<BitSlice, C>
|
|
||||||
where
|
|
||||||
BitSlice: Intern<C>,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
@ -839,11 +638,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, C: InternContext<AllContextsAreIdentical = ConstBool<true>> + Default> Deserialize<'de>
|
impl<'de> Deserialize<'de> for Interned<str> {
|
||||||
for Interned<str, C>
|
|
||||||
where
|
|
||||||
str: Intern<C>,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
@ -852,175 +647,83 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Guard<T: ?Sized + 'static + Send + Sync, C: InternContext = GlobalContext> {
|
impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for T {
|
||||||
inner: C::InternedGuardImpl<T>,
|
fn intern(&self) -> Interned<Self> {
|
||||||
_phantom: PhantomData<&'static C>,
|
Self::intern_cow(Cow::Borrowed(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Guard<T, C> {
|
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self>
|
||||||
pub fn cast_unchecked<U: ?Sized + 'static + Send + Sync>(
|
|
||||||
this: Self,
|
|
||||||
f: impl FnOnce(C::InternedGuardImpl<T>) -> C::InternedGuardImpl<U>,
|
|
||||||
) -> Guard<U, C> {
|
|
||||||
Guard {
|
|
||||||
inner: f(this.inner),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn try_cast_unchecked<U: ?Sized + 'static + Send + Sync, E>(
|
|
||||||
this: Self,
|
|
||||||
f: impl FnOnce(C::InternedGuardImpl<T>) -> Result<C::InternedGuardImpl<U>, E>,
|
|
||||||
) -> Result<Guard<U, C>, E> {
|
|
||||||
Ok(Guard {
|
|
||||||
inner: f(this.inner)?,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
pub fn into_inner(this: Self) -> C::InternedGuardImpl<T> {
|
|
||||||
this.inner
|
|
||||||
}
|
|
||||||
pub fn get_ref(this: &Self) -> &C::InternedGuardImpl<T> {
|
|
||||||
&this.inner
|
|
||||||
}
|
|
||||||
pub fn unguard(&self) -> Interned<T, C> {
|
|
||||||
Interned {
|
|
||||||
inner: C::unguard(&self.inner),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Clone for Guard<T, C> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Guard {
|
|
||||||
inner: self.inner.clone(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Copy for Guard<T, C> where
|
|
||||||
C::InternedGuardImpl<T>: Copy
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync, C: InternContext> Deref for Guard<T, C> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.inner.borrow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> PartialEq
|
|
||||||
for Guard<T, C>
|
|
||||||
{
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
T::interned_compare_key_ref(self.inner.borrow())
|
|
||||||
== T::interned_compare_key_ref(other.inner.borrow())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Eq for Guard<T, C> {}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> PartialOrd
|
|
||||||
for Guard<T, C>
|
|
||||||
{
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Ord for Guard<T, C> {
|
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
|
||||||
T::interned_compare_key_ref(self.inner.borrow())
|
|
||||||
.cmp(&T::interned_compare_key_ref(other.inner.borrow()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized + 'static + Send + Sync + InternedCompare, C: InternContext> Hash for Guard<T, C> {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
T::interned_compare_key_ref(self.inner.borrow()).hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + Send + Sync + 'static + Hash + Eq, C: InternContext> Intern<C> for T {
|
|
||||||
fn intern_with_ctx(&self, context: &C) -> Interned<Self, C> {
|
|
||||||
Self::intern_cow_with_ctx(Cow::Borrowed(self), context)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intern_owned_with_ctx(this: <Self as ToOwned>::Owned, context: &C) -> Interned<Self, C>
|
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
Self::intern_cow_with_ctx(Cow::Owned(this), context)
|
Self::intern_cow(Cow::Owned(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_cow_with_ctx(this: Cow<'_, Self>, context: &C) -> Interned<Self, C>
|
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
context.interner().intern_sized(context, this)
|
Interner::get().intern_sized(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + Send + Sync + 'static + Hash + Eq, C: InternContext> Intern<C> for [T] {
|
impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for [T] {
|
||||||
fn intern_with_ctx(&self, context: &C) -> Interned<Self, C> {
|
fn intern(&self) -> Interned<Self> {
|
||||||
Self::intern_cow_with_ctx(Cow::Borrowed(self), context)
|
Self::intern_cow(Cow::Borrowed(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_owned_with_ctx(this: <Self as ToOwned>::Owned, context: &C) -> Interned<Self, C>
|
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
Self::intern_cow_with_ctx(Cow::Owned(this), context)
|
Self::intern_cow(Cow::Owned(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_cow_with_ctx(this: Cow<'_, Self>, context: &C) -> Interned<Self, C>
|
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
context.interner().intern_slice(context, this)
|
Interner::get().intern_slice(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: BitSliceInternContext> Intern<C> for BitSlice {
|
impl Intern for BitSlice {
|
||||||
fn intern_with_ctx(&self, context: &C) -> Interned<Self, C> {
|
fn intern(&self) -> Interned<Self> {
|
||||||
Self::intern_cow_with_ctx(Cow::Borrowed(self), context)
|
Self::intern_cow(Cow::Borrowed(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_owned_with_ctx(this: <Self as ToOwned>::Owned, context: &C) -> Interned<Self, C>
|
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
Self::intern_cow_with_ctx(Cow::Owned(this), context)
|
Self::intern_cow(Cow::Owned(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_cow_with_ctx(this: Cow<'_, Self>, context: &C) -> Interned<Self, C>
|
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
context.interner().intern_bit_slice(context, this)
|
Interner::get().intern_bit_slice(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: InternContext> Intern<C> for str {
|
impl Intern for str {
|
||||||
fn intern_with_ctx(&self, context: &C) -> Interned<Self, C> {
|
fn intern(&self) -> Interned<Self> {
|
||||||
Self::intern_cow_with_ctx(Cow::Borrowed(self), context)
|
Self::intern_cow(Cow::Borrowed(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_owned_with_ctx(this: <Self as ToOwned>::Owned, context: &C) -> Interned<Self, C>
|
fn intern_owned(this: <Self as ToOwned>::Owned) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
Self::intern_cow_with_ctx(Cow::Owned(this), context)
|
Self::intern_cow(Cow::Owned(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_cow_with_ctx(this: Cow<'_, Self>, context: &C) -> Interned<Self, C>
|
fn intern_cow(this: Cow<'_, Self>) -> Interned<Self>
|
||||||
where
|
where
|
||||||
Self: ToOwned,
|
Self: ToOwned,
|
||||||
{
|
{
|
||||||
context.interner().intern_str(context, this)
|
Interner::get().intern_str(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,6 @@ impl<T: Type> Index<T> for AsMaskWithoutGenerics {
|
||||||
type Output = T::MaskType;
|
type Output = T::MaskType;
|
||||||
|
|
||||||
fn index(&self, ty: T) -> &Self::Output {
|
fn index(&self, ty: T) -> &Self::Output {
|
||||||
Interned::<_>::into_inner(Intern::intern_sized(ty.mask_type()))
|
Interned::into_inner(Intern::intern_sized(ty.mask_type()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue