aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAria Shrimpton <me@aria.rip>2024-02-24 16:42:12 +0000
committerAria Shrimpton <me@aria.rip>2024-02-24 16:42:12 +0000
commit0194c4a9ffa0fc3b77dedede9beeb1d0e0d5488f (patch)
tree22a0e7f4264167775ef2b60565d3b09c6d0a77f0
parent1741057ebb734d97acc4edfc84dcc2d62b8789f1 (diff)
add iter method to container and make contains immutable
-rw-r--r--Tasks.org4
-rw-r--r--src/crates/library/src/adaptive.rs12
-rw-r--r--src/crates/library/src/eager_sorted_vector.rs21
-rw-r--r--src/crates/library/src/eager_unique_vector.rs23
-rw-r--r--src/crates/library/src/hashset.rs9
-rw-r--r--src/crates/library/src/list.rs9
-rw-r--r--src/crates/library/src/profiler.rs21
-rw-r--r--src/crates/library/src/traits.rs7
-rw-r--r--src/crates/library/src/treeset.rs9
-rw-r--r--src/crates/library/src/vector.rs14
10 files changed, 92 insertions, 37 deletions
diff --git a/Tasks.org b/Tasks.org
index 98bf0fb..6ed50ef 100644
--- a/Tasks.org
+++ b/Tasks.org
@@ -236,6 +236,10 @@ Ideas:
require_cdr fuckery
renaming of op- stuff
boolean literals
+problems with trait bounds on element types
+and on being able to implement traits w/ types using container types because of opaqueness
+iterator trait stuff
+mutable borrows in methods
*** TODO Integration w/ Cargo
diff --git a/src/crates/library/src/adaptive.rs b/src/crates/library/src/adaptive.rs
index e464602..17be55b 100644
--- a/src/crates/library/src/adaptive.rs
+++ b/src/crates/library/src/adaptive.rs
@@ -36,7 +36,7 @@ impl<const THRESHOLD: usize, LO: Default + Container<E>, HI: Default + Container
get_inner!(self, c, c.is_empty())
}
- fn contains(&mut self, x: &E) -> bool {
+ fn contains(&self, x: &E) -> bool {
get_inner!(self, c, c.contains(x))
}
@@ -63,6 +63,16 @@ impl<const THRESHOLD: usize, LO: Default + Container<E>, HI: Default + Container
fn clear(&mut self) {
get_inner!(self, c, c.clear())
}
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a E>
+ where
+ E: 'a,
+ {
+ match self {
+ AdaptiveContainer::Low(lo, _) => AdaptiveContainerIter::Low(lo.iter(), PhantomData),
+ AdaptiveContainer::High(hi) => AdaptiveContainerIter::High(hi.iter()),
+ }
+ }
}
impl<const THRESHOLD: usize, LO, HI, E> FromIterator<E> for AdaptiveContainer<THRESHOLD, LO, HI, E>
diff --git a/src/crates/library/src/eager_sorted_vector.rs b/src/crates/library/src/eager_sorted_vector.rs
index 2ea6bde..0df0ab4 100644
--- a/src/crates/library/src/eager_sorted_vector.rs
+++ b/src/crates/library/src/eager_sorted_vector.rs
@@ -4,7 +4,6 @@ rust-eager-sorted-vec-spec primrose_library::EagerSortedVec
use crate::traits::{Container, Indexable};
-use std::slice::Iter;
use std::vec::Vec;
/// A Sorted Vector
@@ -27,7 +26,7 @@ impl<T: Ord> EagerSortedVec<T> {
self.v.len()
}
- pub fn contains(&mut self, x: &T) -> bool {
+ pub fn contains(&self, x: &T) -> bool {
self.v.binary_search(x).is_ok()
}
@@ -60,10 +59,6 @@ impl<T: Ord> EagerSortedVec<T> {
self.v.last()
}
- pub fn iter(&self) -> Iter<'_, T> {
- self.v.iter()
- }
-
pub fn to_vec(self) -> Vec<T> {
self.v
}
@@ -96,7 +91,7 @@ impl<T: Ord> Container<T> for EagerSortedVec<T> {
(define (pre-contains xs) (equal? xs (sort xs <)))
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
EagerSortedVec::contains(self, x)
}
@@ -148,9 +143,15 @@ impl<T: Ord> Container<T> for EagerSortedVec<T> {
(define (post-remove xs r) (equal? r (op-remove xs)))
*ENDLIBSPEC*/
fn remove(&mut self, elt: T) -> Option<T> {
- self.iter()
- .position(|x| *x == elt)
- .map(|index| self.remove(index))
+ let idx = self.v.binary_search(&elt).ok()?;
+ Some(self.v.remove(idx))
+ }
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ self.v.iter()
}
}
diff --git a/src/crates/library/src/eager_unique_vector.rs b/src/crates/library/src/eager_unique_vector.rs
index 2e2d00d..da98421 100644
--- a/src/crates/library/src/eager_unique_vector.rs
+++ b/src/crates/library/src/eager_unique_vector.rs
@@ -4,7 +4,6 @@ rust-eager-unique-vec-spec primrose_library::EagerUniqueVec
use crate::traits::{Container, Indexable};
-use std::slice::Iter;
use std::vec::Vec;
/// A Unique Vector
@@ -32,7 +31,7 @@ impl<T: PartialEq> EagerUniqueVec<T> {
self.v.len()
}
- pub fn contains(&mut self, x: &T) -> bool {
+ pub fn contains(&self, x: &T) -> bool {
self.v.contains(x)
}
@@ -67,10 +66,6 @@ impl<T: PartialEq> EagerUniqueVec<T> {
self.v.last()
}
- pub fn iter(&self) -> Iter<'_, T> {
- self.v.iter()
- }
-
pub fn to_vec(self) -> Vec<T> {
self.v
}
@@ -103,7 +98,7 @@ impl<T: Ord + PartialEq> Container<T> for EagerUniqueVec<T> {
(define (pre-contains xs) (equal? xs (remove-duplicates xs)))
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
EagerUniqueVec::contains(self, x) // use fully qualified syntax to avoid function name collision
}
@@ -155,9 +150,15 @@ impl<T: Ord + PartialEq> Container<T> for EagerUniqueVec<T> {
(define (post-remove xs r) (equal? r (op-remove xs)))
*ENDLIBSPEC*/
fn remove(&mut self, elt: T) -> Option<T> {
- self.iter()
- .position(|x| *x == elt)
- .map(|index| self.remove(index))
+ let idx = self.iter().position(|x| *x == elt)?;
+ Some(self.v.remove(idx))
+ }
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ self.v.iter()
}
}
@@ -208,7 +209,7 @@ impl<T: PartialEq> Indexable<T> for EagerUniqueVec<T> {
(define (post-nth xs n r) (equal? r (op-nth xs n)))
*ENDLIBSPEC*/
fn nth(&self, n: usize) -> Option<&T> {
- EagerUniqueVec::iter(self).nth(n)
+ self.v.get(n)
}
}
diff --git a/src/crates/library/src/hashset.rs b/src/crates/library/src/hashset.rs
index f8f637c..9c52049 100644
--- a/src/crates/library/src/hashset.rs
+++ b/src/crates/library/src/hashset.rs
@@ -33,7 +33,7 @@ impl<T: Ord + Hash> Container<T> for HashSet<T> {
(define (pre-contains xs) (equal? xs (remove-duplicates (sort xs <))))
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
HashSet::contains(self, x)
}
@@ -90,6 +90,13 @@ impl<T: Ord + Hash> Container<T> for HashSet<T> {
false => None,
}
}
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ (&self).into_iter()
+ }
}
#[cfg(test)]
diff --git a/src/crates/library/src/list.rs b/src/crates/library/src/list.rs
index 8ccb146..061f1b4 100644
--- a/src/crates/library/src/list.rs
+++ b/src/crates/library/src/list.rs
@@ -34,7 +34,7 @@ impl<T: Ord> Container<T> for LinkedList<T> {
(define (pre-contains xs) #t)
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
LinkedList::contains(self, x)
}
@@ -100,6 +100,13 @@ impl<T: Ord> Container<T> for LinkedList<T> {
}
}
}
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ (&self).into_iter()
+ }
}
/*IMPL*
diff --git a/src/crates/library/src/profiler.rs b/src/crates/library/src/profiler.rs
index 1b58a21..ebedd28 100644
--- a/src/crates/library/src/profiler.rs
+++ b/src/crates/library/src/profiler.rs
@@ -12,7 +12,7 @@ use crate::traits::{Container, Indexable, Mapping, Stack};
pub struct ProfilerWrapper<const ID: usize, T, E> {
inner: Option<T>,
max_n: Cell<usize>,
- n_contains: usize,
+ n_contains: Cell<usize>,
n_insert: usize,
n_clear: usize,
n_remove: usize,
@@ -30,7 +30,7 @@ impl<const ID: usize, T: Default, E> Default for ProfilerWrapper<ID, T, E> {
Self {
inner: Some(T::default()),
max_n: Cell::new(0),
- n_contains: 0,
+ n_contains: Cell::new(0),
n_insert: 0,
n_clear: 0,
n_remove: 0,
@@ -57,10 +57,10 @@ impl<const ID: usize, T: Container<E>, E> Container<E> for ProfilerWrapper<ID, T
self.inner.as_ref().unwrap().len()
}
- fn contains(&mut self, x: &E) -> bool {
+ fn contains(&self, x: &E) -> bool {
self.add_n();
- self.n_contains += 1;
- self.inner.as_mut().unwrap().contains(x)
+ self.n_contains.set(self.n_contains.get() + 1);
+ self.inner.as_ref().unwrap().contains(x)
}
fn is_empty(&self) -> bool {
@@ -84,6 +84,13 @@ impl<const ID: usize, T: Container<E>, E> Container<E> for ProfilerWrapper<ID, T
self.n_remove += 1;
self.inner.as_mut().unwrap().remove(elt)
}
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a E>
+ where
+ E: 'a,
+ {
+ self.inner.as_ref().unwrap().iter()
+ }
}
impl<const ID: usize, T: Indexable<E> + Container<E>, E> Indexable<E>
@@ -136,7 +143,7 @@ impl<const ID: usize, T, E> Drop for ProfilerWrapper<ID, T, E> {
let mut f = File::create(format!("{}/{}", dir, unix_time.as_nanos())).unwrap();
writeln!(f, "{}", self.max_n.get()).unwrap();
- writeln!(f, "{}", self.n_contains).unwrap();
+ writeln!(f, "{}", self.n_contains.get()).unwrap();
writeln!(f, "{}", self.n_insert).unwrap();
writeln!(f, "{}", self.n_clear).unwrap();
writeln!(f, "{}", self.n_remove).unwrap();
@@ -167,7 +174,7 @@ impl<const ID: usize, C: FromIterator<E> + Container<E>, E> FromIterator<E>
Self {
max_n: Cell::new(c.len()),
inner: Some(c),
- n_contains: 0,
+ n_contains: Cell::new(0),
n_insert: 0,
n_clear: 0,
n_remove: 0,
diff --git a/src/crates/library/src/traits.rs b/src/crates/library/src/traits.rs
index 8af7df6..35e91c1 100644
--- a/src/crates/library/src/traits.rs
+++ b/src/crates/library/src/traits.rs
@@ -8,7 +8,7 @@ pub trait Container<T>: Default + IntoIterator<Item = T> + FromIterator<T> {
fn is_empty(&self) -> bool;
/// Check if the specified item is in the container
- fn contains(&mut self, x: &T) -> bool;
+ fn contains(&self, x: &T) -> bool;
/// Insert the given item
fn insert(&mut self, elt: T);
@@ -18,6 +18,11 @@ pub trait Container<T>: Default + IntoIterator<Item = T> + FromIterator<T> {
/// Remove all elements from the container
fn clear(&mut self);
+
+ /// Iterate over all items in this container
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a;
}
pub trait Stack<T> {
diff --git a/src/crates/library/src/treeset.rs b/src/crates/library/src/treeset.rs
index 8845d33..ad3b60d 100644
--- a/src/crates/library/src/treeset.rs
+++ b/src/crates/library/src/treeset.rs
@@ -32,7 +32,7 @@ impl<T: Ord> Container<T> for BTreeSet<T> {
(define (pre-contains xs) (equal? xs (remove-duplicates (sort xs <))))
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
BTreeSet::contains(self, x)
}
@@ -89,6 +89,13 @@ impl<T: Ord> Container<T> for BTreeSet<T> {
false => None,
}
}
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ (&self).into_iter()
+ }
}
/*IMPL*
diff --git a/src/crates/library/src/vector.rs b/src/crates/library/src/vector.rs
index 3555f6c..19d0179 100644
--- a/src/crates/library/src/vector.rs
+++ b/src/crates/library/src/vector.rs
@@ -32,7 +32,7 @@ impl<T: PartialEq> Container<T> for Vec<T> {
(define (pre-contains xs) #t)
(define (post-contains xs x r) (equal? r (op-contains xs x)))
*ENDLIBSPEC*/
- fn contains(&mut self, x: &T) -> bool {
+ fn contains(&self, x: &T) -> bool {
<[T]>::contains(self, x) // use fully qualified syntax to avoid function name collision
}
@@ -84,9 +84,15 @@ impl<T: PartialEq> Container<T> for Vec<T> {
(define (post-remove xs r) (equal? r (op-remove xs)))
*ENDLIBSPEC*/
fn remove(&mut self, elt: T) -> Option<T> {
- self.iter()
- .position(|x| *x == elt)
- .map(|index| self.remove(index))
+ let idx = self.iter().position(|x| *x == elt)?;
+ Some(Vec::remove(self, idx))
+ }
+
+ fn iter<'a>(&'a self) -> impl Iterator<Item = &'a T>
+ where
+ T: 'a,
+ {
+ (&self).into_iter()
}
}