diff options
-rw-r--r-- | src/crates/library/src/adaptive.rs | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/crates/library/src/adaptive.rs b/src/crates/library/src/adaptive.rs index 5f21716..68bd42b 100644 --- a/src/crates/library/src/adaptive.rs +++ b/src/crates/library/src/adaptive.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use crate::traits::{Container, Mapping}; +use crate::traits::{Container, Indexable, Mapping, Stack}; use take_mut::take_or_recover; pub enum AdaptiveContainer<const THRESHOLD: usize, LO, HI, E> { @@ -82,6 +82,50 @@ impl<const THRESHOLD: usize, LO: Default + Container<E>, HI: Default + Container } } +impl< + const THRESHOLD: usize, + LO: Default + Container<E> + Stack<E>, + HI: Default + Container<E> + Stack<E>, + E, + > Stack<E> for AdaptiveContainer<THRESHOLD, LO, HI, E> +{ + fn push(&mut self, elt: E) { + get_inner!(self, c, c.push(elt)); + if let Self::Low(l, _) = self { + if l.len() < THRESHOLD { + return; + } + // adapt! + take_or_recover(self, Default::default, |old| { + let Self::Low(l, _) = old else { + unreachable!(); + }; + Self::High(HI::from_iter(l)) + }); + } + } + + fn pop(&mut self) -> Option<E> { + get_inner!(self, c, c.pop()) + } +} + +impl<const THRESHOLD: usize, LO: Default + Indexable<E>, HI: Default + Indexable<E>, E> Indexable<E> + for AdaptiveContainer<THRESHOLD, LO, HI, E> +{ + fn first(&self) -> Option<&E> { + get_inner!(self, c, c.first()) + } + + fn last(&self) -> Option<&E> { + get_inner!(self, c, c.last()) + } + + fn nth(&self, n: usize) -> Option<&E> { + get_inner!(self, c, c.nth(n)) + } +} + impl<const THRESHOLD: usize, LO, HI, K, V> Mapping<K, V> for AdaptiveContainer<THRESHOLD, LO, HI, (K, V)> where |