mod handle; mod handle_set; mod handlevec; mod range; mod unique_arena;
pubuse handle::{BadHandle, Handle}; pub(crate) use handle_set::HandleSet; pub(crate) use handlevec::HandleVec; pubuse range::{BadRangeError, Range}; pubuse unique_arena::UniqueArena;
usecrate::Span;
use handle::Index;
use std::{fmt, ops};
/// An arena holding some kind of component (e.g., type, constant, /// instruction, etc.) that can be referenced. /// /// Adding new items to the arena produces a strongly-typed [`Handle`]. /// The arena can be indexed using the given handle to obtain /// a reference to the stored item. #[derive(Clone)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "serialize", serde(transparent))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(test, derive(PartialEq))] pubstruct Arena<T> { /// Values of this arena.
data: Vec<T>, #[cfg_attr(feature = "serialize", serde(skip))]
span_info: Vec<Span>,
}
impl<T> Arena<T> { /// Create a new arena with no initial capacity allocated. pubconstfn new() -> Self {
Arena {
data: Vec::new(),
span_info: Vec::new(),
}
}
/// Extracts the inner vector. #[allow(clippy::missing_const_for_fn)] // ignore due to requirement of #![feature(const_precise_live_drops)] pubfn into_inner(self) -> Vec<T> { self.data
}
/// Returns the current number of items stored in this arena. pubfn len(&self) -> usize { self.data.len()
}
/// Returns `true` if the arena contains no elements. pubfn is_empty(&self) -> bool { self.data.is_empty()
}
/// Returns an iterator over the items stored in this arena, returning both /// the item's handle and a reference to it. pubfn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> { self.data
.iter()
.enumerate()
.map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
}
/// Drains the arena, returning an iterator over the items stored. pubfn drain(&mutself) -> impl DoubleEndedIterator<Item = (Handle<T>, T, Span)> { let arena = std::mem::take(self);
arena
.data
.into_iter()
.zip(arena.span_info)
.enumerate()
.map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
}
/// Returns a iterator over the items stored in this arena, /// returning both the item's handle and a mutable reference to it. pubfn iter_mut(&mutself) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T)> { self.data
.iter_mut()
.enumerate()
.map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
}
/// Adds a new value to the arena, returning a typed handle. pubfn append(&mutself, value: T, span: Span) -> Handle<T> { let index = self.data.len(); self.data.push(value); self.span_info.push(span);
Handle::from_usize(index)
}
/// Fetch a handle to an existing type. pubfn fetch_if<F: Fn(&T) -> bool>(&self, fun: F) -> Option<Handle<T>> { self.data
.iter()
.position(fun)
.map(|index| unsafe { Handle::from_usize_unchecked(index) })
}
/// Adds a value with a custom check for uniqueness: /// returns a handle pointing to /// an existing element if the check succeeds, or adds a new /// element otherwise. pubfn fetch_if_or_append<F: Fn(&T, &T) -> bool>(
&mutself,
value: T,
span: Span,
fun: F,
) -> Handle<T> { iflet Some(index) = self.data.iter().position(|d| fun(d, &value)) { unsafe { Handle::from_usize_unchecked(index) }
} else { self.append(value, span)
}
}
/// Adds a value with a check for uniqueness, where the check is plain comparison. pubfn fetch_or_append(&mutself, value: T, span: Span) -> Handle<T> where
T: PartialEq,
{ self.fetch_if_or_append(value, span, T::eq)
}
/// Get a mutable reference to an element in the arena. pubfn get_mut(&mutself, handle: Handle<T>) -> &mut T { self.data.get_mut(handle.index()).unwrap()
}
/// Get the range of handles from a particular number of elements to the end. pubfn range_from(&self, old_length: usize) -> Range<T> { let range = old_length as u32..self.data.len() as u32;
Range::from_index_range(range, self)
}
/// Clears the arena keeping all allocations pubfn clear(&mutself) { self.data.clear()
}
/// Assert that `handle` is valid for this arena. pubfn check_contains_handle(&self, handle: Handle<T>) -> Result<(), BadHandle> { if handle.index() < self.data.len() {
Ok(())
} else {
Err(BadHandle::new(handle))
}
}
/// Assert that `range` is valid for this arena. pubfn check_contains_range(&self, range: &Range<T>) -> Result<(), BadRangeError> { // Since `range.inner` is a `Range<u32>`, we only need to check that the // start precedes the end, and that the end is in range. if range.inner.start > range.inner.end { return Err(BadRangeError::new(range.clone()));
}
// Empty ranges are tolerated: they can be produced by compaction. if range.inner.start == range.inner.end { return Ok(());
}
#[cfg(feature = "compact")] pub(crate) fn retain_mut<P>(&mutself, mut predicate: P) where
P: FnMut(Handle<T>, &mut T) -> bool,
{ letmut index = 0; letmut retained = 0; self.data.retain_mut(|elt| { let handle = Handle::from_usize(index); let keep = predicate(handle, elt);
// Since `predicate` needs mutable access to each element, // we can't feasibly call it twice, so we have to compact // spans by hand in parallel as part of this iteration. if keep { self.span_info[retained] = self.span_info[index];
retained += 1;
}
index += 1;
keep
});
self.span_info.truncate(retained);
}
}
#[cfg(feature = "deserialize")] impl<'de, T> serde::Deserialize<'de> for Arena<T> where
T: serde::Deserialize<'de>,
{ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
D: serde::Deserializer<'de>,
{ let data = Vec::deserialize(deserializer)?; let span_info = std::iter::repeat(Span::default())
.take(data.len())
.collect();
Ok(Self { data, span_info })
}
}
impl<T> ops::Index<Handle<T>> for Arena<T> { type Output = T; fn index(&self, handle: Handle<T>) -> &T {
&self.data[handle.index()]
}
}
impl<T> ops::IndexMut<Handle<T>> for Arena<T> { fn index_mut(&mutself, handle: Handle<T>) -> &mut T {
&mutself.data[handle.index()]
}
}
impl<T> ops::Index<Range<T>> for Arena<T> { type Output = [T]; fn index(&self, range: Range<T>) -> &[T] {
&self.data[range.inner.start as usize..range.inner.end as usize]
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.