use super::*; use alloc::collections::BTreeSet;
use alloc::format;
use alloc::string::ToString;
use alloc::vec;
use core::fmt::Debug;
use core::ops::{Deref, DerefMut};
use rand::prelude::*;
use std::panic::AssertUnwindSafe;
#[cfg(feature = "allocator_api")]
use alloc::alloc::Global;
#[cfg(feature = "allocator_api")]
mod allocator_tests {
use super::*;
#[test]
fn test_new_in() {
let p: super::super::Partition<i32, Global> = super::super::Partition::new_in(Global);
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
}
#[test]
fn test_with_capacity_in() {
let capacity = 10;
let p: super::super::Partition<i32, Global> =
super::super::Partition::with_capacity_in(capacity, Global);
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
assert!(p.capacity() >= capacity);
}
#[test]
fn test_from_raw_parts_with_allocator() {
let vec: Vec<i32, Global> = Vec::new_in(Global);
let mut vec_with_items: Vec<i32, Global> = Vec::with_capacity_in(4, Global);
vec_with_items.push(1);
vec_with_items.push(2);
vec_with_items.push(3);
vec_with_items.push(4);
let p = super::super::Partition::from_raw_parts(vec, 0);
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
let p = super::super::Partition::from_raw_parts(vec_with_items, 2);
assert_eq!(p.left(), &[1, 2]);
assert_eq!(p.right(), &[3, 4]);
}
#[test]
fn test_from_raw_parts_unchecked_with_allocator() {
let mut vec_with_items: Vec<i32, Global> = Vec::with_capacity_in(4, Global);
vec_with_items.push(1);
vec_with_items.push(2);
vec_with_items.push(3);
vec_with_items.push(4);
let p = unsafe { super::super::Partition::from_raw_parts_unchecked(vec_with_items, 2) };
assert_eq!(p.left(), &[1, 2]);
assert_eq!(p.right(), &[3, 4]);
}
#[test]
#[should_panic]
fn test_from_raw_parts_panic_with_allocator() {
let mut vec: Vec<i32, Global> = Vec::with_capacity_in(3, Global);
vec.push(1);
vec.push(2);
vec.push(3);
let _p = super::super::Partition::from_raw_parts(vec, 4);
}
}
#[derive(Clone)]
pub struct Partition<T>(super::Partition<T>);
impl<T: Debug> Debug for Partition<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl<T> Default for Partition<T> {
fn default() -> Self {
Self(super::Partition::new())
}
}
impl<T> Partition<T> {
pub fn new() -> Self {
Self(super::Partition::new())
}
pub fn with_capacity(capacity: usize) -> Self {
Self(super::Partition::with_capacity(capacity))
}
pub fn from_raw_parts(inner: Vec<T>, partition: usize) -> Self {
Self(super::Partition::from_raw_parts(inner, partition))
}
pub unsafe fn from_raw_parts_unchecked(inner: Vec<T>, partition: usize) -> Self {
Self(unsafe { super::Partition::from_raw_parts_unchecked(inner, partition) })
}
pub fn to_raw_parts(self) -> (Vec<T>, usize) {
let (vec, partition) = self.0.to_raw_parts();
(vec, partition)
}
}
impl<T> DerefMut for Partition<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
let mut rng = rand::rng();
self.0.left_mut().shuffle(&mut rng);
self.0.right_mut().shuffle(&mut rng);
&mut self.0
}
}
impl<T> Deref for Partition<T> {
type Target = super::Partition<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn check_set_equality<T, I1, I2>(left: I1, right: I2)
where
T: Eq + Ord + Debug,
I1: IntoIterator<Item = T>,
I2: IntoIterator<Item = T>,
{
let left_set: BTreeSet<_> = left.into_iter().collect();
let right_set: BTreeSet<_> = right.into_iter().collect();
assert_eq!(left_set, right_set);
}
#[test]
fn test_partition_order_independence() {
let mut p1 = Partition::new();
let mut p2 = Partition::new();
let mut p3 = Partition::new();
p1.push_left(1);
p1.push_left(2);
p1.push_left(3);
p2.push_left(3);
p2.push_left(1);
p2.push_left(2);
p3.push_left(2);
p3.push_left(3);
p3.push_left(1);
check_set_equality(p1.left().iter().copied(), [1, 2, 3]);
check_set_equality(p2.left().iter().copied(), [1, 2, 3]);
check_set_equality(p3.left().iter().copied(), [1, 2, 3]);
check_set_equality(p1.left().iter().copied(), [1, 2, 3]);
check_set_equality(p2.left().iter().copied(), [1, 2, 3]);
check_set_equality(p3.left().iter().copied(), [1, 2, 3]);
}
#[test]
fn test_new() {
let p: Partition<i32> = Partition::new();
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
}
#[test]
fn test_with_capacity() {
let p: Partition<i32> = Partition::with_capacity(10);
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
assert!(p.capacity() >= 10);
}
#[test]
fn test_capacity() {
let mut p: Partition<i32> = Partition::new();
let initial_capacity = p.capacity();
for i in 0..initial_capacity + 10 {
p.push_left(i as i32);
}
assert!(p.capacity() > initial_capacity);
}
#[test]
fn test_reserve() {
let mut p: Partition<i32> = Partition::new();
p.push_left(1);
p.push_right(2);
let current_len = p.len();
p.reserve(20);
assert!(p.capacity() >= current_len + 20);
check_set_equality(p.left().iter().copied(), [1]);
check_set_equality(p.right().iter().copied(), [2]);
}
#[test]
fn test_reserve_exact() {
let mut p: Partition<i32> = Partition::new();
p.push_left(1);
p.push_right(2);
let current_len = p.len();
let additional = 15;
p.reserve_exact(additional);
assert!(p.capacity() >= current_len + additional);
check_set_equality(p.left().iter().copied(), [1]);
check_set_equality(p.right().iter().copied(), [2]);
}
#[test]
fn test_shrink_to_fit() {
let mut p: Partition<i32> = Partition::with_capacity(100);
p.push_left(1);
p.push_left(2);
p.push_right(3);
assert!(p.capacity() > 3);
p.shrink_to_fit();
assert!(p.capacity() >= 3);
assert_eq!(p.len(), 3);
check_set_equality(p.left().iter().copied(), [1, 2]);
check_set_equality(p.right().iter().copied(), [3]);
}
#[test]
fn test_shrink_to() {
let mut p: Partition<i32> = Partition::with_capacity(100);
p.push_left(1);
p.push_left(2);
p.push_right(3);
assert!(p.capacity() > 3);
p.shrink_to(10);
assert!(p.capacity() >= 3);
assert!(p.capacity() <= 10);
assert_eq!(p.len(), 3);
check_set_equality(p.left().iter().copied(), [1, 2]);
check_set_equality(p.right().iter().copied(), [3]);
p.shrink_to(2); assert!(p.capacity() >= 3);
}
#[test]
fn test_try_reserve() {
let mut p: Partition<i32> = Partition::new();
p.push_left(1);
p.push_right(2);
let result = p.try_reserve(10);
assert!(result.is_ok());
assert!(p.capacity() >= p.len() + 10);
check_set_equality(p.left().iter().copied(), [1]);
check_set_equality(p.right().iter().copied(), [2]);
}
#[test]
fn test_try_reserve_exact() {
let mut p: Partition<i32> = Partition::new();
p.push_left(1);
p.push_right(2);
let result = p.try_reserve_exact(10);
assert!(result.is_ok());
assert!(p.capacity() >= p.len() + 10);
check_set_equality(p.left().iter().copied(), [1]);
check_set_equality(p.right().iter().copied(), [2]);
}
#[test]
fn test_append() {
let mut p1 = Partition::new();
p1.push_left(1);
p1.push_left(2);
p1.push_right(3);
let mut p2 = Partition::new();
p2.push_left(4);
p2.push_right(5);
p2.push_right(6);
let p1_left_len = p1.left().len();
let p1_right_len = p1.right().len();
let p2_left_len = p2.left().len();
let p2_right_len = p2.right().len();
p1.append(&mut p2);
assert_eq!(p1.left().len(), p1_left_len + p2_left_len);
assert_eq!(p1.right().len(), p1_right_len + p2_right_len);
let left_contains_all = [1, 2, 4].iter().all(|&x| p1.left().contains(&x));
let right_contains_all = [3, 5, 6].iter().all(|&x| p1.right().contains(&x));
assert!(
left_contains_all,
"Left partition missing expected elements"
);
assert!(
right_contains_all,
"Right partition missing expected elements"
);
assert!(p2.is_empty());
assert_eq!(p2.left().len(), 0);
assert_eq!(p2.right().len(), 0);
}
#[test]
fn test_append_non_copy_types() {
let mut p1 = Partition::new();
p1.push_left("hello".to_string());
p1.push_right("world".to_string());
let mut p2 = Partition::new();
p2.push_left("foo".to_string());
p2.push_right("bar".to_string());
p1.append(&mut p2);
assert_eq!(p1.left().len(), 2);
assert_eq!(p1.right().len(), 2);
assert!(p2.is_empty());
let left_contains_all =
p1.left().iter().any(|s| s == "hello") && p1.left().iter().any(|s| s == "foo");
let right_contains_all =
p1.right().iter().any(|s| s == "world") && p1.right().iter().any(|s| s == "bar");
assert!(
left_contains_all,
"Left partition missing expected elements"
);
assert!(
right_contains_all,
"Right partition missing expected elements"
);
}
#[test]
fn test_set_partition() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
p.push_right(4);
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
unsafe {
p.set_partition(0);
}
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 4);
check_set_equality(p.right().iter().copied(), [1, 2, 3, 4]);
unsafe {
p.set_partition(4);
}
assert_eq!(p.left().len(), 4);
assert_eq!(p.right().len(), 0);
check_set_equality(p.left().iter().copied(), [1, 2, 3, 4]);
unsafe {
p.set_partition(2);
}
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
let mut empty_p: Partition<i32> = Partition::new();
unsafe {
empty_p.set_partition(0);
}
assert_eq!(empty_p.left().len(), 0);
assert_eq!(empty_p.right().len(), 0);
let mut p2 = Partition::new();
p2.push_left(1);
let should_panic = std::panic::catch_unwind(AssertUnwindSafe(|| {
unsafe {
p2.set_partition(2); }
}));
assert!(
should_panic.is_err(),
"set_partition should panic with out-of-bounds index"
);
}
#[test]
fn test_swap_remove_left() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_left(3);
p.push_right(4);
assert_eq!(p.left().len(), 3);
let removed = p.swap_remove_left(1);
assert!(removed == 1 || removed == 2 || removed == 3);
assert_eq!(p.left().len(), 2);
let left_elements: Vec<_> = p.left().to_vec();
assert!(!left_elements.contains(&removed));
assert_eq!(p.right().len(), 1);
assert!(p.right().contains(&4));
let mut empty_p: Partition<i32> = Partition::new();
let should_panic = std::panic::catch_unwind(AssertUnwindSafe(|| {
empty_p.swap_remove_left(0);
}));
assert!(
should_panic.is_err(),
"swap_remove_left should panic with out-of-bounds index"
);
}
#[test]
fn test_swap_remove_right() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_right(3);
p.push_right(4);
assert_eq!(p.right().len(), 3);
let removed = p.swap_remove_right(0);
assert!(removed == 2 || removed == 3 || removed == 4);
assert_eq!(p.right().len(), 2);
let right_elements: Vec<_> = p.right().to_vec();
assert!(!right_elements.contains(&removed));
assert_eq!(p.left().len(), 1);
assert!(p.left().contains(&1));
let mut empty_p: Partition<i32> = Partition::new();
let should_panic = std::panic::catch_unwind(AssertUnwindSafe(|| {
empty_p.swap_remove_right(0);
}));
assert!(
should_panic.is_err(),
"swap_remove_right should panic with out-of-bounds index"
);
}
#[test]
fn test_retain_left() {
let mut p = Partition::new();
for i in 1..=10 {
if i <= 6 {
p.push_left(i);
} else {
p.push_right(i);
}
}
p.retain_left(|&x| x % 2 == 0);
assert!(
p.left().iter().all(|&x| x % 2 == 0),
"Left partition should only contain even numbers"
);
assert_eq!(
p.left().len(),
3,
"Left should have exactly 3 elements (2,4,6)"
);
assert!(p.left().contains(&2));
assert!(p.left().contains(&4));
assert!(p.left().contains(&6));
assert_eq!(p.right().len(), 4);
for i in 7..=10 {
assert!(
p.right().contains(&i),
"Right partition missing element {}",
i
);
}
let mut empty_left = Partition::new();
empty_left.push_right(1);
empty_left.retain_left(|_| false);
assert_eq!(empty_left.left().len(), 0);
assert_eq!(empty_left.right().len(), 1);
}
#[test]
fn test_retain_right() {
let mut p = Partition::new();
for i in 1..=10 {
if i <= 5 {
p.push_left(i);
} else {
p.push_right(i);
}
}
p.retain_right(|&x| x % 2 == 1);
assert!(
p.right().iter().all(|&x| x % 2 == 1),
"Right partition should only contain odd numbers"
);
assert_eq!(p.right().len(), 2);
assert!(p.right().contains(&7));
assert!(p.right().contains(&9));
assert_eq!(p.left().len(), 5);
for i in 1..=5 {
assert!(
p.left().contains(&i),
"Left partition missing element {}",
i
);
}
let mut empty_right = Partition::new();
empty_right.push_left(1);
empty_right.retain_right(|_| false);
assert_eq!(empty_right.left().len(), 1);
assert_eq!(empty_right.right().len(), 0);
}
#[test]
fn test_retain_edge_cases() {
let mut p1 = Partition::new();
p1.push_left(1);
p1.push_left(2);
p1.push_right(3);
p1.retain_left(|_| false);
assert_eq!(p1.left().len(), 0);
assert_eq!(p1.right().len(), 1);
let mut p2 = Partition::new();
p2.push_left(1);
p2.push_right(2);
p2.push_right(3);
p2.retain_right(|_| true);
assert_eq!(p2.left().len(), 1);
assert_eq!(p2.right().len(), 2);
let mut p3 = Partition::new();
for i in 1..=10 {
p3.push_left(i);
}
for i in 11..=20 {
p3.push_right(i);
}
let is_prime = |&n: &i32| {
if n <= 1 {
return false;
}
if n <= 3 {
return true;
}
if n % 2 == 0 || n % 3 == 0 {
return false;
}
let mut i = 5;
while i * i <= n {
if n % i == 0 || n % (i + 2) == 0 {
return false;
}
i += 6;
}
true
};
p3.retain_left(is_prime);
assert_eq!(p3.left().len(), 4);
assert!(p3.left().contains(&2));
assert!(p3.left().contains(&3));
assert!(p3.left().contains(&5));
assert!(p3.left().contains(&7));
assert_eq!(p3.right().len(), 10);
for i in 11..=20 {
assert!(p3.right().contains(&i));
}
}
#[test]
fn test_push_left() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
check_set_equality(p.left().iter().copied(), [1, 2]);
}
#[test]
fn test_push_right() {
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
check_set_equality(p.right().iter().copied(), [1, 2]);
}
#[test]
fn test_automatic_shuffling() {
let mut first = Partition::new();
let mut second = Partition::new();
for i in 0..10 {
first.push_left(i);
second.push_left(i);
}
second.push_right(100);
check_set_equality(first.left().iter().copied(), second.left().iter().copied());
}
#[test]
fn test_mixed_push() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_left(3);
p.push_right(4);
check_set_equality(p.left().iter().copied(), [1, 3]);
check_set_equality(p.right().iter().copied(), [2, 4]);
}
#[test]
fn test_pop_left() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
let val = p.pop_left();
assert!(val == Some(1) || val == Some(2));
let remaining = if val == Some(1) { 2 } else { 1 };
check_set_equality(p.left(), &[remaining]);
assert_eq!(p.pop_left(), Some(remaining));
assert_eq!(p.left(), &[]);
assert_eq!(p.pop_left(), None);
}
#[test]
fn test_pop_right() {
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
let first_popped = p.pop_right();
assert!(first_popped == Some(1) || first_popped == Some(2));
assert_eq!(p.right().len(), 1);
let first_val = first_popped.unwrap();
let second_val = if first_val == 1 { 2 } else { 1 };
check_set_equality(p.right(), &[second_val]);
let second_popped = p.pop_right();
assert_eq!(second_popped, Some(second_val));
assert_eq!(p.right(), &[]);
assert_eq!(p.pop_right(), None);
}
#[test]
fn test_left_and_right() {
let mut p = Partition::new();
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[]);
p.push_left(1);
p.push_right(2);
check_set_equality(p.left(), &[1]);
check_set_equality(p.right(), &[2]);
}
#[test]
fn test_left_mut_and_right_mut() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
for item in p.left_mut() {
*item = 3;
}
for item in p.right_mut() {
*item = 4;
}
check_set_equality(p.left(), &[3]);
check_set_equality(p.right(), &[4]);
}
#[test]
fn test_move_to_left() {
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
let first_moved = p.move_to_left();
assert!(first_moved == Some(1) || first_moved == Some(2));
assert_eq!(p.left().len(), 1);
assert_eq!(p.right().len(), 1);
let left_val = first_moved.unwrap();
check_set_equality(p.left(), &[left_val]);
let right_val = if left_val == 1 { 2 } else { 1 };
check_set_equality(p.right(), &[right_val]);
let second_moved = p.move_to_left();
assert_eq!(second_moved, Some(right_val));
check_set_equality(p.left(), &[1, 2]);
assert_eq!(p.right(), &[]);
assert_eq!(p.move_to_left(), None);
}
#[test]
fn test_move_to_right() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
let val = p.move_to_right();
assert!(val == Some(1) || val == Some(2));
let remaining = if val == Some(1) { 2 } else { 1 };
let moved = if val == Some(1) { 1 } else { 2 };
check_set_equality(p.left(), &[remaining]);
check_set_equality(p.right(), &[moved]);
assert_eq!(p.move_to_right(), Some(remaining));
assert_eq!(p.left(), &[]);
check_set_equality(p.right(), &[1, 2]);
assert_eq!(p.move_to_right(), None);
}
#[test]
fn test_drain_left() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
let drained: Vec<_> = p.drain_left().collect();
assert_eq!(drained.len(), 2);
assert_eq!(p.left(), &[]);
assert_eq!(p.right(), &[3]);
}
#[test]
fn test_drain_right() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_right(3);
let drained: Vec<_> = p.drain_right().collect();
assert_eq!(drained.len(), 2);
assert_eq!(p.right(), &[]);
assert_eq!(p.left(), &[1]);
}
#[test]
fn test_drain_empty() {
let mut p: Partition<i32> = Partition::new();
let drained: Vec<_> = p.drain_left().collect();
assert_eq!(drained, vec![]);
let drained: Vec<_> = p.drain_right().collect();
assert_eq!(drained, vec![]);
}
#[test]
fn test_drain_to_right() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
let moved: Vec<_> = p.drain_to_right().collect();
assert_eq!(moved.len(), 2);
assert_eq!(p.left(), &[]);
assert_eq!(p.right().len(), 3);
let right_vals: BTreeSet<_> = p.right().iter().copied().collect();
assert!(right_vals.contains(&1));
assert!(right_vals.contains(&2));
assert!(right_vals.contains(&3));
}
#[test]
fn test_drain_to_left() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_right(3);
let moved: Vec<_> = p.drain_to_left().collect();
assert_eq!(moved.len(), 2);
assert_eq!(p.right(), &[]);
assert_eq!(p.left().len(), 3);
let left_vals: BTreeSet<_> = p.left().iter().copied().collect();
assert!(left_vals.contains(&1));
assert!(left_vals.contains(&2));
assert!(left_vals.contains(&3));
}
#[test]
fn test_drain_iterator_size_hint() {
{
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
let iter = p.drain_to_right();
assert_eq!(iter.size_hint(), (2, Some(2)));
}
{
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
let iter = p.drain_to_left();
assert_eq!(iter.size_hint(), (2, Some(2)));
}
}
#[test]
fn test_drain_partially_consumed() {
{
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_left(3);
let left_count = p.left().len();
{
let mut iter = p.drain_to_right();
let first = iter.next();
assert!(first.is_some());
}
assert_eq!(p.left(), &[]);
assert_eq!(p.right().len(), left_count);
}
{
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
p.push_right(3);
let right_count = p.right().len();
{
let mut iter = p.drain_to_left();
let first = iter.next();
assert!(first.is_some());
}
assert_eq!(p.right(), &[]);
assert_eq!(p.left().len(), right_count);
}
}
#[test]
fn test_drain_immediate_drop() {
{
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
drop(p.drain_to_right());
assert_eq!(p.left(), &[]);
assert_eq!(p.right().len(), 2);
}
{
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
drop(p.drain_to_left());
assert_eq!(p.right(), &[]);
assert_eq!(p.left().len(), 2);
}
}
#[test]
fn test_complex_operations() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_left(3);
check_set_equality(p.left(), &[1, 3]);
check_set_equality(p.right(), &[2]);
let val = p.move_to_right();
assert!(val == Some(1) || val == Some(3));
let moved_left = p.move_to_left();
assert!(moved_left.is_some());
let left_count = p.left().len();
let right_count = p.right().len();
assert_eq!(left_count + right_count, 3);
let drained_left: Vec<_> = p.drain_to_right().collect();
assert_eq!(drained_left.len(), left_count);
assert_eq!(p.left(), &[]);
assert_eq!(p.right().len(), 3);
let drained_right: Vec<_> = p.drain_to_left().collect();
assert_eq!(drained_right.len(), 3);
assert_eq!(p.right(), &[]);
assert_eq!(p.left().len(), 3);
}
#[test]
fn test_large_partition_with_interleaved_operations() {
let mut p = Partition::new();
for i in 0..50 {
if i % 3 == 0 {
p.push_left(i);
} else {
p.push_right(i);
}
}
let expected_left: Vec<_> = (0..50).filter(|&i| i % 3 == 0).collect();
let expected_right: Vec<_> = (0..50).filter(|&i| i % 3 != 0).collect();
let left_vec: Vec<_> = p.left().to_vec();
let right_vec: Vec<_> = p.right().to_vec();
for &val in &expected_left {
assert!(left_vec.contains(&val));
}
assert_eq!(left_vec.len(), expected_left.len());
for &val in &expected_right {
assert!(right_vec.contains(&val));
}
assert_eq!(right_vec.len(), expected_right.len());
let left_count = p.left().len();
let mut moved_to_right = Vec::new();
for _ in 0..(left_count / 2) {
if let Some(val) = p.move_to_right() {
moved_to_right.push(val);
}
}
assert_eq!(p.left().len(), left_count - moved_to_right.len());
for _ in 0..5 {
p.move_to_left();
}
for i in 50..60 {
if i % 2 == 0 {
p.push_left(i);
} else {
p.push_right(i);
}
}
let left_elements: Vec<_> = p.drain_left().collect();
let right_elements: Vec<_> = p.drain_right().collect();
assert_eq!(left_elements.len() + right_elements.len(), 60);
assert!(p.left().is_empty());
assert!(p.right().is_empty());
}
#[test]
fn test_random_operation_sequence() {
let mut p = Partition::new();
let mut expected_left = Vec::new();
let mut expected_right = Vec::new();
for i in 0..10 {
if i % 2 == 0 {
p.push_left(i);
expected_left.push(i);
} else {
p.push_right(i);
expected_right.push(i);
}
}
let left_vec: Vec<_> = p.left().to_vec();
let right_vec: Vec<_> = p.right().to_vec();
assert_eq!(left_vec.len(), expected_left.len());
assert_eq!(right_vec.len(), expected_right.len());
for &val in &expected_left {
assert!(left_vec.contains(&val));
}
for &val in &expected_right {
assert!(right_vec.contains(&val));
}
for _ in 0..2 {
if let Some(val) = p.move_to_right() {
expected_left.retain(|&x| x != val);
expected_right.push(val);
}
}
if let Some(val) = p.move_to_left() {
expected_right.retain(|&x| x != val);
expected_left.push(val);
}
let left_vec: Vec<_> = p.left().to_vec();
let right_vec: Vec<_> = p.right().to_vec();
assert_eq!(left_vec.len(), expected_left.len());
assert_eq!(right_vec.len(), expected_right.len());
for &val in &expected_left {
assert!(left_vec.contains(&val));
}
for &val in &expected_right {
assert!(right_vec.contains(&val));
}
if let Some(val) = p.pop_left() {
expected_left.retain(|&x| x != val);
}
if let Some(val) = p.pop_right() {
expected_right.retain(|&x| x != val);
}
let left_vec: Vec<_> = p.left().to_vec();
let right_vec: Vec<_> = p.right().to_vec();
assert_eq!(left_vec.len(), expected_left.len());
assert_eq!(right_vec.len(), expected_right.len());
for &val in &expected_left {
assert!(left_vec.contains(&val));
}
for &val in &expected_right {
assert!(right_vec.contains(&val));
}
for i in 10..15 {
if i % 2 == 0 {
p.push_left(i);
expected_left.push(i);
} else {
p.push_right(i);
expected_right.push(i);
}
}
let left_count = expected_left.len();
let right_count = expected_right.len();
let drained_left: Vec<_> = p.drain_to_right().collect();
assert_eq!(drained_left.len(), left_count);
assert!(p.left().is_empty());
assert_eq!(p.right().len(), left_count + right_count);
}
#[test]
fn test_push_left_swap_behavior() {
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
p.push_right(3);
assert_eq!(p.left(), &[]);
check_set_equality(p.right().iter().copied(), [1, 2, 3]);
p.push_left(4);
check_set_equality(p.left().iter().copied(), [4]);
let right_set: BTreeSet<_> = p.right().iter().copied().collect();
assert_eq!(right_set.len(), 3);
assert!(right_set.contains(&1));
assert!(right_set.contains(&2));
assert!(right_set.contains(&3));
p.push_left(5);
check_set_equality(p.left().iter().copied(), [4, 5]);
let right_set: BTreeSet<_> = p.right().iter().copied().collect();
assert_eq!(right_set.len(), 3);
assert!(right_set.contains(&1));
assert!(right_set.contains(&2));
assert!(right_set.contains(&3));
}
#[test]
fn test_partitions() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
p.push_right(4);
let (left, right) = p.partitions();
check_set_equality(left.iter().copied(), [1, 2]);
check_set_equality(right.iter().copied(), [3, 4]);
}
#[test]
fn test_partitions_mut() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
p.push_right(4);
let (left_mut, right_mut) = p.partitions_mut();
for item in left_mut.iter_mut() {
*item *= 10;
}
for item in right_mut.iter_mut() {
*item *= 100;
}
check_set_equality(p.left().iter().copied(), [10, 20]);
check_set_equality(p.right().iter().copied(), [300, 400]);
}
#[test]
fn test_len() {
let mut p = Partition::new();
assert_eq!(p.len(), 0);
p.push_left(1);
assert_eq!(p.len(), 1);
p.push_right(2);
assert_eq!(p.len(), 2);
p.push_left(3);
assert_eq!(p.len(), 3);
p.pop_left();
assert_eq!(p.len(), 2);
p.pop_right();
assert_eq!(p.len(), 1);
p.pop_left();
assert_eq!(p.len(), 0);
}
#[test]
fn test_is_empty() {
let mut p = Partition::new();
assert!(p.is_empty());
p.push_left(1);
assert!(!p.is_empty());
p.pop_left();
assert!(p.is_empty());
p.push_right(2);
assert!(!p.is_empty());
p.pop_right();
assert!(p.is_empty());
}
#[test]
fn test_clear() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
p.push_right(4);
assert_eq!(p.len(), 4);
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
p.clear();
assert!(p.is_empty());
assert_eq!(p.len(), 0);
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 0);
p.push_left(5);
p.push_right(6);
assert_eq!(p.len(), 2);
assert_eq!(p.left().len(), 1);
assert_eq!(p.right().len(), 1);
check_set_equality(p.left().iter().copied(), [5]);
check_set_equality(p.right().iter().copied(), [6]);
}
#[test]
fn test_to_raw_parts() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_right(3);
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 1);
let (vec, partition) = p.to_raw_parts();
assert_eq!(vec.len(), 3);
assert_eq!(partition, 2);
let mut elements = vec.clone();
elements.sort();
assert_eq!(elements, vec![1, 2, 3]);
}
#[test]
fn test_from_raw_parts() {
let vec = vec![10, 20, 30, 40];
let partition = 2;
let p = Partition::from_raw_parts(vec, partition);
assert_eq!(p.left(), &[10, 20]);
assert_eq!(p.right(), &[30, 40]);
let vec = Vec::<i32>::new();
let partition = 0;
let p = Partition::from_raw_parts(vec, partition);
assert!(p.left().is_empty());
assert!(p.right().is_empty());
let vec = vec![1, 2, 3];
let partition = 3;
let p = Partition::from_raw_parts(vec, partition);
assert_eq!(p.left(), &[1, 2, 3]);
assert!(p.right().is_empty());
let vec = vec![1, 2, 3];
let partition = 0;
let p = Partition::from_raw_parts(vec, partition);
assert!(p.left().is_empty());
assert_eq!(p.right(), &[1, 2, 3]);
}
#[test]
#[should_panic(expected = "partition index 4 is out of bounds")]
fn test_from_raw_parts_panic() {
let vec = vec![1, 2, 3];
let partition = 4;
let _p = Partition::from_raw_parts(vec, partition);
}
#[test]
fn test_from_raw_parts_unchecked() {
let vec = vec![10, 20, 30, 40];
let partition = 2;
let p = unsafe { Partition::from_raw_parts_unchecked(vec, partition) };
assert_eq!(p.left(), &[10, 20]);
assert_eq!(p.right(), &[30, 40]);
let vec = Vec::<i32>::new();
let partition = 0;
let p = unsafe { Partition::from_raw_parts_unchecked(vec, partition) };
assert!(p.left().is_empty());
assert!(p.right().is_empty());
let vec = vec![1, 2, 3];
let partition = 3;
let p = unsafe { Partition::from_raw_parts_unchecked(vec, partition) };
assert_eq!(p.left(), &[1, 2, 3]);
assert!(p.right().is_empty());
let vec = vec![1, 2, 3];
let partition = 0;
let p = unsafe { Partition::from_raw_parts_unchecked(vec, partition) };
assert!(p.left().is_empty());
assert_eq!(p.right(), &[1, 2, 3]);
}
#[test]
fn test_raw_parts_roundtrip() {
let mut original = Partition::new();
original.push_left(1);
original.push_left(2);
original.push_right(3);
original.push_right(4);
let (vec, partition) = original.to_raw_parts();
let reconstructed = Partition::from_raw_parts(vec, partition);
check_set_equality(reconstructed.left().iter().copied(), [1, 2]);
check_set_equality(reconstructed.right().iter().copied(), [3, 4]);
}
#[test]
fn test_with_non_copy_types() {
let mut p = Partition::new();
p.push_left("hello".to_string());
p.push_left("world".to_string());
p.push_right("foo".to_string());
p.push_right("bar".to_string());
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
let left_has_hello = p.left().iter().any(|s| s == "hello");
let left_has_world = p.left().iter().any(|s| s == "world");
assert!(left_has_hello);
assert!(left_has_world);
let popped = p.pop_left();
assert!(popped.is_some());
let popped_val = popped.unwrap();
assert!(popped_val == "hello" || popped_val == "world");
let p_clone = p.clone();
assert_eq!(p.left().len(), p_clone.left().len());
assert_eq!(p.right().len(), p_clone.right().len());
p.push_left("another".to_string());
assert_ne!(p.left().len(), p_clone.left().len());
}
#[test]
fn test_clone_behavior() {
let mut original = Partition::new();
original.push_left(1);
original.push_left(2);
original.push_right(3);
let cloned = original.clone();
check_set_equality(
original.left().iter().copied(),
cloned.left().iter().copied(),
);
check_set_equality(
original.right().iter().copied(),
cloned.right().iter().copied(),
);
original.push_left(4);
original.push_right(5);
assert_eq!(cloned.left().len(), 2);
assert_eq!(cloned.right().len(), 1);
check_set_equality(cloned.left().iter().copied(), [1, 2]);
check_set_equality(cloned.right().iter().copied(), [3]);
}
#[test]
fn test_default_behavior() {
let p: Partition<i32> = Default::default();
assert!(p.is_empty());
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 0);
}
#[test]
fn test_partial_iterator_consumption() {
let mut p = Partition::new();
for i in 0..10 {
p.push_left(i);
}
let mut iter = p.drain_to_right();
for _ in 0..5 {
let _ = iter.next();
}
drop(iter);
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 10);
let mut p = Partition::new();
for i in 0..10 {
p.push_right(i);
}
let mut iter = p.drain_to_left();
assert!(iter.next().is_some());
assert!(iter.next().is_some());
drop(iter);
assert_eq!(p.left().len(), 10);
assert_eq!(p.right().len(), 0);
}
#[test]
fn test_iterator_size_hint_accuracy() {
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
p.push_left(3);
let iter = p.drain_to_right();
assert_eq!(iter.size_hint(), (3, Some(3)));
let mut p = Partition::new();
p.push_left(1);
p.push_left(2);
let iter = p.drain_left();
assert_eq!(iter.size_hint(), (2, Some(2)));
let mut p = Partition::new();
p.push_right(1);
p.push_right(2);
let iter = p.drain_right();
assert_eq!(iter.size_hint(), (2, Some(2)));
}
#[test]
fn test_partition_invariants() {
let mut p = Partition::new();
for i in 0..100 {
if i % 2 == 0 {
p.push_left(i);
} else {
p.push_right(i);
}
assert!(p.partition <= p.len());
}
for _ in 0..50 {
if p.left().len() > 0 {
p.pop_left();
}
if p.right().len() > 0 {
p.pop_right();
}
assert!(p.partition <= p.len());
}
}
#[test]
fn test_boundary_conditions() {
let mut p = Partition::new();
for i in 0..1000 {
if i % 2 == 0 {
p.push_left(i);
} else {
p.push_right(i);
}
}
assert_eq!(p.left().len(), 500);
assert_eq!(p.right().len(), 500);
while p.left().len() > 0 {
p.move_to_right();
}
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 1000);
while p.right().len() > 0 {
p.move_to_left();
}
assert_eq!(p.left().len(), 1000);
assert_eq!(p.right().len(), 0);
}
#[test]
fn test_debug_contains_expected_elements() {
let mut p = Partition::new();
p.push_left(42);
p.push_left(24);
p.push_right(99);
let debug_string = format!("{:?}", p);
assert!(debug_string.contains("Partition"));
assert!(debug_string.contains("left"));
assert!(debug_string.contains("right"));
assert!(debug_string.contains("42"));
assert!(debug_string.contains("24"));
assert!(debug_string.contains("99"));
}
#[test]
fn test_with_capacity_reservations() {
let capacity = 100;
let p: Partition<i32> = Partition::with_capacity(capacity);
assert!(p.0.inner.capacity() >= capacity);
}
#[test]
fn test_to_raw_parts_empty() {
let p = Partition::<i32>::new();
let (vec, partition) = p.to_raw_parts();
assert!(vec.is_empty());
assert_eq!(partition, 0);
let p2 = Partition::from_raw_parts(vec, partition);
assert!(p2.is_empty());
assert_eq!(p2.left().len(), 0);
assert_eq!(p2.right().len(), 0);
}
#[test]
fn test_left_mut_right_mut_empty() {
let mut p = Partition::<i32>::new();
assert!(p.left_mut().is_empty());
assert!(p.right_mut().is_empty());
}
#[test]
fn test_partitions_mut_empty() {
let mut p = Partition::<i32>::new();
let (left, right) = p.partitions_mut();
assert!(left.is_empty());
assert!(right.is_empty());
let mut p = Partition::new();
p.push_right(1);
let (left, right) = p.partitions_mut();
assert!(left.is_empty());
assert!(!right.is_empty());
let mut p = Partition::new();
p.push_left(1);
let (left, right) = p.partitions_mut();
assert!(!left.is_empty());
assert!(right.is_empty());
}
#[test]
fn test_iterator_behavior_after_emptying() {
let mut p = Partition::new();
p.push_left(1);
let mut iter = p.drain_to_right();
assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
let mut p = Partition::new();
p.push_left(1);
let mut iter = p.drain_left();
assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
let mut p = Partition::new();
p.push_right(1);
let mut iter = p.drain_right();
assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); }
#[test]
fn test_zero_sized_types() {
let mut p = Partition::<()>::new();
p.push_left(());
p.push_left(());
p.push_right(());
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 1);
let moved = p.move_to_right();
assert_eq!(moved, Some(()));
assert_eq!(p.left().len(), 1);
assert_eq!(p.right().len(), 2);
assert_eq!(p.pop_left(), Some(()));
assert_eq!(p.pop_right(), Some(()));
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 1);
}
#[test]
fn test_complex_method_interactions() {
let mut p = Partition::new();
p.push_left(1);
p.push_right(2);
p.push_left(3);
p.push_right(4);
let moved = p.move_to_right();
assert!(moved.is_some());
let popped = p.pop_right();
assert!(popped.is_some());
p.push_left(5);
let drained: Vec<_> = p.drain_to_left().collect();
assert!(!drained.is_empty());
assert!(p.right().is_empty());
assert!(!p.left().is_empty());
p.clear();
assert!(p.is_empty());
p.push_left(1);
p.push_right(2);
p.pop_left(); p.push_left(3);
p.move_to_right(); p.move_to_left();
assert_eq!(p.left().len(), 1);
assert_eq!(p.right().len(), 1);
}
#[test]
fn test_unchecked_from_raw_parts_preserves_invariants() {
let vec = vec![1, 2, 3, 4];
let partition = 2;
let p = unsafe { Partition::from_raw_parts_unchecked(vec.clone(), partition) };
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
let left_items: Vec<_> = p.left().to_vec();
let right_items: Vec<_> = p.right().to_vec();
check_set_equality(left_items, [1, 2]);
check_set_equality(right_items, [3, 4]);
let empty_vec = Vec::<i32>::new();
let p = unsafe { Partition::from_raw_parts_unchecked(empty_vec, 0) };
assert!(p.left().is_empty());
assert!(p.right().is_empty());
}
#[test]
fn test_spare_capacity_mut() {
let mut p: Partition<usize> = Partition::with_capacity(10);
p.push_left(1);
p.push_left(2);
p.push_right(3);
let len_before = p.len();
let cap_before = p.capacity();
let spare_len = cap_before - len_before;
{
let spare = p.spare_capacity_mut();
assert_eq!(spare.len(), spare_len);
assert!(spare.len() >= 7);
spare[0].write(10);
spare[1].write(20);
spare[2].write(30);
}
unsafe {
p.set_len(len_before + 3);
}
assert_eq!(p.left().len(), 2);
check_set_equality(p.left().iter().copied(), [1, 2]);
assert_eq!(p.right().len(), 4);
let mut right_elements = p.right().to_vec();
right_elements.sort(); assert_eq!(right_elements, vec![3, 10, 20, 30]);
let mut empty_p: Partition<usize> = Partition::with_capacity(5);
let capacity = empty_p.capacity();
{
let empty_spare = empty_p.spare_capacity_mut();
assert_eq!(empty_spare.len(), capacity);
empty_spare[0].write(100);
}
unsafe {
empty_p.set_len(1);
}
assert_eq!(empty_p.left().len(), 0);
assert_eq!(empty_p.right().len(), 1);
assert_eq!(empty_p.right()[0], 100);
}
#[test]
fn test_set_len() {
let mut p: Partition<usize> = Partition::with_capacity(10);
assert!(p.capacity() >= 3);
let ptr = p.inner.as_mut_ptr();
unsafe {
ptr.write(10);
ptr.add(1).write(20);
ptr.add(2).write(30);
p.set_len(3);
}
assert_eq!(p.len(), 3);
assert_eq!(p.left().len(), 0);
assert_eq!(p.right().len(), 3);
check_set_equality(p.right().iter().copied(), [10, 20, 30]);
let mut p2: Partition<usize> = Partition::with_capacity(10);
p2.push_left(1);
p2.push_left(2);
p2.push_right(3);
let len_before = p2.len();
assert!(p2.capacity() >= len_before + 2);
let ptr = unsafe { p2.inner.as_mut_ptr().add(len_before) };
unsafe {
ptr.write(40);
ptr.add(1).write(50);
p2.set_len(len_before + 2);
}
assert_eq!(p2.len(), len_before + 2);
assert_eq!(p2.left().len(), 2);
assert_eq!(p2.right().len(), 3);
let right_elements: Vec<_> = p2.right().to_vec();
assert_eq!(right_elements.len(), 3);
assert!(right_elements.contains(&3));
assert!(right_elements.contains(&40));
assert!(right_elements.contains(&50));
}
#[test]
fn test_reserve_and_reserve_exact() {
let mut p1: Partition<usize> = Partition::new();
assert_eq!(p1.capacity(), 0);
p1.reserve(10);
assert!(p1.capacity() >= 10);
let cap_before = p1.capacity();
p1.reserve(20);
assert!(p1.capacity() >= cap_before);
let mut p2: Partition<usize> = Partition::new();
p2.reserve_exact(10);
assert!(p2.capacity() >= 10);
for i in 0..5 {
p2.push_left(i);
}
p2.reserve_exact(10);
assert!(p2.capacity() >= p2.len() + 10);
let mut p3: Partition<usize> = Partition::new();
p3.push_left(1);
p3.push_left(2);
p3.push_right(3);
p3.push_right(4);
let len_before = p3.len();
let cap_before = p3.capacity();
p3.reserve(20);
assert!(p3.capacity() >= cap_before + 20);
assert_eq!(p3.len(), len_before);
assert_eq!(p3.left().len(), 2);
assert_eq!(p3.right().len(), 2);
check_set_equality(p3.left().iter().copied(), [1, 2]);
check_set_equality(p3.right().iter().copied(), [3, 4]);
}
#[test]
fn test_spare_capacity_mut_with_set_len_interaction() {
let mut p: Partition<usize> = Partition::with_capacity(20);
p.push_left(1);
p.push_left(2);
p.push_right(3);
p.push_right(4);
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 2);
assert_eq!(p.len(), 4);
let current_len = p.len();
{
let spare = p.spare_capacity_mut();
for i in 0..5 {
spare[i].write(100 + i);
}
}
unsafe {
p.set_len(current_len + 5);
}
assert_eq!(p.len(), 9);
assert_eq!(p.left().len(), 2);
assert_eq!(p.right().len(), 7);
assert!(p.left().contains(&1));
assert!(p.left().contains(&2));
for i in 0..5 {
assert!(p.right().contains(&(100 + i)));
}
let partition_idx_before = p.partition;
let current_len = p.len();
unsafe {
p.set_len(current_len + 1);
}
assert_eq!(
p.partition, partition_idx_before,
"Partition index shouldn't change with set_len"
);
}
#[test]
#[should_panic]
fn test_set_len_debug_assertion() {
let mut p: Partition<usize> = Partition::with_capacity(5);
unsafe {
p.set_len(10);
}
}