Skip to content

Commit

Permalink
Feature/into array (#8)
Browse files Browse the repository at this point in the history
* unsafe set_len() implemented

* test_drop_after_set_len() implemented

* test_set_len() implemented

* impl From<LocalVec<T, N>> for [T; N] added

* test for converting into array implemented

* test for Drop behavior after converting into array

* manifest updated
  • Loading branch information
m-rinaldi authored Sep 5, 2021
1 parent f67e7a6 commit 65017ab
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "local_vec"
version = "0.1.1"
version = "0.2.0"
edition = "2018"
authors = ["Jorge Rinaldi <jrg.rinaldi@gmail.com>"]
license = "MIT"
Expand Down
46 changes: 46 additions & 0 deletions src/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,50 @@ mod tests {
assert_eq!(cnt, 0);
}

#[test]
fn test_drop_after_set_len() {
let mut cnt = 0u8;
let mut buf = LocalVec::<_, 3>::new();

assert_eq!(cnt, 0);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 1);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 2);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 3);

unsafe {
buf.set_len(1);
}

std::mem::drop(buf);
assert_eq!(cnt, 2);
}

#[test]
fn test_drop_after_into_array() {
let mut cnt = 0u8;
let mut buf = LocalVec::<_, 3>::new();

assert_eq!(cnt, 0);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 1);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 2);

buf.push(CounterGuard::new(&mut cnt));
assert_eq!(cnt, 3);

let arr: [_; 3] = buf.into();
assert_eq!(cnt, 3);

std::mem::drop(arr);
assert_eq!(cnt, 0);
}
}
33 changes: 33 additions & 0 deletions src/from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use std::convert::From;
use crate::LocalVec;

impl<T, const N: usize> From<LocalVec<T, N>> for [T; N] {
fn from(mut local_vec: LocalVec<T, N>) -> Self {
let arr: [T; N] = unsafe {
local_vec.set_len(0);
std::mem::transmute_copy(&local_vec.buf)
};

arr
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_into_array() {
let mut vec = LocalVec::<_, 4>::new();
vec.push(0);
vec.push(1);
vec.push(2);
vec.push(3);

let arr: [_; 4] = vec.into();
assert_eq!(arr[0], 0);
assert_eq!(arr[1], 1);
assert_eq!(arr[2], 2);
assert_eq!(arr[3], 3);
}
}
18 changes: 18 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::mem::MaybeUninit;

mod drop;
mod index;
mod from;

#[derive(Debug)]
/// A fixed-capacity vector that directly stores its elements
Expand All @@ -22,6 +23,7 @@ impl<T, const N: usize> LocalVec<T, N> {
}
}

// TODO implement From<[T; N]> on top of this?
pub fn from_array<const M: usize>(arr: [T; M]) -> Self {
// TODO check at compile time
assert!(M <= N, "can't store {} elements with a capacity of {}", M, N);
Expand All @@ -47,6 +49,10 @@ impl<T, const N: usize> LocalVec<T, N> {
self.len
}

pub unsafe fn set_len(&mut self, len: usize) {
self.len = len;
}

pub fn capacity(&self) -> usize {
N
}
Expand Down Expand Up @@ -191,4 +197,16 @@ mod tests {

assert_eq!(vec.len(), 4);
}

#[test]
fn test_set_len() {
let arr = [7; 4];
let mut vec = LocalVec::<_, 6>::from_array(arr);

assert_eq!(vec.len(), 4);
unsafe {
vec.set_len(1);
}
assert_eq!(vec.len(), 1);
}
}

0 comments on commit 65017ab

Please sign in to comment.