From 0194c4a9ffa0fc3b77dedede9beeb1d0e0d5488f Mon Sep 17 00:00:00 2001 From: Aria Shrimpton Date: Sat, 24 Feb 2024 16:42:12 +0000 Subject: add iter method to container and make contains immutable --- Tasks.org | 4 ++++ src/crates/library/src/adaptive.rs | 12 +++++++++++- src/crates/library/src/eager_sorted_vector.rs | 21 +++++++++++---------- src/crates/library/src/eager_unique_vector.rs | 23 ++++++++++++----------- src/crates/library/src/hashset.rs | 9 ++++++++- src/crates/library/src/list.rs | 9 ++++++++- src/crates/library/src/profiler.rs | 21 ++++++++++++++------- src/crates/library/src/traits.rs | 7 ++++++- src/crates/library/src/treeset.rs | 9 ++++++++- src/crates/library/src/vector.rs | 14 ++++++++++---- 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, 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, HI: Default + Container fn clear(&mut self) { get_inner!(self, c, c.clear()) } + + fn iter<'a>(&'a self) -> impl Iterator + where + E: 'a, + { + match self { + AdaptiveContainer::Low(lo, _) => AdaptiveContainerIter::Low(lo.iter(), PhantomData), + AdaptiveContainer::High(hi) => AdaptiveContainerIter::High(hi.iter()), + } + } } impl FromIterator for AdaptiveContainer 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 EagerSortedVec { 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 EagerSortedVec { self.v.last() } - pub fn iter(&self) -> Iter<'_, T> { - self.v.iter() - } - pub fn to_vec(self) -> Vec { self.v } @@ -96,7 +91,7 @@ impl Container for EagerSortedVec { (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 Container for EagerSortedVec { (define (post-remove xs r) (equal? r (op-remove xs))) *ENDLIBSPEC*/ fn remove(&mut self, elt: T) -> Option { - 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 + 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 EagerUniqueVec { 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 EagerUniqueVec { self.v.last() } - pub fn iter(&self) -> Iter<'_, T> { - self.v.iter() - } - pub fn to_vec(self) -> Vec { self.v } @@ -103,7 +98,7 @@ impl Container for EagerUniqueVec { (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 Container for EagerUniqueVec { (define (post-remove xs r) (equal? r (op-remove xs))) *ENDLIBSPEC*/ fn remove(&mut self, elt: T) -> Option { - 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 + where + T: 'a, + { + self.v.iter() } } @@ -208,7 +209,7 @@ impl Indexable for EagerUniqueVec { (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 Container for HashSet { (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 Container for HashSet { false => None, } } + + fn iter<'a>(&'a self) -> impl Iterator + 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 Container for LinkedList { (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 Container for LinkedList { } } } + + fn iter<'a>(&'a self) -> impl Iterator + 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 { inner: Option, max_n: Cell, - n_contains: usize, + n_contains: Cell, n_insert: usize, n_clear: usize, n_remove: usize, @@ -30,7 +30,7 @@ impl Default for ProfilerWrapper { 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, E> Container for ProfilerWrapper 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, E> Container for ProfilerWrapper(&'a self) -> impl Iterator + where + E: 'a, + { + self.inner.as_ref().unwrap().iter() + } } impl + Container, E> Indexable @@ -136,7 +143,7 @@ impl Drop for ProfilerWrapper { 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 + Container, E> FromIterator 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: Default + IntoIterator + FromIterator { 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: Default + IntoIterator + FromIterator { /// Remove all elements from the container fn clear(&mut self); + + /// Iterate over all items in this container + fn iter<'a>(&'a self) -> impl Iterator + where + T: 'a; } pub trait Stack { 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 Container for BTreeSet { (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 Container for BTreeSet { false => None, } } + + fn iter<'a>(&'a self) -> impl Iterator + 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 Container for Vec { (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 Container for Vec { (define (post-remove xs r) (equal? r (op-remove xs))) *ENDLIBSPEC*/ fn remove(&mut self, elt: T) -> Option { - 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 + where + T: 'a, + { + (&self).into_iter() } } -- cgit v1.2.3