#![no_std]
extern crate alloc;
use alloc::vec::Vec;
impl<'a, T> core::ops::Deref for FirstVec<'a, T> {
type Target = [T];
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<'a, T> core::ops::DerefMut for FirstVec<'a, T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_slice_mut()
}
}
pub struct FirstVec<'a, T> {
foo: &'a mut TwoUnorderedVecs<T>,
}
impl<'a, T> RetainMutUnordered<T> for FirstVec<'a, T> {
#[inline(always)]
fn truncate(&mut self, num: usize) {
FirstVec::truncate(self, num);
}
#[inline(always)]
fn as_slice_mut(&mut self) -> &mut [T] {
FirstVec::as_slice_mut(self)
}
}
impl<'a, T> FirstVec<'a, T> {
#[inline(always)]
pub fn as_slice(&self) -> &[T] {
&self.foo.inner[..self.foo.first_length]
}
#[inline(always)]
pub fn as_slice_mut(&mut self) -> &mut [T] {
&mut self.foo.inner[..self.foo.first_length]
}
#[inline(always)]
pub fn truncate(&mut self, num: usize) {
let total_len = self.foo.inner.len();
let diff = self.foo.first_length - num;
let target_ptr = &mut self.foo.inner[num] as *mut _;
let source_ptr = unsafe {
self.foo
.inner
.as_mut_ptr()
.offset((total_len - diff.min(total_len - self.foo.first_length)) as isize)
};
unsafe {
core::ptr::drop_in_place(target_ptr);
core::ptr::copy(source_ptr, target_ptr, diff);
}
self.foo.first_length = num;
unsafe {
self.foo.inner.set_len(total_len - diff);
}
}
#[inline(always)]
pub fn push(&mut self, a: T) {
let total_len = self.foo.inner.len();
self.foo.inner.push(a);
self.foo.inner.swap(self.foo.first_length, total_len);
self.foo.first_length += 1;
}
}
pub struct SecondVec<'a, T> {
foo: &'a mut TwoUnorderedVecs<T>,
}
impl<'a, T> RetainMutUnordered<T> for SecondVec<'a, T> {
#[inline(always)]
fn truncate(&mut self, num: usize) {
SecondVec::truncate(self, num);
}
#[inline(always)]
fn as_slice_mut(&mut self) -> &mut [T] {
SecondVec::as_slice_mut(self)
}
}
impl<'a, T> core::ops::Deref for SecondVec<'a, T> {
type Target = [T];
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<'a, T> core::ops::DerefMut for SecondVec<'a, T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_slice_mut()
}
}
impl<'a, T> SecondVec<'a, T> {
#[inline(always)]
pub fn as_slice(&self) -> &[T] {
&self.foo.inner[self.foo.first_length..]
}
#[inline(always)]
pub fn as_slice_mut(&mut self) -> &mut [T] {
&mut self.foo.inner[self.foo.first_length..]
}
#[inline(always)]
pub fn push(&mut self, b: T) {
self.foo.inner.push(b);
}
#[inline(always)]
pub fn truncate(&mut self, num: usize) {
self.foo.inner.truncate(self.foo.first_length + num);
}
}
impl<T> From<TwoUnorderedVecs<T>> for Vec<T>{
#[inline(always)]
fn from(a:TwoUnorderedVecs<T>)->Vec<T>{
a.inner
}
}
#[derive(Debug)]
pub struct TwoUnorderedVecs<T> {
inner: Vec<T>,
first_length: usize,
}
pub struct BorrowedVec<'a,T>{
pub inner:&'a mut Vec<T>
}
impl<'a,T> Drop for BorrowedVec<'a,T>{
fn drop(&mut self){
assert!(self.inner.is_empty());
}
}
impl<T> TwoUnorderedVecs<T> {
#[inline(always)]
pub fn with_capacity(num: usize) -> Self {
TwoUnorderedVecs {
inner: Vec::with_capacity(num),
first_length: 0,
}
}
#[inline(always)]
pub fn new() -> Self {
TwoUnorderedVecs {
inner: Vec::new(),
first_length: 0,
}
}
#[inline(always)]
pub fn first(&mut self) -> FirstVec<T> {
FirstVec { foo: self }
}
#[inline(always)]
pub fn second(&mut self) -> SecondVec<T> {
SecondVec { foo: self }
}
pub fn as_vec_mut(&mut self)->BorrowedVec<T>{
assert!(self.inner.is_empty());
BorrowedVec{
inner:&mut self.inner
}
}
#[inline(always)]
pub fn clear(&mut self) {
self.first_length = 0;
self.inner.clear();
}
#[inline(always)]
pub fn into_vec(self) -> Vec<T> {
self.inner
}
#[inline(always)]
pub fn as_vec(&self) -> &Vec<T> {
&self.inner
}
#[inline(always)]
pub fn as_slice_mut(&mut self) -> (&mut [T], &mut [T]) {
self.inner.split_at_mut(self.first_length)
}
#[inline(always)]
pub fn as_slice(&self) -> (&[T], &[T]) {
self.inner.split_at(self.first_length)
}
}
impl<T> RetainMutUnordered<T> for Vec<T> {
#[inline(always)]
fn truncate(&mut self, val: usize) {
Vec::truncate(self, val);
}
#[inline(always)]
fn as_slice_mut(&mut self) -> &mut [T] {
self
}
}
pub trait RetainMutUnordered<T> {
fn truncate(&mut self, val: usize);
fn as_slice_mut(&mut self) -> &mut [T];
#[inline(always)]
fn retain_mut_unordered<F>(&mut self, mut f: F)
where
F: FnMut(&mut T) -> bool,
{
let len = self.as_slice_mut().len();
let mut del = 0;
{
let v = self.as_slice_mut();
let mut cursor = 0;
for _ in 0..len {
if !f(&mut v[cursor]) {
v.swap(cursor, len - 1 - del);
del += 1;
} else {
cursor += 1;
}
}
}
if del > 0 {
self.truncate(len - del);
}
}
}
#[cfg(test)]
mod test {
#[test]
fn test_foo(){
let mut k = TwoUnorderedVecs::new();
{
let v=k.as_vec_mut();
v.inner.push(0);
v.inner.clear();
}
}
use super::*;
#[test]
fn test_truncate() {
let mut k = TwoUnorderedVecs::new();
k.first().push(0);
k.first().push(1);
k.first().push(2);
k.second().push(3);
k.second().push(4);
k.second().push(5);
k.second().push(6);
slices_tuple_eq(k.as_slice(), (&[0, 1, 2], &[3, 4, 5, 6]));
k.first().truncate(2);
slices_tuple_eq(k.as_slice(), (&[0, 1], &[6, 3, 4, 5]));
}
#[test]
fn test_truncate2() {
let mut k = TwoUnorderedVecs::new();
k.first().push(0);
k.first().push(1);
k.first().push(2);
k.first().push(3);
k.first().push(4);
k.second().push(5);
k.first().truncate(3);
slices_tuple_eq(k.as_slice(), (&[0, 1, 2], &[5]));
assert_eq!(k.first_length, 3);
assert_eq!(k.inner.len(), 4);
}
#[test]
fn test_other() {
let mut k = TwoUnorderedVecs::new();
k.second().push(5);
k.first().push(6);
k.second().push(5);
k.first().push(6);
k.second().push(5);
k.first().push(6);
k.second().push(5);
k.first().push(6);
k.first().truncate(2);
k.second().truncate(2);
slices_match(&k.first(), &[6, 6]);
slices_match(&k.second(), &[5, 5]);
}
#[test]
fn test_push() {
let mut k = TwoUnorderedVecs::new();
k.first().push(9);
k.second().push(0);
k.first().push(3);
k.first().push(6);
k.second().push(8);
k.first().push(5);
slices_match(&k.first(), &[9, 3, 6, 5]);
slices_match(&k.second(), &[0, 8]);
assert_eq!(k.first_length, 4);
k.first().truncate(2);
k.second().truncate(1);
slices_match(&k.first(), &[3, 9]);
slices_match(&k.second(), &[8]);
assert_eq!(k.first().len(), 2);
assert_eq!(k.second().len(), 1);
assert_eq!(k.first_length, 2);
k.first().push(4);
k.first().push(6);
k.first().push(7);
k.first().push(8);
k.second().push(7);
k.second().push(3);
k.second().push(2);
k.second().push(4);
k.first().retain_mut_unordered(|&mut a| a % 2 == 1);
k.second().retain_mut_unordered(|&mut a| a % 2 == 0);
slices_match(&k.first(), &[9, 3, 7]);
slices_match(&k.second(), &[8, 2, 4]);
}
fn slices_tuple_eq<T: Eq + core::fmt::Debug>(arr: (&[T], &[T]), arr2: (&[T], &[T])) {
assert_eq!(arr, arr2);
}
fn slices_match<T: Eq>(arr1: &[T], arr2: &[T]) {
for a in arr2.iter() {
assert!(arr1.contains(a));
}
for b in arr1.iter() {
assert!(arr2.contains(b));
}
assert_eq!(arr1.len(), arr2.len());
}
}