| Crates.io | array-deque |
| lib.rs | array-deque |
| version | 0.3.1 |
| created_at | 2025-06-10 22:21:53.157422+00 |
| updated_at | 2025-06-10 23:48:14.570048+00 |
| description | Fixed-capacity circular buffer implementations: heap-allocated ArrayDeque and stack-allocated StackArrayDeque. Efficient O(1) operations, no_std support. |
| homepage | https://github.com/0x7030676e31/array-deque |
| repository | https://github.com/0x7030676e31/array-deque |
| max_upload_size | |
| id | 1707814 |
| size | 64,672 |
A collection of fixed-capacity circular buffer (ring buffer) implementations providing efficient double-ended queue operations. This crate offers both heap-allocated and stack-allocated variants, making it suitable for a wide range of use cases from general applications to embedded systems.
This crate provides two deque implementations:
ArrayDeque: Heap-allocated with runtime-determined capacityStackArrayDeque: Stack-allocated with compile-time fixed capacityBoth implementations use circular buffers for efficient O(1) operations at both ends and will overwrite old elements when full.
StackArrayDeque uses no heap memory at allno_std environments (with alloc for ArrayDeque)serde feature)IntoIteratorAdd this to your Cargo.toml:
[dependencies]
array-deque = "0.3.1"
# For serde support
array-deque = { version = "0.3.1", features = ["serde"] }
# For no_std environments (requires alloc for ArrayDeque)
array-deque = { version = "0.3.1", default-features = false }
# For no_std with serde
array-deque = { version = "0.3.1", default-features = false, features = ["serde"] }
Use ArrayDeque when:
Use StackArrayDeque when:
use array_deque::ArrayDeque;
// Create a deque with capacity for 5 elements
let mut deque = ArrayDeque::new(5);
// Add elements to the back
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
// Add elements to the front
deque.push_front(0);
// Access elements by index (0 = front, len-1 = back)
assert_eq!(deque[0], 0); // front element
assert_eq!(deque[1], 1);
assert_eq!(deque[2], 2);
assert_eq!(deque[3], 3); // back element
// Remove elements
assert_eq!(deque.pop_front(), Some(0));
assert_eq!(deque.pop_back(), Some(3));
use array_deque::StackArrayDeque;
// Create a stack-allocated deque with compile-time capacity
let mut deque: StackArrayDeque<i32, 5> = StackArrayDeque::new();
// Same API as ArrayDeque
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
deque.push_front(0);
assert_eq!(deque[0], 0);
assert_eq!(deque[1], 1);
assert_eq!(deque[2], 2);
assert_eq!(deque[3], 3);
assert_eq!(deque.pop_front(), Some(0));
assert_eq!(deque.pop_back(), Some(3));
Both implementations behave identically when reaching capacity:
use array_deque::{ArrayDeque, StackArrayDeque};
// Heap-allocated version
let mut heap_deque = ArrayDeque::new(3);
heap_deque.push_back(1);
heap_deque.push_back(2);
heap_deque.push_back(3);
heap_deque.push_back(4); // Overwrites 1
// Deque is now: [2, 3, 4]
// Stack-allocated version
let mut stack_deque: StackArrayDeque<i32, 3> = StackArrayDeque::new();
stack_deque.push_back(1);
stack_deque.push_back(2);
stack_deque.push_back(3);
stack_deque.push_back(4); // Overwrites 1
// Deque is now: [2, 3, 4]
Both types support the same iteration patterns:
use array_deque::{ArrayDeque, StackArrayDeque};
// ArrayDeque
let mut heap_deque = ArrayDeque::new(5);
heap_deque.extend(vec![1, 2, 3, 4, 5]);
// StackArrayDeque
let mut stack_deque: StackArrayDeque<i32, 5> = StackArrayDeque::new();
for i in 1..=5 {
stack_deque.push_back(i);
}
// Both support iteration by reference
for item in &heap_deque {
println!("{}", item);
}
for item in stack_deque.iter() {
println!("{}", item);
}
ArrayDeque supports creation from various collections:
use array_deque::ArrayDeque;
// From array
let deque = ArrayDeque::from([1, 2, 3, 4, 5]);
// From vector
let deque = ArrayDeque::from(vec![1, 2, 3]);
// From slice
let slice = &[1, 2, 3];
let deque = ArrayDeque::from(slice);
// From iterator
let deque: ArrayDeque<i32> = (1..=5).collect();
StackArrayDeque must be created with new() and populated manually:
use array_deque::StackArrayDeque;
let mut deque: StackArrayDeque<i32, 5> = StackArrayDeque::new();
for i in 1..=5 {
deque.push_back(i);
}
Both types work in no_std environments:
#![no_std]
extern crate alloc; // Only needed for ArrayDeque
use array_deque::{ArrayDeque, StackArrayDeque};
use alloc::vec;
// ArrayDeque requires alloc
let mut heap_deque = ArrayDeque::new(3);
heap_deque.extend(vec![1, 2, 3]);
// StackArrayDeque works without alloc
let mut stack_deque: StackArrayDeque<i32, 3> = StackArrayDeque::new();
stack_deque.push_back(1);
stack_deque.push_back(2);
stack_deque.push_back(3);
With the serde feature enabled, both types support serialization:
use array_deque::{ArrayDeque, StackArrayDeque};
use serde_json;
// ArrayDeque
let mut heap_deque = ArrayDeque::new(3);
heap_deque.extend(vec![1, 2, 3]);
let json = serde_json::to_string(&heap_deque).unwrap();
// StackArrayDeque
let mut stack_deque: StackArrayDeque<i32, 3> = StackArrayDeque::new();
stack_deque.push_back(1);
stack_deque.push_back(2);
stack_deque.push_back(3);
let json_stack = serde_json::to_string(&stack_deque).unwrap();
Both ArrayDeque and StackArrayDeque share the same core API:
new() - Create a new deque (new(capacity) for ArrayDeque, new() for StackArrayDeque)push_back(item) - Add element to the backpush_front(item) - Add element to the frontpop_back() - Remove and return back elementpop_front() - Remove and return front elementlen() - Number of elements currently storedcapacity() - Maximum number of elementsis_empty() - Check if deque has no elementsis_full() - Check if deque is at capacityclear() - Remove all elements[index] - Direct element access and mutationiter() - Iterator over element referencesinto_iter() - Consuming iteratorextend() - Extend from iteratorFrom implementationsAll core operations are O(1) for both implementations:
push_back / push_front: O(1)pop_back / pop_front: O(1)len / is_empty / is_full: O(1)| Feature | ArrayDeque |
StackArrayDeque |
VecDeque |
|---|---|---|---|
| Allocation | Heap | Stack | Heap |
| Capacity | Runtime-fixed | Compile-time fixed | Dynamic, grows |
| Memory | Predictable after init | Completely predictable | May reallocate |
| Overflow | Overwrites oldest | Overwrites oldest | Grows capacity |
| Performance | Consistent O(1) | Consistent O(1) | Amortized O(1) |
| No-std | Supported (with alloc) |
Fully supported | Requires std |
| ISR-safe | No (heap allocation) | Yes | No |
This project is licensed under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.