diff --git a/CHANGELOG.md b/CHANGELOG.md index f933d976..1e51c629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `VecView`, the `!Sized` version of `Vec`. - Added pool implementations for 64-bit architectures. - Added `IntoIterator` implementation for `LinearMap` +- Added `Deque::{get, get_mut, get_unchecked, get_unchecked_mut}`. ### Changed diff --git a/src/deque.rs b/src/deque.rs index 9e923539..b596086d 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -535,6 +535,62 @@ impl Deque { done, } } + + /// Returns a reference to the element at the given index. + /// + /// Index 0 is the front of the `Deque`. + pub fn get(&self, index: usize) -> Option<&T> { + if index < self.len() { + let idx = self.to_physical_index(index); + Some(unsafe { self.buffer.get_unchecked(idx).assume_init_ref() }) + } else { + None + } + } + + /// Returns a mutable reference to the element at the given index. + /// + /// Index 0 is the front of the `Deque`. + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + if index < self.len() { + let idx = self.to_physical_index(index); + Some(unsafe { self.buffer.get_unchecked_mut(idx).assume_init_mut() }) + } else { + None + } + } + + /// Returns a reference to the element at the given index without checking if it exists. + /// + /// # Safety + /// + /// The element at the given `index` must exist (i.e. `index < self.len()`). + pub unsafe fn get_unchecked(&self, index: usize) -> &T { + debug_assert!(index < self.len()); + + let idx = self.to_physical_index(index); + self.buffer.get_unchecked(idx).assume_init_ref() + } + + /// Returns a mutable reference to the element at the given index without checking if it exists. + /// + /// # Safety + /// + /// The element at the given `index` must exist (i.e. `index < self.len()`). + pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + debug_assert!(index < self.len()); + + let idx = self.to_physical_index(index); + self.buffer.get_unchecked_mut(idx).assume_init_mut() + } + + fn to_physical_index(&self, index: usize) -> usize { + let mut res = self.front + index; + if res >= N { + res -= N; + } + res + } } // Trait implementations @@ -1099,4 +1155,52 @@ mod tests { // Deque contains: 5, 6, 7, 8 assert_eq!(q.as_slices(), ([5, 6, 7, 8].as_slice(), [].as_slice())); } + + #[test] + fn get() { + let mut q: Deque = Deque::new(); + assert_eq!(q.get(0), None); + + q.push_back(0).unwrap(); + assert_eq!(q.get(0), Some(&0)); + assert_eq!(q.get(1), None); + + q.push_back(1).unwrap(); + assert_eq!(q.get(0), Some(&0)); + assert_eq!(q.get(1), Some(&1)); + assert_eq!(q.get(2), None); + + q.pop_front().unwrap(); + assert_eq!(q.get(0), Some(&1)); + assert_eq!(q.get(1), None); + + q.push_back(2).unwrap(); + q.push_back(3).unwrap(); + q.push_back(4).unwrap(); + assert_eq!(q.get(0), Some(&1)); + assert_eq!(q.get(1), Some(&2)); + assert_eq!(q.get(2), Some(&3)); + assert_eq!(q.get(3), Some(&4)); + } + + #[test] + fn get_mut() { + let mut q: Deque = Deque::new(); + assert_eq!(q.get(0), None); + + q.push_back(0).unwrap(); + assert_eq!(q.get_mut(0), Some(&mut 0)); + assert_eq!(q.get_mut(1), None); + + q.push_back(1).unwrap(); + assert_eq!(q.get_mut(0), Some(&mut 0)); + assert_eq!(q.get_mut(1), Some(&mut 1)); + assert_eq!(q.get_mut(2), None); + *q.get_mut(0).unwrap() = 42; + *q.get_mut(1).unwrap() = 43; + + assert_eq!(q.pop_front(), Some(42)); + assert_eq!(q.pop_front(), Some(43)); + assert_eq!(q.pop_front(), None); + } }