From 5204b59b4e08ec1c5ce857819b37f6905cf2143b Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:06:30 -0700 Subject: [PATCH 01/47] Test workflow --- .circleci/config.yml | 18 ---------------- .github/dependabot.yaml | 10 +++++++++ .github/workflows/bench.yaml | 35 +++++++++++++++++++++++++++++++ .github/workflows/dependabot.yaml | 13 ++++++++++++ .github/workflows/lint.yaml | 30 ++++++++++++++++++++++++++ .github/workflows/release.yaml | 23 ++++++++++++++++++++ .github/workflows/test.yaml | 19 +++++++++++++++++ 7 files changed, 130 insertions(+), 18 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/dependabot.yaml create mode 100644 .github/workflows/bench.yaml create mode 100644 .github/workflows/dependabot.yaml create mode 100644 .github/workflows/lint.yaml create mode 100644 .github/workflows/release.yaml create mode 100644 .github/workflows/test.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 783bbc3..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: rustlang/rust:nightly - steps: - - checkout - - run: - name: Build - command: | - cargo build - cargo build --release - - run: - name: Test - command: cargo test - - run: - name: Benchmark - command: cargo bench diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..1557067 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily + - package-ecosystem: cargo + directory: / + schedule: + interval: daily diff --git a/.github/workflows/bench.yaml b/.github/workflows/bench.yaml new file mode 100644 index 0000000..bb911fc --- /dev/null +++ b/.github/workflows/bench.yaml @@ -0,0 +1,35 @@ +name: bench +on: + push: + branches: + - main + pull_request: +concurrency: + group: bench-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} +jobs: + cargo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: swatinem/rust-cache@v2 + - run: cargo bench + codspeed: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: swatinem/rust-cache@v2 + - run: cargo install --features vendored-openssl cargo-codspeed + - run: cargo codspeed build + - uses: codspeedhq/action@v3 + with: + run: cargo codspeed run + token: ${{ secrets.CODSPEED_TOKEN }} + bench: + needs: + - cargo + - codspeed + if: always() + runs-on: ubuntu-latest + steps: + - run: for result in ${{ join(needs.*.result, ' ') }}; do [ $result = success ]; done diff --git a/.github/workflows/dependabot.yaml b/.github/workflows/dependabot.yaml new file mode 100644 index 0000000..b4e087b --- /dev/null +++ b/.github/workflows/dependabot.yaml @@ -0,0 +1,13 @@ +name: dependabot +on: pull_request +permissions: + contents: write + pull-requests: write +jobs: + merge: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - run: gh pr merge --auto --squash ${{ github.event.pull_request.html_url }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..82ae86e --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,30 @@ +name: lint +on: + push: + branches: + - main + pull_request: +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: swatinem/rust-cache@v2 + - run: cargo clippy -- -D warnings + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - run: cargo fmt -- --check + spell_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: streetsidesoftware/cspell-action@v7 + with: + files: "**/*.{md,rs}" + readme: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: raviqqe/markdown-link-check@v1 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..30c1485 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +name: release +on: + push: + branches: + - main + pull_request: +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} +jobs: + release: + runs-on: ubuntu-latest + environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }} + steps: + - uses: actions/checkout@v5 + with: + submodules: true + - uses: raviqqe/cargo-cache@v1 + - run: cargo install cargo-workspaces + - run: cargo workspaces publish -y --from-git + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + if: github.ref == 'refs/heads/main' diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..01fec1b --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,19 @@ +name: test +on: + push: + branches: + - main + pull_request: +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: swatinem/rust-cache@v2 + - run: cargo build + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: swatinem/rust-cache@v2 + - run: cargo test From 79b3b6bdf1dc11d0d0511c005d1d6f5ac3fbb4f4 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:14:56 -0700 Subject: [PATCH 02/47] Fix --- Cargo.toml | 34 +++++++++++++++++++++++++++++++++- cspell.json | 3 +++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 cspell.json diff --git a/Cargo.toml b/Cargo.toml index 373573e..0279312 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,41 @@ [package] name = "array-queue" -description = "Fixed size bidirectional queues based on arrays" version = "0.3.3" authors = ["Yota Toyama "] +description = "Fixed size bidirectional queues based on arrays" license = "MIT" [dependencies] arrayvec = "0.4" + +[lints.clippy] +alloc_instead_of_core = "deny" +cargo = "deny" +complexity = "deny" +correctness = "deny" +dbg_macro = "deny" +derive_partial_eq_without_eq = "deny" +equatable_if_let = "deny" +explicit_deref_methods = "deny" +if_not_else = "deny" +manual_let_else = "deny" +missing_const_for_fn = "deny" +missing_panics_doc = "deny" +multiple_crate_versions = { level = "allow", priority = 1 } +option_if_let_else = "deny" +perf = "deny" +std_instead_of_alloc = "deny" +std_instead_of_core = "deny" +style = "deny" +suspicious = "deny" +todo = "deny" +undocumented_unsafe_blocks = "deny" +unimplemented = "deny" +uninlined_format_args = "deny" +unnecessary_safety_comment = "deny" +unused_self = "deny" +use_self = "deny" + +[lints.rust] +missing_docs = "deny" +warnings = "deny" diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..e972dce --- /dev/null +++ b/cspell.json @@ -0,0 +1,3 @@ +{ + "words": ["arrayvec", "clippy", "uninlined", "yota"] +} From 8e0d194e9c6416d49f90b794ad7ed1ba307fc654 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:15:24 -0700 Subject: [PATCH 03/47] Fix --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 0279312..460bb56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "array-queue" version = "0.3.3" authors = ["Yota Toyama "] +edition = "2024" description = "Fixed size bidirectional queues based on arrays" license = "MIT" From 1db38ce93ef05f691a8b81c58e7373aed358d761 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:17:48 -0700 Subject: [PATCH 04/47] Fix --- src/array_queue.rs | 12 ++++++------ src/error.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 35c16ac..0a24292 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,4 +1,4 @@ -use std::mem::{drop, forget, replace, uninitialized, ManuallyDrop}; +use core::mem::{drop, forget, replace, uninitialized, ManuallyDrop}; use arrayvec::Array; @@ -13,7 +13,7 @@ pub struct ArrayQueue::Item]> + AsMut<[::Item]> + AsMut<[::Item]>> ArrayQueue { pub fn new() -> Self { - ArrayQueue { + Self { array: unsafe { uninitialized() }, start: 0, length: 0, @@ -115,7 +115,7 @@ impl::Item]> + AsMut<[::Item]>> Array Some(x) } - pub fn len(&self) -> usize { + pub const fn len(&self) -> usize { self.length } @@ -155,7 +155,7 @@ impl::Item]> + AsMut<[::Item]>> Defau for ArrayQueue { fn default() -> Self { - ArrayQueue::new() + Self::new() } } @@ -214,7 +214,7 @@ pub struct ArrayQueueIterator< impl<'a, A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>> ArrayQueueIterator<'a, A> { - fn exhausted(&self) -> bool { + const fn exhausted(&self) -> bool { self.first >= self.last } } @@ -262,7 +262,7 @@ pub struct ArrayQueueMutIterator< impl<'a, A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>> ArrayQueueMutIterator<'a, A> { - fn exhausted(&self) -> bool { + const fn exhausted(&self) -> bool { self.first >= self.last } } diff --git a/src/error.rs b/src/error.rs index a4a97d6..2ddd601 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,14 +1,14 @@ -use std::error::Error; -use std::fmt::{Display, Formatter, Result}; +use core::error::Error; +use core::fmt::{Display, Formatter, Result}; -const MESSAGE: &'static str = "queue is full"; +const MESSAGE: &str = "queue is full"; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct CapacityError; impl Display for CapacityError { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "{}", MESSAGE) + write!(f, "{MESSAGE}") } } From 41bb2a1e427c6ed335cf6d367a18e0e114099e4d Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:18:25 -0700 Subject: [PATCH 05/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 0a24292..58d2948 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,4 +1,4 @@ -use core::mem::{drop, forget, replace, uninitialized, ManuallyDrop}; +use core::mem::{ManuallyDrop, drop, forget, replace, uninitialized}; use arrayvec::Array; @@ -119,7 +119,7 @@ impl::Item]> + AsMut<[::Item]>> Array self.length } - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.len() == 0 } @@ -550,7 +550,7 @@ mod test { assert!(a.push_back(&Box::new(42)).is_ok()); } - a.clone(); + let _ = a.clone(); } static mut FOO_SUM: usize = 0; From a8c421fc15aea7b1735ae414abdc742a3547e994 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:37:21 -0700 Subject: [PATCH 06/47] Fix --- src/array_queue.rs | 19 +++++++++++++++---- src/lib.rs | 4 +++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 58d2948..57fe200 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,9 +1,8 @@ -use core::mem::{ManuallyDrop, drop, forget, replace, uninitialized}; - +use crate::error::CapacityError; use arrayvec::Array; +use core::mem::{ManuallyDrop, drop, forget, replace, uninitialized}; -use super::error::CapacityError; - +/// A queue backed by a fixed-size array. #[derive(Debug)] pub struct ArrayQueue::Item]> + AsMut<[::Item]>> { array: ManuallyDrop, @@ -12,6 +11,7 @@ pub struct ArrayQueue::Item]> + AsMut<[::Item]> + AsMut<[::Item]>> ArrayQueue { + /// Creates an empty queue. pub fn new() -> Self { Self { array: unsafe { uninitialized() }, @@ -20,14 +20,17 @@ impl::Item]> + AsMut<[::Item]>> Array } } + /// Returns a reference to the first element of the queue, or `None` if it is empty. pub fn first(&self) -> Option<&::Item> { self.element(0) } + /// Returns a mutable reference to the first element of the queue, or `None` if it is empty. pub fn first_mut(&mut self) -> Option<&mut ::Item> { self.element_mut(0) } + /// Returns a reference to the last element of the queue, or `None` if it is empty. pub fn last(&self) -> Option<&::Item> { if self.is_empty() { return None; @@ -36,6 +39,7 @@ impl::Item]> + AsMut<[::Item]>> Array self.element(self.length - 1) } + /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. pub fn last_mut(&mut self) -> Option<&mut ::Item> { if self.is_empty() { return None; @@ -62,6 +66,7 @@ impl::Item]> + AsMut<[::Item]>> Array } } + /// Pushes an element to the back of the queue. pub fn push_back(&mut self, x: &::Item) -> Result<(), CapacityError> where ::Item: Clone, @@ -76,6 +81,7 @@ impl::Item]> + AsMut<[::Item]>> Array Ok(()) } + /// Pushes an element to the front of the queue. pub fn push_front(&mut self, x: &::Item) -> Result<(), CapacityError> where ::Item: Clone, @@ -90,6 +96,7 @@ impl::Item]> + AsMut<[::Item]>> Array Ok(()) } + /// Pops an element from the back of the queue. pub fn pop_back(&mut self) -> Option<::Item> { if self.is_empty() { return None; @@ -102,6 +109,7 @@ impl::Item]> + AsMut<[::Item]>> Array Some(x) } + /// Pops an element from the fonrt of the queue. pub fn pop_front(&mut self) -> Option<::Item> { if self.is_empty() { return None; @@ -115,14 +123,17 @@ impl::Item]> + AsMut<[::Item]>> Array Some(x) } + /// Returns the number of elements in the queue. pub const fn len(&self) -> usize { self.length } + /// Returns `true` if the queue is empty. pub const fn is_empty(&self) -> bool { self.len() == 0 } + /// Returns `true` if the queue is full. pub fn is_full(&self) -> bool { self.len() == Self::capacity() } diff --git a/src/lib.rs b/src/lib.rs index 898f7fb..7a9d8c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ -extern crate arrayvec; +//! An arra queue. + +#![no_std] mod array_queue; mod error; From 54f34f4bf902396ff13b078674337869c112cb4b Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:37:38 -0700 Subject: [PATCH 07/47] Fix --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 7a9d8c1..5b31ac0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! An arra queue. +//! A queue backed by a fixed-size array. #![no_std] From 3ffe819d9d08686335b20ab2db053b6258283447 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:38:01 -0700 Subject: [PATCH 08/47] Fix --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5b31ac0..7997c9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,8 @@ #![no_std] +extern crate alloc; + mod array_queue; mod error; From 5f72fb4fac2c3044c834d8cad45b767e7d9d0676 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:38:37 -0700 Subject: [PATCH 09/47] Fix --- src/array_queue.rs | 1 + src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/array_queue.rs b/src/array_queue.rs index 57fe200..f2d5f51 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -313,6 +313,7 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> D #[cfg(test)] mod test { use super::*; + use alloc::boxed::Box; #[test] fn new() { diff --git a/src/lib.rs b/src/lib.rs index 7997c9d..729e819 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ #![no_std] +#[cfg(test)] extern crate alloc; mod array_queue; From 62ee496c082d3472656bb98d99df06c66b5bb00d Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:39:39 -0700 Subject: [PATCH 10/47] Fix --- cspell.json | 2 +- src/array_queue.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cspell.json b/cspell.json index e972dce..1882f4f 100644 --- a/cspell.json +++ b/cspell.json @@ -1,3 +1,3 @@ { - "words": ["arrayvec", "clippy", "uninlined", "yota"] + "words": ["arrayvec", "clippy", "uninit", "uninlined", "yota"] } diff --git a/src/array_queue.rs b/src/array_queue.rs index f2d5f51..cda32de 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,6 +1,6 @@ use crate::error::CapacityError; use arrayvec::Array; -use core::mem::{ManuallyDrop, drop, forget, replace, uninitialized}; +use core::mem::{ManuallyDrop, MaybeUninit, drop, forget, replace}; /// A queue backed by a fixed-size array. #[derive(Debug)] @@ -14,7 +14,7 @@ impl::Item]> + AsMut<[::Item]>> Array /// Creates an empty queue. pub fn new() -> Self { Self { - array: unsafe { uninitialized() }, + array: MaybeUninit::new(), start: 0, length: 0, } From e9a8991f1ec37dfee94b9c23755a8687a2bf27a2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:41:14 -0700 Subject: [PATCH 11/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index cda32de..4042bc9 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -109,7 +109,7 @@ impl::Item]> + AsMut<[::Item]>> Array Some(x) } - /// Pops an element from the fonrt of the queue. + /// Pops an element from the front of the queue. pub fn pop_front(&mut self) -> Option<::Item> { if self.is_empty() { return None; From 5f5ac7bd38bdc1f5b90a16b0bc74d78f56050c62 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:56:52 -0700 Subject: [PATCH 12/47] fix --- src/array_queue.rs | 77 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 4042bc9..d9624a1 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,20 +1,19 @@ use crate::error::CapacityError; -use arrayvec::Array; -use core::mem::{ManuallyDrop, MaybeUninit, drop, forget, replace}; +use core::mem::{MaybeUninit, drop, forget, replace}; /// A queue backed by a fixed-size array. #[derive(Debug)] -pub struct ArrayQueue::Item]> + AsMut<[::Item]>> { - array: ManuallyDrop, +pub struct ArrayQueue { + array: [MaybeUninit; N], start: usize, length: usize, } -impl::Item]> + AsMut<[::Item]>> ArrayQueue { +impl ArrayQueue { /// Creates an empty queue. pub fn new() -> Self { Self { - array: MaybeUninit::new(), + array: Default::default(), start: 0, length: 0, } @@ -99,14 +98,14 @@ impl::Item]> + AsMut<[::Item]>> Array /// Pops an element from the back of the queue. pub fn pop_back(&mut self) -> Option<::Item> { if self.is_empty() { - return None; + None + } else { + let x = replace(&mut self.array.as_mut()[self.length - 1], unsafe { + uninitialized() + }); + self.length -= 1; + Some(x) } - - let x = replace(&mut self.array.as_mut()[self.length - 1], unsafe { - uninitialized() - }); - self.length -= 1; - Some(x) } /// Pops an element from the front of the queue. @@ -317,13 +316,13 @@ mod test { #[test] fn new() { - ArrayQueue::<[usize; 1]>::new(); - ArrayQueue::<[usize; 2]>::new(); + ArrayQueue::::new(); + ArrayQueue::::new(); } #[test] fn first_and_last() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.first(), None); assert_eq!(a.first_mut(), None); @@ -347,7 +346,7 @@ mod test { #[test] fn push_back() { - let mut a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); assert!(a.push_back(&42).is_ok()); @@ -355,7 +354,7 @@ mod test { assert_eq!(a.push_back(&42), Err(CapacityError)); assert_eq!(a.len(), 1); - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); assert!(a.push_back(&42).is_ok()); @@ -368,7 +367,7 @@ mod test { #[test] fn push_front() { - let mut a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); assert!(a.push_front(&42).is_ok()); @@ -376,7 +375,7 @@ mod test { assert_eq!(a.push_front(&42), Err(CapacityError)); assert_eq!(a.len(), 1); - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); assert!(a.push_front(&1).is_ok()); @@ -393,14 +392,14 @@ mod test { #[test] fn pop_back() { - let mut a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&42).is_ok()); assert_eq!(a.pop_back(), Some(42)); assert_eq!(a.len(), 0); - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&123).is_ok()); assert!(a.push_back(&42).is_ok()); @@ -415,14 +414,14 @@ mod test { #[test] fn pop_front() { - let mut a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&42).is_ok()); assert_eq!(a.pop_front(), Some(42)); assert_eq!(a.len(), 0); - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&123).is_ok()); assert!(a.push_back(&42).is_ok()); @@ -437,7 +436,7 @@ mod test { #[test] fn push_and_pop_across_edges() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&1).is_ok()); assert!(a.push_back(&2).is_ok()); @@ -452,20 +451,20 @@ mod test { #[test] fn is_empty() { - let a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let a: ArrayQueue = ArrayQueue::new(); assert!(a.is_empty()); - let a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let a: ArrayQueue = ArrayQueue::new(); assert!(a.is_empty()); } #[test] fn is_full() { - let mut a: ArrayQueue<[usize; 1]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.is_full()); - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.push_back(&0).is_ok()); assert!(a.is_full()); @@ -473,7 +472,7 @@ mod test { #[test] fn iterator() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.push_back(&1).is_ok()); @@ -485,7 +484,7 @@ mod test { #[test] fn iterator_across_edges() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&42).is_ok()); a.pop_front(); @@ -499,7 +498,7 @@ mod test { #[test] fn iterate_forward_and_backward() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.push_back(&1).is_ok()); @@ -514,7 +513,7 @@ mod test { #[test] fn iterate_forward_and_backward_mutablly() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.push_back(&1).is_ok()); @@ -529,14 +528,14 @@ mod test { #[test] fn iterate_empty_queue() { - let a = ArrayQueue::<[usize; 0]>::new(); + let a = ArrayQueue::::new(); for _ in a.into_iter() {} } #[test] fn iterator_mut() { - let mut a: ArrayQueue<[usize; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); assert!(a.push_back(&1).is_ok()); @@ -549,14 +548,14 @@ mod test { #[test] fn reference_elements() { - let mut a: ArrayQueue<[Box; 2]> = ArrayQueue::new(); + let mut a: ArrayQueue, 2> = ArrayQueue::new(); assert!(a.push_back(&Box::new(42)).is_ok()); assert!(a.push_front(&Box::new(42)).is_ok()); } #[test] fn clone() { - let mut a: ArrayQueue<[Box; 32]> = ArrayQueue::new(); + let mut a: ArrayQueue, 32> = ArrayQueue::new(); for _ in 0..32 { assert!(a.push_back(&Box::new(42)).is_ok()); @@ -582,7 +581,7 @@ mod test { fn no_drops_of_elements_on_push_back() { assert_eq!(unsafe { FOO_SUM }, 0); - let mut a: ArrayQueue<[Foo; 32]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); for _ in 0..32 { assert!(a.push_back(&Foo).is_ok()); @@ -612,7 +611,7 @@ mod test { fn drops_of_elements_on_pop_back() { assert_eq!(unsafe { BAR_SUM }, 0); - let mut a: ArrayQueue<[Bar; 32]> = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); for _ in 0..32 { assert!(a.push_back(&Bar).is_ok()); From fd627e482b1ffdabc6e5177a6bb7ed60f7553237 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 19:58:54 -0700 Subject: [PATCH 13/47] Fix --- src/array_queue.rs | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index d9624a1..2a949d5 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -20,17 +20,17 @@ impl ArrayQueue { } /// Returns a reference to the first element of the queue, or `None` if it is empty. - pub fn first(&self) -> Option<&::Item> { + pub fn first(&self) -> Option<&T> { self.element(0) } /// Returns a mutable reference to the first element of the queue, or `None` if it is empty. - pub fn first_mut(&mut self) -> Option<&mut ::Item> { + pub fn first_mut(&mut self) -> Option<&mut T> { self.element_mut(0) } /// Returns a reference to the last element of the queue, or `None` if it is empty. - pub fn last(&self) -> Option<&::Item> { + pub fn last(&self) -> Option<&T> { if self.is_empty() { return None; } @@ -39,7 +39,7 @@ impl ArrayQueue { } /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. - pub fn last_mut(&mut self) -> Option<&mut ::Item> { + pub fn last_mut(&mut self) -> Option<&mut T> { if self.is_empty() { return None; } @@ -48,7 +48,7 @@ impl ArrayQueue { self.element_mut(i) } - fn element(&self, i: usize) -> Option<&::Item> { + fn element(&self, i: usize) -> Option<&T> { if self.is_empty() { None } else { @@ -56,7 +56,7 @@ impl ArrayQueue { } } - fn element_mut(&mut self, i: usize) -> Option<&mut ::Item> { + fn element_mut(&mut self, i: usize) -> Option<&mut T> { if self.is_empty() { None } else { @@ -66,7 +66,7 @@ impl ArrayQueue { } /// Pushes an element to the back of the queue. - pub fn push_back(&mut self, x: &::Item) -> Result<(), CapacityError> + pub fn push_back(&mut self, x: &T) -> Result<(), CapacityError> where ::Item: Clone, { @@ -161,15 +161,13 @@ where } } -impl::Item]> + AsMut<[::Item]>> Default - for ArrayQueue -{ +impl Default for ArrayQueue { fn default() -> Self { Self::new() } } -impl::Item]> + AsMut<[::Item]>> Drop for ArrayQueue { +impl Drop for ArrayQueue { fn drop(&mut self) { for x in self { drop(replace(x, unsafe { uninitialized() })); @@ -177,10 +175,8 @@ impl::Item]> + AsMut<[::Item]>> Drop } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> IntoIterator - for &'a ArrayQueue -{ - type Item = &'a ::Item; +impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue { + type Item = &'a T; type IntoIter = ArrayQueueIterator<'a, A>; fn into_iter(self) -> Self::IntoIter { @@ -194,10 +190,8 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> I } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> IntoIterator - for &'a mut ArrayQueue -{ - type Item = &'a mut ::Item; +impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue { + type Item = &'a mut T; type IntoIter = ArrayQueueMutIterator<'a, A>; fn into_iter(self) -> Self::IntoIter { From d80ebbd3bb044bbee1494e124a4aeedcd5bdcb58 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:00:12 -0700 Subject: [PATCH 14/47] Fix --- src/array_queue.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 2a949d5..d31c889 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -68,7 +68,7 @@ impl ArrayQueue { /// Pushes an element to the back of the queue. pub fn push_back(&mut self, x: &T) -> Result<(), CapacityError> where - ::Item: Clone, + T: Clone, { if self.is_full() { return Err(CapacityError); @@ -83,7 +83,7 @@ impl ArrayQueue { /// Pushes an element to the front of the queue. pub fn push_front(&mut self, x: &::Item) -> Result<(), CapacityError> where - ::Item: Clone, + T: Clone, { if self.is_full() { return Err(CapacityError); @@ -96,7 +96,7 @@ impl ArrayQueue { } /// Pops an element from the back of the queue. - pub fn pop_back(&mut self) -> Option<::Item> { + pub fn pop_back(&mut self) -> Option { if self.is_empty() { None } else { @@ -109,7 +109,7 @@ impl ArrayQueue { } /// Pops an element from the front of the queue. - pub fn pop_front(&mut self) -> Option<::Item> { + pub fn pop_front(&mut self) -> Option { if self.is_empty() { return None; } @@ -146,10 +146,7 @@ impl ArrayQueue { } } -impl::Item]> + AsMut<[::Item]>> Clone for ArrayQueue -where - ::Item: Clone, -{ +impl Clone for ArrayQueue { fn clone(&self) -> Self { let mut a = Self::new(); From e55ef71ed27f1ef80405873722551a2c47632cf5 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:00:52 -0700 Subject: [PATCH 15/47] Fix --- src/array_queue.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index d31c889..b804834 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -134,15 +134,11 @@ impl ArrayQueue { /// Returns `true` if the queue is full. pub fn is_full(&self) -> bool { - self.len() == Self::capacity() + self.len() == N } fn index(&self, i: usize) -> usize { - (self.start + i) % Self::capacity() - } - - fn capacity() -> usize { - A::capacity() + (self.start + i) % N } } From f6ee3d4a54c07c811057dfaf9d0706936f3d502e Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:04:59 -0700 Subject: [PATCH 16/47] Fix --- src/array_queue.rs | 54 ++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index b804834..70496c8 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -89,7 +89,7 @@ impl ArrayQueue { return Err(CapacityError); } - self.start = self.index(Self::capacity() - 1); + self.start = self.index(N - 1); forget(replace(&mut self.array.as_mut()[self.start], x.clone())); self.length += 1; Ok(()) @@ -142,7 +142,7 @@ impl ArrayQueue { } } -impl Clone for ArrayQueue { +impl Clone for ArrayQueue { fn clone(&self) -> Self { let mut a = Self::new(); @@ -170,7 +170,7 @@ impl Drop for ArrayQueue { impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue { type Item = &'a T; - type IntoIter = ArrayQueueIterator<'a, A>; + type IntoIter = ArrayQueueIterator<'a, T, N>; fn into_iter(self) -> Self::IntoIter { let l = self.len(); @@ -185,7 +185,7 @@ impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue { impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue { type Item = &'a mut T; - type IntoIter = ArrayQueueMutIterator<'a, A>; + type IntoIter = ArrayQueueMutIterator<'a, T, N>; fn into_iter(self) -> Self::IntoIter { let l = self.len(); @@ -199,27 +199,20 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue { } #[derive(Debug)] -pub struct ArrayQueueIterator< - 'a, - A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>, -> { - queue: &'a ArrayQueue, +pub struct ArrayQueueIterator<'a, T, const N: usize> { + queue: &'a ArrayQueue, first: usize, last: usize, } -impl<'a, A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>> - ArrayQueueIterator<'a, A> -{ +impl<'a, T, const N: usize> ArrayQueueIterator<'a, T, N> { const fn exhausted(&self) -> bool { self.first >= self.last } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> Iterator - for ArrayQueueIterator<'a, A> -{ - type Item = &'a ::Item; +impl<'a, T, const N: usize> Iterator for ArrayQueueIterator<'a, T, N> { + type Item = &'a T; fn next(&mut self) -> Option { if self.exhausted() { @@ -232,9 +225,7 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> I } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> DoubleEndedIterator - for ArrayQueueIterator<'a, A> -{ +impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueIterator<'a, T, N> { fn next_back(&mut self) -> Option { if self.exhausted() { return None; @@ -247,27 +238,20 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> D } #[derive(Debug)] -pub struct ArrayQueueMutIterator< - 'a, - A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>, -> { - queue: &'a mut ArrayQueue, +pub struct ArrayQueueMutIterator<'a, T, const N: usize> { + queue: &'a mut ArrayQueue, first: usize, last: usize, } -impl<'a, A: 'a + Array + AsRef<[::Item]> + AsMut<[::Item]>> - ArrayQueueMutIterator<'a, A> -{ +impl<'a, T, const N: usize> ArrayQueueMutIterator<'a, T, N> { const fn exhausted(&self) -> bool { self.first >= self.last } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> Iterator - for ArrayQueueMutIterator<'a, A> -{ - type Item = &'a mut ::Item; +impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { + type Item = &'a mut T; fn next(&mut self) -> Option { if self.exhausted() { @@ -275,15 +259,13 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> I } let i = self.queue.index(self.first); - let x = &mut self.queue.array.as_mut()[i] as *mut ::Item; + let x = &mut self.queue.array.as_mut()[i] as *mut T; self.first += 1; Some(unsafe { &mut *x }) } } -impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> DoubleEndedIterator - for ArrayQueueMutIterator<'a, A> -{ +impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, N> { fn next_back(&mut self) -> Option { if self.exhausted() { return None; @@ -291,7 +273,7 @@ impl<'a, A: Array + AsRef<[::Item]> + AsMut<[::Item]>> D self.last -= 1; let i = self.queue.index(self.last); - let x = &mut self.queue.array.as_mut()[i] as *mut ::Item; + let x = &mut self.queue.array.as_mut()[i] as *mut T; Some(unsafe { &mut *x }) } } From a54a24fe19525d8fbe7e8166a81bde249bb04756 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:05:45 -0700 Subject: [PATCH 17/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 70496c8..de4f40a 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -13,7 +13,7 @@ impl ArrayQueue { /// Creates an empty queue. pub fn new() -> Self { Self { - array: Default::default(), + array: [const { MaybeUninit::uninit() }; N], start: 0, length: 0, } From e124e20d03a3c3360b38a5328a75440f9173ecd2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:07:32 -0700 Subject: [PATCH 18/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index de4f40a..63a2005 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -81,7 +81,7 @@ impl ArrayQueue { } /// Pushes an element to the front of the queue. - pub fn push_front(&mut self, x: &::Item) -> Result<(), CapacityError> + pub fn push_front(&mut self, x: &T) -> Result<(), CapacityError> where T: Clone, { From 5945c2037be799a20e27a989475800f22cf5c6e8 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:31:42 -0700 Subject: [PATCH 19/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 63a2005..323f126 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -481,7 +481,7 @@ mod test { } #[test] - fn iterate_forward_and_backward_mutablly() { + fn iterate_forward_and_backward_mutable() { let mut a: ArrayQueue = ArrayQueue::new(); assert!(a.push_back(&0).is_ok()); From 954e2da04fee5bf8db173d9ac25fec8253b634bb Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:32:41 -0700 Subject: [PATCH 20/47] fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 323f126..688eab6 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -101,7 +101,7 @@ impl ArrayQueue { None } else { let x = replace(&mut self.array.as_mut()[self.length - 1], unsafe { - uninitialized() + MaybeUninit::uninit() }); self.length -= 1; Some(x) @@ -115,7 +115,7 @@ impl ArrayQueue { } let x = replace(&mut self.array.as_mut()[self.start], unsafe { - uninitialized() + MaybeUninit::uninit() }); self.start = self.index(1); self.length -= 1; @@ -163,7 +163,7 @@ impl Default for ArrayQueue { impl Drop for ArrayQueue { fn drop(&mut self) { for x in self { - drop(replace(x, unsafe { uninitialized() })); + drop(replace(x, unsafe { MaybeUninit::uninit() })); } } } From 49e382e65e7fa6941836f72f4a76093b098da73c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:34:24 -0700 Subject: [PATCH 21/47] Fix --- src/array_queue.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 688eab6..85efb28 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -31,21 +31,12 @@ impl ArrayQueue { /// Returns a reference to the last element of the queue, or `None` if it is empty. pub fn last(&self) -> Option<&T> { - if self.is_empty() { - return None; - } - self.element(self.length - 1) } /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. pub fn last_mut(&mut self) -> Option<&mut T> { - if self.is_empty() { - return None; - } - - let i = self.length - 1; - self.element_mut(i) + self.element_mut(self.length - 1) } fn element(&self, i: usize) -> Option<&T> { From f2025b34e99c9208a90d8ec5c377cad1f5dde1f7 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:39:35 -0700 Subject: [PATCH 22/47] fix --- src/array_queue.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 85efb28..d126b89 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -40,19 +40,22 @@ impl ArrayQueue { } fn element(&self, i: usize) -> Option<&T> { - if self.is_empty() { - None + if i < self.length { + let x = &self.array[self.index(i)]; + + Some(unsafe { x.assume_init_ref() }) } else { - Some(&self.array.as_ref()[self.index(i)]) + None } } fn element_mut(&mut self, i: usize) -> Option<&mut T> { - if self.is_empty() { - None + if i < self.length { + let x = &mut self.array[self.index(i)]; + + Some(unsafe { x.assume_init_mut() }) } else { - let i = self.index(i); - Some(&mut self.array.as_mut()[i]) + None } } From e57b6cb50eb4d05bbfe4385d7a3431c5fe23e5ce Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:40:26 -0700 Subject: [PATCH 23/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index d126b89..9f9e964 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -69,7 +69,7 @@ impl ArrayQueue { } let i = self.index(self.length); - forget(replace(&mut self.array.as_mut()[i], x.clone())); + forget(replace(&mut self.array[i], x.clone())); self.length += 1; Ok(()) } From ee000f14c8ff15bca17b23b62f9cb272db607c8a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:41:22 -0700 Subject: [PATCH 24/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 9f9e964..ae0b288 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -39,9 +39,9 @@ impl ArrayQueue { self.element_mut(self.length - 1) } - fn element(&self, i: usize) -> Option<&T> { - if i < self.length { - let x = &self.array[self.index(i)]; + fn element(&self, index: usize) -> Option<&T> { + if index < self.length { + let x = &self.array[self.index(index)]; Some(unsafe { x.assume_init_ref() }) } else { From fb92b2d13abe69637317bafce36b31daad70e3e0 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:41:38 -0700 Subject: [PATCH 25/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index ae0b288..488e226 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -49,9 +49,9 @@ impl ArrayQueue { } } - fn element_mut(&mut self, i: usize) -> Option<&mut T> { - if i < self.length { - let x = &mut self.array[self.index(i)]; + fn element_mut(&mut self, index: usize) -> Option<&mut T> { + if index < self.length { + let x = &mut self.array[self.index(index)]; Some(unsafe { x.assume_init_mut() }) } else { From a0c2b8bf5d32ffa343378df9e335cec49898bc05 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:44:10 -0700 Subject: [PATCH 26/47] fix --- src/array_queue.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 488e226..9c2c3c5 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -60,17 +60,17 @@ impl ArrayQueue { } /// Pushes an element to the back of the queue. - pub fn push_back(&mut self, x: &T) -> Result<(), CapacityError> - where - T: Clone, - { + pub fn push_back(&mut self, x: T) -> Result<(), CapacityError> { if self.is_full() { return Err(CapacityError); } - let i = self.index(self.length); - forget(replace(&mut self.array[i], x.clone())); + replace( + &mut self.array[self.index(self.length)], + MaybeUninit::new(x), + ); self.length += 1; + Ok(()) } From 642ddc7cf8756c58a535599a8ee796f2312816bc Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:45:11 -0700 Subject: [PATCH 27/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 9c2c3c5..1cf04ed 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -138,13 +138,13 @@ impl ArrayQueue { impl Clone for ArrayQueue { fn clone(&self) -> Self { - let mut a = Self::new(); + let mut queue = Self::new(); for x in self { - a.push_back(x).unwrap(); + queue.push_back(x.clone()).unwrap(); } - a + queue } } From ae5383b6e94f0f9e9d85d3e732046fe76959c409 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:51:57 -0700 Subject: [PATCH 28/47] Fix --- src/array_queue.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 1cf04ed..1bbf37f 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,5 +1,5 @@ use crate::error::CapacityError; -use core::mem::{MaybeUninit, drop, forget, replace}; +use core::mem::{MaybeUninit, replace}; /// A queue backed by a fixed-size array. #[derive(Debug)] @@ -65,27 +65,22 @@ impl ArrayQueue { return Err(CapacityError); } - replace( - &mut self.array[self.index(self.length)], - MaybeUninit::new(x), - ); + self.array[self.index(self.length)] = MaybeUninit::new(x); self.length += 1; Ok(()) } /// Pushes an element to the front of the queue. - pub fn push_front(&mut self, x: &T) -> Result<(), CapacityError> - where - T: Clone, - { + pub fn push_front(&mut self, x: T) -> Result<(), CapacityError> { if self.is_full() { return Err(CapacityError); } self.start = self.index(N - 1); - forget(replace(&mut self.array.as_mut()[self.start], x.clone())); + self.array[self.start] = MaybeUninit::new(x); self.length += 1; + Ok(()) } @@ -94,11 +89,10 @@ impl ArrayQueue { if self.is_empty() { None } else { - let x = replace(&mut self.array.as_mut()[self.length - 1], unsafe { - MaybeUninit::uninit() - }); + let x = replace(&mut self.array[self.length - 1], MaybeUninit::uninit()); self.length -= 1; - Some(x) + + Some(unsafe { x.assume_init() }) } } @@ -156,9 +150,7 @@ impl Default for ArrayQueue { impl Drop for ArrayQueue { fn drop(&mut self) { - for x in self { - drop(replace(x, unsafe { MaybeUninit::uninit() })); - } + for _ in self {} } } From 974b525fc46df99ee05dde3b43021bb0275ed49d Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:53:21 -0700 Subject: [PATCH 29/47] Fix --- src/array_queue.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 1bbf37f..1303ea8 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -99,15 +99,14 @@ impl ArrayQueue { /// Pops an element from the front of the queue. pub fn pop_front(&mut self) -> Option { if self.is_empty() { - return None; - } + None + } else { + let x = replace(&mut self.array[self.start], MaybeUninit::uninit()); + self.start = self.index(1); + self.length -= 1; - let x = replace(&mut self.array.as_mut()[self.start], unsafe { - MaybeUninit::uninit() - }); - self.start = self.index(1); - self.length -= 1; - Some(x) + Some(x) + } } /// Returns the number of elements in the queue. From 01581415eca095ecbfd0bbb77bbbd944376f1271 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:53:56 -0700 Subject: [PATCH 30/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 1303ea8..34f1ee4 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -105,7 +105,7 @@ impl ArrayQueue { self.start = self.index(1); self.length -= 1; - Some(x) + Some(unsafe { x.assume_init() }) } } From 03646732918f8acd3145b0913f60b98aa0380d09 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:55:48 -0700 Subject: [PATCH 31/47] Fix --- src/array_queue.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 34f1ee4..2350387 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -124,8 +124,8 @@ impl ArrayQueue { self.len() == N } - fn index(&self, i: usize) -> usize { - (self.start + i) % N + fn index(&self, index: usize) -> usize { + (self.start + index) % N } } From aa8aac6f6edeb17bf5094f577241b98770772d68 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 20:58:24 -0700 Subject: [PATCH 32/47] Fix --- src/array_queue.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 2350387..8b216e6 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -149,7 +149,9 @@ impl Default for ArrayQueue { impl Drop for ArrayQueue { fn drop(&mut self) { - for _ in self {} + for _ in self { + // TODO + } } } From af911c21ac7189e54ca5c5a01f5abb956a1ecaf0 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:09:02 -0700 Subject: [PATCH 33/47] Fix --- src/array_queue.rs | 82 ++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 8b216e6..9eaca79 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -155,36 +155,6 @@ impl Drop for ArrayQueue { } } -impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue { - type Item = &'a T; - type IntoIter = ArrayQueueIterator<'a, T, N>; - - fn into_iter(self) -> Self::IntoIter { - let l = self.len(); - - ArrayQueueIterator { - queue: self, - first: 0, - last: l, - } - } -} - -impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue { - type Item = &'a mut T; - type IntoIter = ArrayQueueMutIterator<'a, T, N>; - - fn into_iter(self) -> Self::IntoIter { - let l = self.len(); - - ArrayQueueMutIterator { - queue: self, - first: 0, - last: l, - } - } -} - #[derive(Debug)] pub struct ArrayQueueIterator<'a, T, const N: usize> { queue: &'a ArrayQueue, @@ -193,34 +163,47 @@ pub struct ArrayQueueIterator<'a, T, const N: usize> { } impl<'a, T, const N: usize> ArrayQueueIterator<'a, T, N> { - const fn exhausted(&self) -> bool { + const fn is_exhausted(&self) -> bool { self.first >= self.last } } +impl<'a, T, const N: usize> IntoIterator for &'a ArrayQueue { + type Item = &'a T; + type IntoIter = ArrayQueueIterator<'a, T, N>; + + fn into_iter(self) -> Self::IntoIter { + ArrayQueueIterator { + queue: self, + first: 0, + last: self.len(), + } + } +} + impl<'a, T, const N: usize> Iterator for ArrayQueueIterator<'a, T, N> { type Item = &'a T; fn next(&mut self) -> Option { - if self.exhausted() { + if self.is_exhausted() { return None; } - let x = &self.queue.array.as_ref()[self.queue.index(self.first)]; - self.first += 1; - Some(x) + let x = self.queue.element(self.first); + self.first += x.is_some() as usize; + x } } impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueIterator<'a, T, N> { fn next_back(&mut self) -> Option { - if self.exhausted() { + if self.is_exhausted() { return None; } - self.last -= 1; - let x = &self.queue.array.as_ref()[self.queue.index(self.last)]; - Some(x) + let x = self.queue.element(self.last); + self.last -= x.is_some() as usize; + x } } @@ -232,16 +215,31 @@ pub struct ArrayQueueMutIterator<'a, T, const N: usize> { } impl<'a, T, const N: usize> ArrayQueueMutIterator<'a, T, N> { - const fn exhausted(&self) -> bool { + const fn is_exhausted(&self) -> bool { self.first >= self.last } } +impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayQueue { + type Item = &'a mut T; + type IntoIter = ArrayQueueMutIterator<'a, T, N>; + + fn into_iter(self) -> Self::IntoIter { + let last = self.len(); + + ArrayQueueMutIterator { + queue: self, + first: 0, + last, + } + } +} + impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { type Item = &'a mut T; fn next(&mut self) -> Option { - if self.exhausted() { + if self.is_exhausted() { return None; } @@ -254,7 +252,7 @@ impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, N> { fn next_back(&mut self) -> Option { - if self.exhausted() { + if self.is_exhausted() { return None; } From 945e87abe6ee08d43e82e074d2bad7b619a5367c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:12:27 -0700 Subject: [PATCH 34/47] Fix --- src/array_queue.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 9eaca79..791f7cc 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -243,10 +243,9 @@ impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { return None; } - let i = self.queue.index(self.first); - let x = &mut self.queue.array.as_mut()[i] as *mut T; - self.first += 1; - Some(unsafe { &mut *x }) + let x = self.queue.element_mut(self.first); + self.first += x.is_some() as usize; + x } } @@ -256,10 +255,9 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, return None; } - self.last -= 1; - let i = self.queue.index(self.last); - let x = &mut self.queue.array.as_mut()[i] as *mut T; - Some(unsafe { &mut *x }) + let x = self.queue.element_mut(self.last); + self.last -= x.is_some() as usize; + x } } From 2e4af00e384f6b43fba8419069c17b4f78e02b30 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:23:22 -0700 Subject: [PATCH 35/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 791f7cc..566a80a 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -1,5 +1,5 @@ use crate::error::CapacityError; -use core::mem::{MaybeUninit, replace}; +use core::mem::{MaybeUninit, replace, transmute}; /// A queue backed by a fixed-size array. #[derive(Debug)] @@ -245,7 +245,7 @@ impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { let x = self.queue.element_mut(self.first); self.first += x.is_some() as usize; - x + x.map(|x| unsafe { transmute(x) }) } } @@ -257,7 +257,7 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, let x = self.queue.element_mut(self.last); self.last -= x.is_some() as usize; - x + x.map(|x| unsafe { transmute(x) }) } } From fb92296d6a7d886af8004c4320c5cbe17c6e0666 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:24:51 -0700 Subject: [PATCH 36/47] Fix --- src/array_queue.rs | 80 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 566a80a..3081bf0 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -281,14 +281,14 @@ mod test { assert_eq!(a.last(), None); assert_eq!(a.last_mut(), None); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(1).is_ok()); assert_eq!(a.first(), Some(&1)); assert_eq!(a.first_mut(), Some(&mut 1)); assert_eq!(a.last(), Some(&1)); assert_eq!(a.last_mut(), Some(&mut 1)); - assert!(a.push_back(&2).is_ok()); + assert!(a.push_back(2).is_ok()); assert_eq!(a.first(), Some(&1)); assert_eq!(a.first_mut(), Some(&mut 1)); @@ -301,19 +301,19 @@ mod test { let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.len(), 1); - assert_eq!(a.push_back(&42), Err(CapacityError)); + assert_eq!(a.push_back(42), Err(CapacityError)); assert_eq!(a.len(), 1); let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.len(), 1); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.len(), 2); - assert_eq!(a.push_back(&42), Err(CapacityError)); + assert_eq!(a.push_back(42), Err(CapacityError)); assert_eq!(a.len(), 2); } @@ -322,23 +322,23 @@ mod test { let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); - assert!(a.push_front(&42).is_ok()); + assert!(a.push_front(42).is_ok()); assert_eq!(a.len(), 1); - assert_eq!(a.push_front(&42), Err(CapacityError)); + assert_eq!(a.push_front(42), Err(CapacityError)); assert_eq!(a.len(), 1); let mut a: ArrayQueue = ArrayQueue::new(); assert_eq!(a.len(), 0); - assert!(a.push_front(&1).is_ok()); + assert!(a.push_front(1).is_ok()); assert_eq!(a.first(), Some(&1)); assert_eq!(a.last(), Some(&1)); assert_eq!(a.len(), 1); - assert!(a.push_front(&2).is_ok()); + assert!(a.push_front(2).is_ok()); assert_eq!(a.first(), Some(&2)); assert_eq!(a.last(), Some(&1)); assert_eq!(a.len(), 2); - assert_eq!(a.push_front(&3), Err(CapacityError)); + assert_eq!(a.push_front(3), Err(CapacityError)); assert_eq!(a.len(), 2); } @@ -346,15 +346,15 @@ mod test { fn pop_back() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.pop_back(), Some(42)); assert_eq!(a.len(), 0); let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&123).is_ok()); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(123).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.pop_back(), Some(42)); assert_eq!(a.first(), Some(&123)); @@ -368,15 +368,15 @@ mod test { fn pop_front() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.pop_front(), Some(42)); assert_eq!(a.len(), 0); let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&123).is_ok()); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(123).is_ok()); + assert!(a.push_back(42).is_ok()); assert_eq!(a.pop_front(), Some(123)); assert_eq!(a.first(), Some(&42)); @@ -390,13 +390,13 @@ mod test { fn push_and_pop_across_edges() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&1).is_ok()); - assert!(a.push_back(&2).is_ok()); + assert!(a.push_back(1).is_ok()); + assert!(a.push_back(2).is_ok()); for i in 3..64 { assert_eq!(a.pop_front(), Some(i - 2)); assert_eq!(a.len(), 1); - assert!(a.push_back(&i).is_ok()); + assert!(a.push_back(i).is_ok()); assert_eq!(a.len(), 2); } } @@ -413,12 +413,12 @@ mod test { #[test] fn is_full() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); + assert!(a.push_back(0).is_ok()); assert!(a.is_full()); let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&0).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(0).is_ok()); assert!(a.is_full()); } @@ -426,8 +426,8 @@ mod test { fn iterator() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(1).is_ok()); for (i, e) in a.into_iter().enumerate() { assert_eq!(*e, i); @@ -438,10 +438,10 @@ mod test { fn iterator_across_edges() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&42).is_ok()); + assert!(a.push_back(42).is_ok()); a.pop_front(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(1).is_ok()); for (i, e) in a.into_iter().enumerate() { assert_eq!(*e, i); @@ -452,8 +452,8 @@ mod test { fn iterate_forward_and_backward() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(1).is_ok()); let mut i = a.into_iter(); @@ -467,8 +467,8 @@ mod test { fn iterate_forward_and_backward_mutable() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(1).is_ok()); let mut i = (&mut a).into_iter(); @@ -489,8 +489,8 @@ mod test { fn iterator_mut() { let mut a: ArrayQueue = ArrayQueue::new(); - assert!(a.push_back(&0).is_ok()); - assert!(a.push_back(&1).is_ok()); + assert!(a.push_back(0).is_ok()); + assert!(a.push_back(1).is_ok()); for (i, e) in (&mut a).into_iter().enumerate() { assert_eq!(*e, i); @@ -501,8 +501,8 @@ mod test { #[test] fn reference_elements() { let mut a: ArrayQueue, 2> = ArrayQueue::new(); - assert!(a.push_back(&Box::new(42)).is_ok()); - assert!(a.push_front(&Box::new(42)).is_ok()); + assert!(a.push_back(Box::new(42)).is_ok()); + assert!(a.push_front(Box::new(42)).is_ok()); } #[test] @@ -510,7 +510,7 @@ mod test { let mut a: ArrayQueue, 32> = ArrayQueue::new(); for _ in 0..32 { - assert!(a.push_back(&Box::new(42)).is_ok()); + assert!(a.push_back(Box::new(42)).is_ok()); } let _ = a.clone(); @@ -536,7 +536,7 @@ mod test { let mut a: ArrayQueue = ArrayQueue::new(); for _ in 0..32 { - assert!(a.push_back(&Foo).is_ok()); + assert!(a.push_back(Foo).is_ok()); } assert_eq!(unsafe { FOO_SUM }, 32); // drops of arguments `&Foo` @@ -566,7 +566,7 @@ mod test { let mut a: ArrayQueue = ArrayQueue::new(); for _ in 0..32 { - assert!(a.push_back(&Bar).is_ok()); + assert!(a.push_back(Bar).is_ok()); } assert_eq!(unsafe { BAR_SUM }, 32); // drops of arguments `&Bar` From 119b9dc9e0025c222b8813ea29a92c8c1940dd27 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:26:27 -0700 Subject: [PATCH 37/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 3081bf0..8f78c49 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -569,16 +569,16 @@ mod test { assert!(a.push_back(Bar).is_ok()); } - assert_eq!(unsafe { BAR_SUM }, 32); // drops of arguments `&Bar` + assert_eq!(unsafe { BAR_SUM }, 0); for _ in 0..32 { assert!(a.pop_back().is_some()); } - assert_eq!(unsafe { BAR_SUM }, 64); // drops of elements + assert_eq!(unsafe { BAR_SUM }, 32); drop(a); - assert_eq!(unsafe { BAR_SUM }, 64); + assert_eq!(unsafe { BAR_SUM }, 32); } } From c9d75b41814a3048fc758e85c81da55fcf27b66c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:27:36 -0700 Subject: [PATCH 38/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 8f78c49..faf4442 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -31,7 +31,7 @@ impl ArrayQueue { /// Returns a reference to the last element of the queue, or `None` if it is empty. pub fn last(&self) -> Option<&T> { - self.element(self.length - 1) + self.element(N + self.length - 1) } /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. From c7749327c96a9e1a6ed09e710df5cf5f113b4985 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:29:21 -0700 Subject: [PATCH 39/47] Fix --- src/array_queue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index faf4442..c4cae79 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -201,7 +201,7 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueIterator<'a, T, N> return None; } - let x = self.queue.element(self.last); + let x = self.queue.element(self.last - 1); self.last -= x.is_some() as usize; x } @@ -255,7 +255,7 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, return None; } - let x = self.queue.element_mut(self.last); + let x = self.queue.element_mut(self.last - 1); self.last -= x.is_some() as usize; x.map(|x| unsafe { transmute(x) }) } @@ -450,7 +450,7 @@ mod test { #[test] fn iterate_forward_and_backward() { - let mut a: ArrayQueue = ArrayQueue::new(); + let mut a = ArrayQueue::::new(); assert!(a.push_back(0).is_ok()); assert!(a.push_back(1).is_ok()); From 068b26b8d9eea973bdf9089ba2f40edd476c0b39 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:30:05 -0700 Subject: [PATCH 40/47] Fix --- src/array_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index c4cae79..6359b50 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -36,7 +36,7 @@ impl ArrayQueue { /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. pub fn last_mut(&mut self) -> Option<&mut T> { - self.element_mut(self.length - 1) + self.element_mut(N + self.length - 1) } fn element(&self, index: usize) -> Option<&T> { From 22967f20ffded7e1e5788af6498873cc3d7ad36a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:31:13 -0700 Subject: [PATCH 41/47] Fix --- src/array_queue.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 6359b50..71347fd 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -31,12 +31,20 @@ impl ArrayQueue { /// Returns a reference to the last element of the queue, or `None` if it is empty. pub fn last(&self) -> Option<&T> { - self.element(N + self.length - 1) + if self.is_empty() { + None + } else { + self.element(self.length - 1) + } } /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. pub fn last_mut(&mut self) -> Option<&mut T> { - self.element_mut(N + self.length - 1) + if self.is_empty() { + None + } else { + self.element_mut(self.length - 1) + } } fn element(&self, index: usize) -> Option<&T> { From d3a1a6d9afd604f440e93d82534df9a99f469a28 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:32:03 -0700 Subject: [PATCH 42/47] Fix --- src/array_queue.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 71347fd..c086555 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -547,11 +547,11 @@ mod test { assert!(a.push_back(Foo).is_ok()); } - assert_eq!(unsafe { FOO_SUM }, 32); // drops of arguments `&Foo` + assert_eq!(unsafe { FOO_SUM }, 0); drop(a); - assert_eq!(unsafe { FOO_SUM }, 64); // drops of elements + assert_eq!(unsafe { FOO_SUM }, 32); } static mut BAR_SUM: usize = 0; From 787afda1c0ec5061f37fc9566320ffd3d1c543ff Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:33:40 -0700 Subject: [PATCH 43/47] fix --- src/array_queue.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index c086555..cc7a977 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -157,9 +157,7 @@ impl Default for ArrayQueue { impl Drop for ArrayQueue { fn drop(&mut self) { - for _ in self { - // TODO - } + while let Some(_) = self.pop_back() {} } } @@ -541,9 +539,9 @@ mod test { fn no_drops_of_elements_on_push_back() { assert_eq!(unsafe { FOO_SUM }, 0); - let mut a: ArrayQueue = ArrayQueue::new(); + let mut a: ArrayQueue = ArrayQueue::new(); - for _ in 0..32 { + for _ in 0..17 { assert!(a.push_back(Foo).is_ok()); } @@ -551,7 +549,7 @@ mod test { drop(a); - assert_eq!(unsafe { FOO_SUM }, 32); + assert_eq!(unsafe { FOO_SUM }, 17); } static mut BAR_SUM: usize = 0; From 651e20e7195ee4c2ee0c028b43d3a076e3aabc77 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:33:53 -0700 Subject: [PATCH 44/47] Fix --- src/array_queue.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index cc7a977..3eb580f 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -11,7 +11,7 @@ pub struct ArrayQueue { impl ArrayQueue { /// Creates an empty queue. - pub fn new() -> Self { + pub const fn new() -> Self { Self { array: [const { MaybeUninit::uninit() }; N], start: 0, @@ -93,7 +93,7 @@ impl ArrayQueue { } /// Pops an element from the back of the queue. - pub fn pop_back(&mut self) -> Option { + pub const fn pop_back(&mut self) -> Option { if self.is_empty() { None } else { @@ -128,11 +128,11 @@ impl ArrayQueue { } /// Returns `true` if the queue is full. - pub fn is_full(&self) -> bool { + pub const fn is_full(&self) -> bool { self.len() == N } - fn index(&self, index: usize) -> usize { + const fn index(&self, index: usize) -> usize { (self.start + index) % N } } From 63cbaa412faf914e34dabea20e179e28cdef483c Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:35:16 -0700 Subject: [PATCH 45/47] Fix --- src/array_queue.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 3eb580f..6518088 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -20,17 +20,17 @@ impl ArrayQueue { } /// Returns a reference to the first element of the queue, or `None` if it is empty. - pub fn first(&self) -> Option<&T> { + pub const fn first(&self) -> Option<&T> { self.element(0) } /// Returns a mutable reference to the first element of the queue, or `None` if it is empty. - pub fn first_mut(&mut self) -> Option<&mut T> { + pub const fn first_mut(&mut self) -> Option<&mut T> { self.element_mut(0) } /// Returns a reference to the last element of the queue, or `None` if it is empty. - pub fn last(&self) -> Option<&T> { + pub const fn last(&self) -> Option<&T> { if self.is_empty() { None } else { @@ -39,7 +39,7 @@ impl ArrayQueue { } /// Returns a mutable reference to the last element of the queue, or `None` if it is empty. - pub fn last_mut(&mut self) -> Option<&mut T> { + pub const fn last_mut(&mut self) -> Option<&mut T> { if self.is_empty() { None } else { @@ -47,7 +47,7 @@ impl ArrayQueue { } } - fn element(&self, index: usize) -> Option<&T> { + const fn element(&self, index: usize) -> Option<&T> { if index < self.length { let x = &self.array[self.index(index)]; @@ -57,7 +57,7 @@ impl ArrayQueue { } } - fn element_mut(&mut self, index: usize) -> Option<&mut T> { + const fn element_mut(&mut self, index: usize) -> Option<&mut T> { if index < self.length { let x = &mut self.array[self.index(index)]; @@ -105,7 +105,7 @@ impl ArrayQueue { } /// Pops an element from the front of the queue. - pub fn pop_front(&mut self) -> Option { + pub const fn pop_front(&mut self) -> Option { if self.is_empty() { None } else { @@ -157,6 +157,7 @@ impl Default for ArrayQueue { impl Drop for ArrayQueue { fn drop(&mut self) { + #[expect(clippy::redundant_pattern_matching)] while let Some(_) = self.pop_back() {} } } From 5ff4d5e1f2d3365bb474a07d4f1a379ad7b432d5 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:38:58 -0700 Subject: [PATCH 46/47] Fix --- src/array_queue.rs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/array_queue.rs b/src/array_queue.rs index 6518088..4aadc8b 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -51,6 +51,7 @@ impl ArrayQueue { if index < self.length { let x = &self.array[self.index(index)]; + // SAFETY: We validate the element existence by the length check. Some(unsafe { x.assume_init_ref() }) } else { None @@ -61,58 +62,61 @@ impl ArrayQueue { if index < self.length { let x = &mut self.array[self.index(index)]; + // SAFETY: We validate the element existence by the length check. Some(unsafe { x.assume_init_mut() }) } else { None } } - /// Pushes an element to the back of the queue. - pub fn push_back(&mut self, x: T) -> Result<(), CapacityError> { + /// Pushes an element to the front of the queue. + pub fn push_front(&mut self, x: T) -> Result<(), CapacityError> { if self.is_full() { return Err(CapacityError); } - self.array[self.index(self.length)] = MaybeUninit::new(x); + self.start = self.index(N - 1); + self.array[self.start] = MaybeUninit::new(x); self.length += 1; Ok(()) } - /// Pushes an element to the front of the queue. - pub fn push_front(&mut self, x: T) -> Result<(), CapacityError> { + /// Pushes an element to the back of the queue. + pub fn push_back(&mut self, x: T) -> Result<(), CapacityError> { if self.is_full() { return Err(CapacityError); } - self.start = self.index(N - 1); - self.array[self.start] = MaybeUninit::new(x); + self.array[self.index(self.length)] = MaybeUninit::new(x); self.length += 1; Ok(()) } - /// Pops an element from the back of the queue. - pub const fn pop_back(&mut self) -> Option { + /// Pops an element from the front of the queue. + pub const fn pop_front(&mut self) -> Option { if self.is_empty() { None } else { - let x = replace(&mut self.array[self.length - 1], MaybeUninit::uninit()); + let x = replace(&mut self.array[self.start], MaybeUninit::uninit()); + self.start = self.index(1); self.length -= 1; + // SAFETY: An element exists at the first index. Some(unsafe { x.assume_init() }) } } - /// Pops an element from the front of the queue. - pub const fn pop_front(&mut self) -> Option { + /// Pops an element from the back of the queue. + pub const fn pop_back(&mut self) -> Option { if self.is_empty() { None } else { - let x = replace(&mut self.array[self.start], MaybeUninit::uninit()); - self.start = self.index(1); + let x = replace(&mut self.array[self.length - 1], MaybeUninit::uninit()); self.length -= 1; + // SAFETY: An element exists at the last index. Some(unsafe { x.assume_init() }) } } @@ -252,6 +256,7 @@ impl<'a, T, const N: usize> Iterator for ArrayQueueMutIterator<'a, T, N> { let x = self.queue.element_mut(self.first); self.first += x.is_some() as usize; + // SAFETY: We do not modify the `queue` field during an iteration. x.map(|x| unsafe { transmute(x) }) } } @@ -264,6 +269,7 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayQueueMutIterator<'a, T, let x = self.queue.element_mut(self.last - 1); self.last -= x.is_some() as usize; + // SAFETY: We do not modify the `queue` field during an iteration. x.map(|x| unsafe { transmute(x) }) } } From 8a082157814bd5a53f9d1a9284227d31fd7eecac Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sun, 31 Aug 2025 21:39:30 -0700 Subject: [PATCH 47/47] fix --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 460bb56..ee00b56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ arrayvec = "0.4" [lints.clippy] alloc_instead_of_core = "deny" -cargo = "deny" complexity = "deny" correctness = "deny" dbg_macro = "deny"