use cc_traits::{Back, Collection, PushBack}; #[cfg(feature = "std")] use std::collections::VecDeque; /// Ordered stack. #[derive(Default)] pub struct Ordered { inner: S, } impl Ordered { pub fn new() -> Self where S: Default, { Default::default() } } impl Ordered { /// Push the given element on the stack iff it is grater or equal /// to every other element already in the stack. pub fn try_push(&mut self, element: T) -> Result<(), T> where T: PartialOrd, S: Collection + Back + PushBack, // `S` must be a stack providing `back` and `push_back`. for<'a> S::ItemRef<'a>: PartialOrd<&'a T>, // The reference type must be comparable with other reference types. { if self .inner .back() .map(|back| back <= &element) .unwrap_or(true) { self.inner.push_back(element); Ok(()) } else { Err(element) } } } fn main() { #[cfg(feature = "std")] fn ordered_stack_usage() where S: Default + Collection + Back + PushBack, for<'a> S::ItemRef<'a>: PartialOrd<&'a i32>, { let mut ordered: Ordered = Ordered::new(); assert!(ordered.try_push(1).is_ok()); assert!(ordered.try_push(2).is_ok()); assert!(ordered.try_push(0).is_err()); } #[cfg(feature = "std")] ordered_stack_usage::>(); // a `Vec` is a stack so it works. #[cfg(feature = "std")] ordered_stack_usage::>(); // a `VecDeque` is also a stack. }