summaryrefslogtreecommitdiff
path: root/vendor/object/src/build/table.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/build/table.rs')
-rw-r--r--vendor/object/src/build/table.rs128
1 files changed, 128 insertions, 0 deletions
diff --git a/vendor/object/src/build/table.rs b/vendor/object/src/build/table.rs
new file mode 100644
index 00000000..63f276a5
--- /dev/null
+++ b/vendor/object/src/build/table.rs
@@ -0,0 +1,128 @@
+use alloc::vec::Vec;
+
+/// An item in a [`Table`].
+pub trait Item {
+ /// The type of identifier for the item.
+ type Id: Id;
+
+ /// Return `True` if the item is deleted.
+ fn is_deleted(&self) -> bool;
+}
+
+/// An identifier for referring to an item in a [`Table`].
+pub trait Id: IdPrivate {
+ /// Return the index of the item in the table.
+ fn index(&self) -> usize;
+}
+
+mod id_private {
+ pub trait IdPrivate {
+ fn new(id: usize) -> Self;
+ }
+}
+pub(super) use id_private::IdPrivate;
+
+/// A table of items.
+///
+/// Each item has a unique identifier.
+/// Items can be deleted without changing the identifiers of other items.
+#[derive(Debug)]
+pub struct Table<T>(Vec<T>);
+
+impl<T> Table<T> {
+ pub(super) fn new() -> Self {
+ Table(Vec::new())
+ }
+}
+
+impl<T: Item> Table<T> {
+ pub(super) fn next_id(&self) -> T::Id {
+ T::Id::new(self.0.len())
+ }
+
+ pub(super) fn push(&mut self, item: T) -> &mut T {
+ self.0.push(item);
+ self.0.last_mut().unwrap()
+ }
+
+ /// Number of items, including deleted items.
+ pub(super) fn len(&self) -> usize {
+ self.0.len()
+ }
+
+ /// Return `True` if there are no non-deleted items.
+ pub fn is_empty(&self) -> bool {
+ self.into_iter().next().is_none()
+ }
+
+ /// Number of non-deleted items.
+ pub fn count(&self) -> usize {
+ self.into_iter().count()
+ }
+
+ /// Return a reference to an item.
+ pub fn get(&self, id: T::Id) -> &T {
+ self.0.get(id.index()).unwrap()
+ }
+
+ /// Return a mutable reference to a segment.
+ pub fn get_mut(&mut self, id: T::Id) -> &mut T {
+ self.0.get_mut(id.index()).unwrap()
+ }
+
+ /// Return an iterator for the segments.
+ pub fn iter(&self) -> TableIter<'_, T> {
+ self.into_iter()
+ }
+
+ /// Return a mutable iterator for the segments.
+ pub fn iter_mut(&mut self) -> TableIterMut<'_, T> {
+ self.into_iter()
+ }
+}
+
+impl<'a, T: Item> IntoIterator for &'a Table<T> {
+ type Item = &'a T;
+ type IntoIter = TableIter<'a, T>;
+ fn into_iter(self) -> TableIter<'a, T> {
+ TableIter {
+ iter: self.0.iter(),
+ }
+ }
+}
+
+impl<'a, T: Item> IntoIterator for &'a mut Table<T> {
+ type Item = &'a mut T;
+ type IntoIter = TableIterMut<'a, T>;
+ fn into_iter(self) -> TableIterMut<'a, T> {
+ TableIterMut {
+ iter: self.0.iter_mut(),
+ }
+ }
+}
+
+/// An iterator for non-deleted items in a [`Table`].
+#[derive(Debug)]
+pub struct TableIter<'a, T> {
+ iter: core::slice::Iter<'a, T>,
+}
+
+impl<'a, T: Item> Iterator for TableIter<'a, T> {
+ type Item = &'a T;
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.find(|item| !item.is_deleted())
+ }
+}
+
+/// An iterator for non-deleted items in a [`Table`].
+#[derive(Debug)]
+pub struct TableIterMut<'a, T> {
+ iter: core::slice::IterMut<'a, T>,
+}
+
+impl<'a, T: Item> Iterator for TableIterMut<'a, T> {
+ type Item = &'a mut T;
+ fn next(&mut self) -> Option<&'a mut T> {
+ self.iter.find(|item| !item.is_deleted())
+ }
+}