#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::{
alloc::{Layout, alloc, dealloc},
collections::VecDeque,
vec::Vec,
};
#[cfg(feature = "std")]
use std::{
alloc::{Layout, alloc, dealloc},
collections::VecDeque,
vec::Vec,
};
use core::marker::PhantomData;
use core::ops::{Index, IndexMut};
use core::{fmt, ptr};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub struct ArrayDeque<T> {
ptr: *mut T,
cap: usize,
len: usize,
idx: usize,
_marker: PhantomData<T>,
}
impl<T> ArrayDeque<T> {
pub fn new(cap: usize) -> Self {
assert!(cap > 0, "Capacity must be greater than zero");
let layout = Layout::array::<T>(cap).expect("Invalid layout");
let ptr = unsafe { alloc(layout) as *mut T };
if ptr.is_null() {
panic!("Failed to allocate memory");
}
Self {
ptr,
cap,
len: 0,
idx: 0,
_marker: PhantomData,
}
}
pub fn push_back(&mut self, value: T) {
let write_idx = (self.idx + self.len) % self.cap;
if self.len == self.cap {
unsafe {
ptr::drop_in_place(self.ptr.add(write_idx));
}
}
unsafe {
ptr::write(self.ptr.add(write_idx), value);
}
if self.len == self.cap {
self.idx = (self.idx + 1) % self.cap;
} else {
self.len += 1;
}
}
pub fn push_front(&mut self, value: T) {
self.idx = (self.idx + self.cap - 1) % self.cap;
if self.len == self.cap {
let drop_idx = (self.idx + self.len) % self.cap;
unsafe {
ptr::drop_in_place(self.ptr.add(drop_idx));
}
} else {
self.len += 1;
}
unsafe {
ptr::write(self.ptr.add(self.idx), value);
}
}
pub fn pop_back(&mut self) -> Option<T> {
if self.len == 0 {
return None;
}
let tail_idx = (self.idx + self.len - 1) % self.cap;
self.len -= 1;
Some(unsafe { ptr::read(self.ptr.add(tail_idx)) })
}
pub fn pop_front(&mut self) -> Option<T> {
if self.len == 0 {
return None;
}
let front_idx = self.idx;
self.idx = (self.idx + 1) % self.cap;
self.len -= 1;
Some(unsafe { ptr::read(self.ptr.add(front_idx)) })
}
pub fn front(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
Some(unsafe { &*self.ptr.add(self.idx) })
}
}
pub fn back(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
let back_idx = if self.idx + self.len <= self.cap {
self.idx + self.len - 1
} else {
(self.idx + self.len - 1) % self.cap
};
Some(unsafe { &*self.ptr.add(back_idx) })
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
(0..self.len).map(move |i| {
let idx = (self.idx + i) % self.cap;
unsafe { &*self.ptr.add(idx) }
})
}
pub fn capacity(&self) -> usize {
self.cap
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn is_full(&self) -> bool {
self.len == self.cap
}
pub fn clear(&mut self) {
for i in 0..self.len {
let idx = (self.idx + i) % self.cap;
unsafe {
ptr::drop_in_place(self.ptr.add(idx));
}
}
self.len = 0;
self.idx = 0;
}
}
impl<T> Drop for ArrayDeque<T> {
fn drop(&mut self) {
self.clear();
let layout = Layout::array::<T>(self.cap).expect("Invalid layout");
unsafe {
dealloc(self.ptr.cast(), layout);
}
}
}
impl<T: fmt::Debug> fmt::Debug for ArrayDeque<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T: Clone> Clone for ArrayDeque<T> {
fn clone(&self) -> Self {
let mut new = ArrayDeque::new(self.cap);
for item in self.iter() {
new.push_back(item.clone());
}
new
}
}
impl<T: PartialEq> PartialEq for ArrayDeque<T> {
fn eq(&self, other: &Self) -> bool {
self.len == other.len && self.iter().eq(other.iter())
}
}
impl<T: Eq> Eq for ArrayDeque<T> {}
impl<T> Index<usize> for ArrayDeque<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
assert!(index < self.len, "Index out of bounds");
let actual_idx = self.idx + index;
let actual_idx = if actual_idx >= self.cap {
actual_idx - self.cap
} else {
actual_idx
};
unsafe { &*self.ptr.add(actual_idx) }
}
}
impl<T> IndexMut<usize> for ArrayDeque<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
assert!(index < self.len);
let idx = (self.idx + index) % self.cap;
unsafe { &mut *self.ptr.add(idx) }
}
}
impl<T> Extend<T> for ArrayDeque<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for item in iter {
self.push_back(item);
}
}
}
impl<T> FromIterator<T> for ArrayDeque<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let vec: Vec<T> = iter.into_iter().collect();
let mut deque = ArrayDeque::new(vec.len().max(1));
deque.extend(vec);
deque
}
}
impl<T: Clone> From<&[T]> for ArrayDeque<T> {
fn from(slice: &[T]) -> Self {
let mut deque = ArrayDeque::new(slice.len().max(1));
for item in slice {
deque.push_back(item.clone());
}
deque
}
}
impl<T, const N: usize> From<[T; N]> for ArrayDeque<T> {
fn from(array: [T; N]) -> Self {
let mut deque = ArrayDeque::new(N.max(1));
for item in array {
deque.push_back(item);
}
deque
}
}
impl<T> From<Vec<T>> for ArrayDeque<T> {
fn from(vec: Vec<T>) -> Self {
let mut deque = ArrayDeque::new(vec.len().max(1));
for item in vec {
deque.push_back(item);
}
deque
}
}
impl<T> From<VecDeque<T>> for ArrayDeque<T> {
fn from(mut vec_deque: VecDeque<T>) -> Self {
let mut deque = ArrayDeque::new(vec_deque.len().max(1));
while let Some(item) = vec_deque.pop_front() {
deque.push_back(item);
}
deque
}
}
impl<T> From<ArrayDeque<T>> for VecDeque<T> {
fn from(deque: ArrayDeque<T>) -> Self {
deque.into_iter().collect()
}
}
impl<T: Clone> From<&ArrayDeque<T>> for VecDeque<T> {
fn from(deque: &ArrayDeque<T>) -> Self {
deque.iter().cloned().collect()
}
}
impl<T: Clone> From<&Vec<T>> for ArrayDeque<T> {
fn from(vec: &Vec<T>) -> Self {
let mut deque = ArrayDeque::new(vec.len().max(1));
for item in vec {
deque.push_back(item.clone());
}
deque
}
}
impl<T: Clone, const N: usize> From<&[T; N]> for ArrayDeque<T> {
fn from(array: &[T; N]) -> Self {
let mut deque = ArrayDeque::new(N.max(1));
for item in array {
deque.push_back(item.clone());
}
deque
}
}
#[cfg(feature = "serde")]
impl<T: Serialize> Serialize for ArrayDeque<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.len))?;
for item in self.iter() {
seq.serialize_element(item)?;
}
seq.end()
}
}
#[cfg(feature = "serde")]
impl<'de, T: Deserialize<'de>> Deserialize<'de> for ArrayDeque<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let vec: Vec<T> = Vec::deserialize(deserializer)?;
Ok(ArrayDeque::from(vec))
}
}
impl<T> IntoIterator for ArrayDeque<T> {
type Item = T;
type IntoIter = ArrayDequeIntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
ArrayDequeIntoIter { deque: self }
}
}
pub struct ArrayDequeIntoIter<T> {
deque: ArrayDeque<T>,
}
impl<T> Iterator for ArrayDequeIntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.deque.pop_front()
}
}
impl<'a, T> IntoIterator for &'a ArrayDeque<T> {
type Item = &'a T;
type IntoIter = ArrayDequeIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
ArrayDequeIter {
deque: self,
pos: 0,
}
}
}
pub struct ArrayDequeIter<'a, T> {
deque: &'a ArrayDeque<T>,
pos: usize,
}
impl<'a, T> Iterator for ArrayDequeIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
if self.pos >= self.deque.len {
return None;
}
let idx = (self.deque.idx + self.pos) % self.deque.cap;
self.pos += 1;
unsafe { Some(&*self.deque.ptr.add(idx)) }
}
}
impl<'a, T> ExactSizeIterator for ArrayDequeIter<'a, T> {}
#[cfg(test)]
mod tests {
use super::*;
use core::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(feature = "std"))]
use alloc::{sync::Arc, vec};
#[cfg(feature = "std")]
use std::sync::Arc;
#[derive(Clone)]
struct DropCounter {
drops: Arc<AtomicUsize>,
}
impl DropCounter {
fn new(drops: Arc<AtomicUsize>) -> Self {
Self { drops }
}
}
impl Drop for DropCounter {
fn drop(&mut self) {
self.drops.fetch_add(1, Ordering::SeqCst);
}
}
#[test]
fn push_pop() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
assert_eq!(deque.pop_front(), Some(1));
assert_eq!(deque.pop_back(), Some(3));
assert_eq!(deque.pop_front(), Some(2));
assert_eq!(deque.pop_front(), None);
}
#[test]
fn push_front_back() {
let mut deque = ArrayDeque::new(3);
deque.push_front(1);
deque.push_front(2);
deque.push_back(3);
assert_eq!(deque.pop_front(), Some(2));
assert_eq!(deque.pop_back(), Some(3));
assert_eq!(deque.pop_front(), Some(1));
assert_eq!(deque.pop_front(), None);
}
#[test]
fn iter() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
let mut iter = deque.iter();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
}
#[test]
fn clear() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.clear();
assert!(deque.is_empty());
assert_eq!(deque.len(), 0);
}
#[test]
fn capacity() {
let deque = ArrayDeque::<i32>::new(5);
assert_eq!(deque.capacity(), 5);
assert!(deque.is_empty());
}
#[test]
fn clone() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
let cloned_deque = deque.clone();
assert_eq!(cloned_deque.len(), 2);
assert_eq!(cloned_deque[0], 1);
assert_eq!(cloned_deque[1], 2);
}
#[test]
fn from_iter() {
let vec = vec![1, 2, 3];
let deque: ArrayDeque<_> = vec.into_iter().collect();
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
fn from_slice() {
let slice = [1, 2, 3];
let deque: ArrayDeque<_> = ArrayDeque::from(&slice[..]);
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
fn from_array() {
let array = [1, 2, 3];
let deque: ArrayDeque<_> = ArrayDeque::from(array);
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
fn index() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
#[should_panic]
fn index_out_of_bounds_panics() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
let _ = deque[1];
}
#[test]
fn index_mut() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
deque[0] = 10;
assert_eq!(deque[0], 10);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
#[should_panic]
fn index_mut_out_of_bounds_panics() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque[1] = 99;
}
#[test]
fn extend() {
let mut deque = ArrayDeque::new(5);
deque.extend(vec![1, 2, 3]);
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
fn into_iter() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
let mut iter = deque.into_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), None);
}
#[test]
fn into_iter_empty() {
let deque: ArrayDeque<i32> = ArrayDeque::new(5);
let mut iter = deque.into_iter();
assert_eq!(iter.next(), None);
}
#[test]
fn into_iter_full() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
let mut iter = deque.into_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), None);
}
#[test]
fn into_iter_partial() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
let mut iter = deque.into_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
}
#[test]
fn iter_empty() {
let deque: ArrayDeque<i32> = ArrayDeque::new(5);
let mut iter = deque.iter();
assert_eq!(iter.next(), None);
}
#[test]
fn iter_full() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
let mut iter = deque.iter();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
}
#[test]
fn iter_partial() {
let mut deque = ArrayDeque::new(5);
deque.push_back(1);
deque.push_back(2);
let mut iter = deque.iter();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
}
#[test]
fn is_empty() {
let deque: ArrayDeque<i32> = ArrayDeque::new(5);
assert!(deque.is_empty());
assert_eq!(deque.len(), 0);
}
#[test]
fn is_full() {
let mut deque = ArrayDeque::new(3);
assert!(!deque.is_full());
deque.push_back(1);
deque.push_back(2);
assert!(!deque.is_full());
deque.push_back(3);
assert!(deque.is_full());
}
#[test]
fn clear_empty() {
let mut deque = ArrayDeque::<()>::new(3);
deque.clear();
assert!(deque.is_empty());
assert_eq!(deque.len(), 0);
}
#[test]
fn clear_non_empty() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.clear();
assert!(deque.is_empty());
assert_eq!(deque.len(), 0);
}
#[test]
fn push_back_overwrite_drops_replaced_element() {
let drops = Arc::new(AtomicUsize::new(0));
{
let mut deque = ArrayDeque::new(2);
deque.push_back(DropCounter::new(drops.clone()));
deque.push_back(DropCounter::new(drops.clone()));
deque.push_back(DropCounter::new(drops.clone()));
assert_eq!(drops.load(Ordering::SeqCst), 1);
}
assert_eq!(drops.load(Ordering::SeqCst), 3);
}
#[test]
fn into_iter_partial_consumption_no_double_drop() {
let drops = Arc::new(AtomicUsize::new(0));
{
let mut deque = ArrayDeque::new(2);
deque.push_back(DropCounter::new(drops.clone()));
deque.push_back(DropCounter::new(drops.clone()));
let mut iter = deque.into_iter();
let _first = iter.next();
assert_eq!(drops.load(Ordering::SeqCst), 0);
}
assert_eq!(drops.load(Ordering::SeqCst), 2);
}
#[test]
fn from_empty_slice_is_empty_with_min_capacity() {
let slice: &[i32] = &[];
let deque = ArrayDeque::from(slice);
assert!(deque.is_empty());
assert_eq!(deque.capacity(), 1);
}
#[test]
fn from_vecdeque_preserves_order_and_len() {
let vec_deque: VecDeque<_> = [1, 2, 3].into_iter().collect();
let deque = ArrayDeque::from(vec_deque);
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
#[test]
fn into_vecdeque_preserves_order() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
let vec_deque: VecDeque<_> = VecDeque::from(deque);
assert_eq!(vec_deque.into_iter().collect::<Vec<_>>(), vec![1, 2, 3]);
}
#[test]
#[cfg(feature = "serde")]
fn serde_serialize() {
let mut deque = ArrayDeque::new(3);
deque.push_back(1);
deque.push_back(2);
let serialized = serde_json::to_string(&deque).unwrap();
assert_eq!(serialized, "[1,2]");
}
#[test]
#[cfg(feature = "serde")]
fn serde_deserialize() {
let serialized = "[1,2,3]";
let deque: ArrayDeque<i32> = serde_json::from_str(serialized).unwrap();
assert_eq!(deque.len(), 3);
assert_eq!(deque[0], 1);
assert_eq!(deque[1], 2);
assert_eq!(deque[2], 3);
}
}