Skip to content

Commit

Permalink
removed Clone trait and introduced TryClone trait
Browse files Browse the repository at this point in the history
  • Loading branch information
amunra committed Oct 8, 2024
1 parent e525779 commit a286993
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "alloc-checked"
description = "Collections that don't panic on alloc failures"
authors = ["Adam Cimarosti <[email protected]>"]
version = "0.1.0"
version = "0.1.1"
edition = "2021"
repository = "https://github.com/questdb/alloc-checked"
keywords = ["alloc", "collections", "no-std", "safe-allocation", "container"]
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
extern crate alloc;
extern crate core;

pub mod try_clone;
pub mod vec;
10 changes: 10 additions & 0 deletions src/try_clone.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// A variant of the `Clone` trait which can fail.
pub trait TryClone: Sized {
type Error;

fn try_clone(&self) -> Result<Self, Self::Error>;
fn try_clone_from(&mut self, source: &Self) -> Result<(), Self::Error> {
*self = source.try_clone()?;
Ok(())
}
}
30 changes: 26 additions & 4 deletions src/vec.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::try_clone::TryClone;
use alloc::alloc::Allocator;
use alloc::collections::TryReserveError;
use alloc::vec::Vec as InnerVec;
use core::fmt::Debug;
use core::ops::{Deref, DerefMut, Index, IndexMut};
use core::slice::SliceIndex;

#[derive(Clone)]
pub struct Vec<T, A: Allocator> {
inner: InnerVec<T, A>,
}
Expand Down Expand Up @@ -186,6 +186,16 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
}
}

impl<T: Clone, A: Allocator + Clone> TryClone for Vec<T, A> {
type Error = TryReserveError;

fn try_clone(&self) -> Result<Self, Self::Error> {
let mut cloned = Self::with_capacity_in(self.len(), self.allocator().clone())?;
cloned.extend_from_slice(self.inner.as_slice())?;
Ok(cloned)
}
}

impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
type Output = I::Output;

Expand Down Expand Up @@ -316,7 +326,7 @@ mod tests {
return Err(AllocError);
}
let allocated = Global.allocate(layout)?;
let true_new_in_use = self.in_use.fetch_add(layout.size(), Ordering::SeqCst);
let true_new_in_use = self.in_use.fetch_add(allocated.len(), Ordering::SeqCst);
unsafe {
if true_new_in_use > self.watermark {
let ptr = allocated.as_ptr() as *mut u8;
Expand Down Expand Up @@ -788,7 +798,7 @@ mod tests {
let wma = WatermarkAllocator::new(128);
let mut vec1 = Vec::new_in(wma);
vec1.extend(vec![1, 2, 3]).unwrap();
let vec2 = vec1.clone();
let vec2 = vec1.try_clone().unwrap();

assert_eq!(vec1, vec2);
let e0vec1 = get_first_elem_vec(vec1);
Expand All @@ -814,12 +824,24 @@ mod tests {
let wma = WatermarkAllocator::new(128);
let mut vec1 = Vec::new_in(wma);
vec1.extend(vec![1, 2, 3]).unwrap();
let vec2 = vec1.clone();
let vec2 = vec1.try_clone().unwrap();
assert_eq!(vec1, vec2);

let d0vec1 = doubled_first_elem_vec(vec1);
let d0vec2 = doubled_first_elem_slice(vec2);

assert_eq!(d0vec1, 2);
assert_eq!(d0vec2, 2);
}

#[test]
fn test_try_clone() {
let wma = WatermarkAllocator::new(64);
let mut vec1 = Vec::new_in(wma.clone());
vec1.extend([1usize, 2, 3, 4, 5, 6, 7, 8]).unwrap();
assert_eq!(vec1.len(), 8);
assert_eq!(vec1.capacity(), 8);
assert_eq!(wma.in_use(), 64);
assert!(vec1.try_clone().is_err());
}
}

0 comments on commit a286993

Please sign in to comment.