From 7260ddeac5f257dbfec77ec501b275b09d66d814 Mon Sep 17 00:00:00 2001 From: Markus Mayer Date: Fri, 26 May 2023 23:17:52 +0200 Subject: [PATCH] Add unstable sorting functions --- src/lib.rs | 198 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 171 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9085752..d6b3b6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ //! - You need to share the array across multiple threads *(you may use `Vec>` or `Arc>>` instead)* use std::cell::{Cell, UnsafeCell}; +use std::cmp::Ordering; use std::fmt::{self, Debug, Display}; use std::ops::{Deref, DerefMut}; @@ -102,7 +103,7 @@ impl VecCell { Self { mut_borrow: Cell::new(None), borrows: Cell::new(0), - inner: Vec::with_capacity(capacity) + inner: Vec::with_capacity(capacity), } } @@ -356,7 +357,10 @@ impl VecCell { /// assert_eq!(s[1], 2); /// assert!(s.get(2).is_none()); /// ``` - pub fn borrow_range<'b, R: std::ops::RangeBounds>(&'b self, range: R) -> Option> { + pub fn borrow_range<'b, R: std::ops::RangeBounds>( + &'b self, + range: R, + ) -> Option> { VecRef::from_range(self, range) } @@ -491,9 +495,7 @@ impl VecCell { /// std::mem::drop(x); /// ``` pub fn try_iter<'b>(&'b self) -> impl Iterator>> { - (0..self.len()).map(|index| { - self.borrow(index) - }) + (0..self.len()).map(|index| self.borrow(index)) } /// Resets the [`borrows`](VecCell::borrows) and [`mut_borrow`](VecCell::mut_borrow) counters. @@ -547,11 +549,134 @@ impl VecCell { /// If no reference was [forgotten](std::mem::forget), then `mut_borrow == None` and `borrows == 0`. #[inline] pub fn into_raw_parts(self) -> (Vec>, Option, usize) { - (self.inner, self.mut_borrow.into_inner(), self.borrows.into_inner()) + ( + self.inner, + self.mut_borrow.into_inner(), + self.borrows.into_inner(), + ) } // == Unsafe functions section == + /// Sorts the vector, but might not preserve the order of equal elements. + /// + /// This sort uses the same implementation as `[T]::sort_unstable_by`. + /// + /// ## Example + /// + /// ``` + /// # use veccell::*; + /// let mut vec: VecCell = VecCell::new(); + /// + /// vec.push(30); + /// vec.push(0); + /// vec.push(20); + /// vec.push(10); + /// + /// vec.sort_unstable(); + /// + /// assert_eq!(vec.borrow(0).unwrap(), 0); + /// assert_eq!(vec.borrow(1).unwrap(), 10); + /// assert_eq!(vec.borrow(2).unwrap(), 20); + /// assert_eq!(vec.borrow(3).unwrap(), 30); + /// ``` + pub fn sort_unstable(&mut self) + where + T: Ord, + { + self.sort_unstable_by(|a, b| a.cmp(b)) + } + + /// Sorts the vector with a comparator function, but might not preserve the order of + /// equal elements. + /// + /// This sort uses the same implementation as `[T]::sort_unstable_by`. + /// + /// ## Example + /// + /// ``` + /// # use veccell::*; + /// let mut vec: VecCell = VecCell::new(); + /// + /// vec.push(30); + /// vec.push(0); + /// vec.push(20); + /// vec.push(10); + /// + /// vec.sort_unstable_by(|a, b| b.cmp(a)); + /// + /// assert_eq!(vec.borrow(0).unwrap(), 30); + /// assert_eq!(vec.borrow(1).unwrap(), 20); + /// assert_eq!(vec.borrow(2).unwrap(), 10); + /// assert_eq!(vec.borrow(3).unwrap(), 0); + /// ``` + pub fn sort_unstable_by(&mut self, mut compare: F) + where + T: Ord, + F: FnMut(&T, &T) -> Ordering, + { + assert_eq!( + self.borrows.get(), + 0, + "Sorting requires that no item is currently borrowed" + ); + assert!( + self.mut_borrow.get().is_none(), + "Sorting requires that no item is currently (mutably) borrowed" + ); + self.inner.sort_unstable_by(|a, b| { + // SAFETY: self is borrowed mutably and a and b are not itself changed. + let a = unsafe { &*a.get() }; + let b = unsafe { &*b.get() }; + compare(a, b) + }); + } + + /// Sorts the vector with a key extraction function, but might not preserve the order of + /// equal elements. + /// + /// This sort uses the same implementation as `[T]::sort_unstable_by_key`. + /// + /// ## Example + /// + /// ``` + /// # use veccell::*; + /// let mut vec: VecCell = VecCell::new(); + /// + /// vec.push(30); + /// vec.push(0); + /// vec.push(20); + /// vec.push(10); + /// + /// vec.sort_unstable_by_key(|a| -(*a)); + /// + /// assert_eq!(vec.borrow(0).unwrap(), 30); + /// assert_eq!(vec.borrow(1).unwrap(), 20); + /// assert_eq!(vec.borrow(2).unwrap(), 10); + /// assert_eq!(vec.borrow(3).unwrap(), 0); + /// ``` + pub fn sort_unstable_by_key(&mut self, mut f: F) + where + F: FnMut(&T) -> K, + K: Ord, + { + assert_eq!( + self.borrows.get(), + 0, + "Sorting requires that no item is currently borrowed" + ); + assert!( + self.mut_borrow.get().is_none(), + "Sorting requires that no item is currently (mutably) borrowed" + ); + self.inner.sort_unstable_by(|a, b| { + // SAFETY: self is borrowed mutably and a and b are not itself changed. + let a = f(unsafe { &*a.get() }); + let b = f(unsafe { &*b.get() }); + a.cmp(&b) + }); + } + /// Alternative to `get`, which skips all checks and returns a mutable reference. /// Neither the `mut_borrow`, nor the `borrows` buffer will be updated or read, /// so make sure that no exclusive reference to the element at `index` is made. @@ -571,7 +696,11 @@ impl VecCell { } /// Constructs a `VecCell` from its raw parts. - pub unsafe fn from_raw_parts(inner: Vec>, mut_borrow: Option, borrows: usize) -> Self { + pub unsafe fn from_raw_parts( + inner: Vec>, + mut_borrow: Option, + borrows: usize, + ) -> Self { Self { inner, borrows: Cell::new(borrows), @@ -599,12 +728,16 @@ impl fmt::Debug for VecCell { f.debug_struct("VecCell") .field("borrows", &self.borrows.get()) .field("mut_borrow", &self.mut_borrow.get()) - .field("inner", &self.try_iter().map(|x| { - match x { - Some(y) => BorrowStatus::Ok(y), - None => BorrowStatus::Borrowed, - } - }).collect::>()) + .field( + "inner", + &self + .try_iter() + .map(|x| match x { + Some(y) => BorrowStatus::Ok(y), + None => BorrowStatus::Borrowed, + }) + .collect::>(), + ) .finish() } } @@ -619,7 +752,7 @@ impl<'a, T: 'a> IntoIterator for &'a VecCell { fn into_iter(self) -> Self::IntoIter { VecCellRefIter { vec: self, - index: 0 + index: 0, } } } @@ -629,7 +762,7 @@ impl<'a, T: 'a> IntoIterator for &'a VecCell { #[derive(Clone)] pub struct VecCellRefIter<'a, T> { vec: &'a VecCell, - index: usize + index: usize, } impl<'a, T> Iterator for VecCellRefIter<'a, T> { @@ -637,12 +770,15 @@ impl<'a, T> Iterator for VecCellRefIter<'a, T> { fn next(&mut self) -> Option { if self.index >= self.vec.len() { - return None + return None; } let res = match self.vec.borrow(self.index) { Some(x) => x, - None => panic!("Error while borrowing immutably element {} of VecCell: already mutably borrowed", self.index), + None => panic!( + "Error while borrowing immutably element {} of VecCell: already mutably borrowed", + self.index + ), }; self.index += 1; @@ -681,7 +817,7 @@ impl IntoIterator for VecCell { /// Panics if a value is currently mutably borrowed fn into_iter(self) -> Self::IntoIter { VecCellIntoIter { - iter: self.inner.into_iter() + iter: self.inner.into_iter(), } } } @@ -718,7 +854,10 @@ impl Clone for VecCell { /// Panics if a value is currently mutably borrowed fn clone(&self) -> Self { VecCell { - inner: self.into_iter().map(|x| UnsafeCell::new((*x).clone())).collect::>(), + inner: self + .into_iter() + .map(|x| UnsafeCell::new((*x).clone())) + .collect::>(), mut_borrow: Cell::new(None), borrows: Cell::new(0), } @@ -731,12 +870,12 @@ impl PartialEq for VecCell { /// Panics if a value in `self` or `other` is currently mutably borrowed when it is encountered in the comparison. fn eq(&self, other: &Self) -> bool { if self.len() != other.len() { - return false + return false; } for (s, o) in self.iter().zip(other.iter()) { if *s != *o { - return false + return false; } } @@ -750,12 +889,12 @@ impl PartialEq> for VecCell { /// Panics if a value in `self` is currently mutably borrowed when it is encountered in the comparison. fn eq(&self, other: &Vec) -> bool { if self.len() != other.len() { - return false + return false; } for (s, o) in self.iter().zip(other.iter()) { if *s != *o { - return false + return false; } } @@ -766,7 +905,10 @@ impl PartialEq> for VecCell { impl From> for VecCell { fn from(vec: Vec) -> Self { VecCell { - inner: vec.into_iter().map(|x| UnsafeCell::new(x)).collect::>(), + inner: vec + .into_iter() + .map(|x| UnsafeCell::new(x)) + .collect::>(), mut_borrow: Cell::new(None), borrows: Cell::new(0), } @@ -783,9 +925,11 @@ impl From> for Vec { impl serde::Serialize for VecCell { fn serialize(&self, serializer: S) -> Result where - S: serde::Serializer + S: serde::Serializer, { - let range = self.borrow_range(..).expect("Cannot borrow immutably VecCell: already borrowed mutably."); + let range = self + .borrow_range(..) + .expect("Cannot borrow immutably VecCell: already borrowed mutably."); (*range).serialize(serializer) } } @@ -794,7 +938,7 @@ impl serde::Serialize for VecCell { impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for VecCell { fn deserialize(deserializer: D) -> Result where - D: serde::Deserializer<'de> + D: serde::Deserializer<'de>, { let vec: Vec = Vec::deserialize(deserializer)?; Ok(Self::from(vec))