Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed Feb 4, 2024
1 parent 6e68291 commit a1f048a
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 38 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- run: rustup update 1.72 --no-self-update && rustup default 1.72
- run: cargo build --all-targets
- run: cargo test --all-targets
- run: rustup update 1.70 --no-self-update && rustup default 1.70
- run: cargo build --workspace --lib --bins --examples --tests
- run: cargo test --workspace --lib --bins --examples --tests
- run: rustup component add rustfmt
- run: cargo fmt --check
- run: cargo build --workspace --lib --bins --examples --tests --no-default-features
- run: cargo test --workspace --lib --bins --examples --tests --no-default-features
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ repository = "https://github.com/antiguru/flatcontainer"
rust-version = "1.70"

[dependencies]
cfg-if = "1.0"
paste = "1.0.14"
serde = { version = "1.0", optional = true, features = ["derive"]}

[dev-dependencies]
serde_json = "1.0"

[features]
default = ["serde"]

[profile.bench]
debug = 2
codegen-units = 1
lto = true

[[bench]]
name = "bench"
harness = false
7 changes: 5 additions & 2 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ fn _bench_clone<T: Containerized + Eq + Clone>(bencher: &mut Bencher, record: T)
}

fn _bench_realloc<T: Containerized + Eq>(bencher: &mut Bencher, record: T)
where for<'a> &'a T: CopyOnto<<T as Containerized>::Region>
where
for<'a> &'a T: CopyOnto<<T as Containerized>::Region>,
{
bencher.iter(|| {
// prepare encoded data for bencher.bytes
Expand All @@ -203,7 +204,9 @@ where for<'a> &'a T: CopyOnto<<T as Containerized>::Region>
}

fn _bench_prealloc<T: Containerized + Eq>(bencher: &mut Bencher, record: T)
where for<'a> &'a T: ReserveItems<<T as Containerized>::Region> + CopyOnto<<T as Containerized>::Region>
where
for<'a> &'a T:
ReserveItems<<T as Containerized>::Region> + CopyOnto<<T as Containerized>::Region>,
{
bencher.iter(|| {
// prepare encoded data for bencher.bytes
Expand Down
10 changes: 7 additions & 3 deletions src/impls/mirror.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use std::marker::PhantomData;

use crate::{Containerized, CopyOnto, Region, ReserveItems};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Containerized, CopyOnto, Index, Region, ReserveItems};

/// A region for types where the read item type is equal to the index type.
#[derive(Debug)]
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MirrorRegion<T>(PhantomData<*const T>);

impl<T> Default for MirrorRegion<T> {
Expand All @@ -12,7 +16,7 @@ impl<T> Default for MirrorRegion<T> {
}
}

impl<T: Copy> Region for MirrorRegion<T> {
impl<T: Index> Region for MirrorRegion<T> {
type ReadItem<'a> = T where T: 'a;
type Index = T;

Expand Down
6 changes: 5 additions & 1 deletion src/impls/result.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Containerized, CopyOnto, Region, ReserveItems};

impl<T: Containerized, E: Containerized> Containerized for Result<T, E> {
type Region = ResultRegion<T::Region, E::Region>;
}

#[derive(Default)]
#[derive(Default, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ResultRegion<T, E> {
oks: T,
errs: E,
Expand Down
11 changes: 8 additions & 3 deletions src/impls/slice.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use crate::{CopyOnto, Region, ReserveItems};
use std::ops::Deref;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{CopyOnto, Region, ReserveItems};

/// A container representing slices of data.
#[derive(Debug)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SliceRegion<C: Region> {
// offsets: Vec<usize>,
slices: Vec<C::Index>,
Expand Down Expand Up @@ -38,7 +43,7 @@ impl<C: Region> Region for SliceRegion<C> {
}
}

impl<C: Region + Default> Default for SliceRegion<C> {
impl<C: Region> Default for SliceRegion<C> {
fn default() -> Self {
Self {
slices: Vec::default(),
Expand Down
6 changes: 5 additions & 1 deletion src/impls/slice_copy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{CopyOnto, Region, ReserveItems};

/// A container for [`Copy`] types.
#[derive(Debug)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CopyRegion<T: Copy> {
slices: Vec<T>,
}
Expand Down
6 changes: 5 additions & 1 deletion src/impls/string.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::impls::slice_copy::CopyRegion;
use crate::{Containerized, CopyOnto, Region, ReserveItems, SliceRegion};

/// A region to store strings and read `&str`.
#[derive(Default, Debug)]
#[derive(Default, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StringRegion {
inner: CopyRegion<u8>,
}
Expand Down
46 changes: 28 additions & 18 deletions src/impls/tuple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/// Implementation for tuples.
use paste::paste;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::{Containerized, CopyOnto, Region, ReserveItems};

Expand All @@ -12,13 +14,17 @@ macro_rules! tuple_flatcontainer {
}

#[allow(non_snake_case)]
#[derive(Default)]
#[derive(Default, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct [<Tuple $($name)* Region >]<$($name),*> {
$([<container $name>]: $name),*
}

#[allow(non_snake_case)]
impl<$($name: Region),*> Region for [<Tuple $($name)* Region>]<$($name),*> {
impl<$($name: Region),*> Region for [<Tuple $($name)* Region>]<$($name),*>
where
$(<$name as Region>::Index: crate::Index),*
{
type ReadItem<'a> = ($($name::ReadItem<'a>,)*) where Self: 'a;

type Index = ($($name::Index,)*);
Expand Down Expand Up @@ -127,19 +133,23 @@ tuple_flatcontainer!(A B C D E F G H I J K L M);
tuple_flatcontainer!(A B C D E F G H I J K L M N);
tuple_flatcontainer!(A B C D E F G H I J K L M N O);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF);
cfg_if::cfg_if! {
if #[cfg(not(feature="serde"))] {
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE);
tuple_flatcontainer!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF);
}
}
58 changes: 52 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

mod impls;

pub use impls::mirror::MirrorRegion;
Expand All @@ -6,6 +9,16 @@ pub use impls::slice::SliceRegion;
pub use impls::slice_copy::CopyRegion;
pub use impls::string::StringRegion;

#[cfg(feature = "serde")]
pub trait Index: Copy + Serialize + for<'a> Deserialize<'a> {}
#[cfg(feature = "serde")]
impl<T: Copy + Serialize + for<'a> Deserialize<'a>> Index for T {}

#[cfg(not(feature = "serde"))]
pub trait Index: Copy {}
#[cfg(not(feature = "serde"))]
impl<T: Copy> Index for T {}

/// A region to store data.
pub trait Region: Default {
/// The type of the data that one gets out of the container.
Expand All @@ -15,7 +28,7 @@ pub trait Region: Default {

/// The type to index into the container. Should be treated
/// as an opaque type, even if known.
type Index: Copy;
type Index: Index;

/// Index into the container. The index must be obtained by
/// pushing data into the container.
Expand Down Expand Up @@ -63,6 +76,14 @@ impl<T: Containerized> Containerized for [T] {
type Region = SliceRegion<T::Region>;
}

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(
bound = "R: Serialize + for<'a> Deserialize<'a>, R::Index: Serialize + for<'a> Deserialize<'a>"
)
)]
pub struct FlatStack<R: Region> {
indices: Vec<R::Index>,
region: R,
Expand Down Expand Up @@ -117,19 +138,40 @@ impl<R: Region> FlatStack<R> {
self.region.clear();
}

pub fn reserve_items<T>(&mut self, items: impl Iterator<Item=T> + Clone)
where T: ReserveItems<R>,
pub fn reserve_items<T>(&mut self, items: impl Iterator<Item = T> + Clone)
where
T: ReserveItems<R>,
{
ReserveItems::reserve_items(&mut self.region, items);
}

pub fn reserve_regions<'a>(&mut self, regions: impl Iterator<Item=&'a R> + Clone)
where R: 'a
pub fn reserve_regions<'a>(&mut self, regions: impl Iterator<Item = &'a R> + Clone)
where
R: 'a,
{
self.region.reserve_regions(regions)
}
}

impl<R: Region> PartialEq<Self> for FlatStack<R>
where
for<'a> R::ReadItem<'a>: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for index in 0..self.len() {
if self.get(index) != other.get(index) {
return false;
}
}
return true;
}
}

impl<R: Region> Eq for FlatStack<R> where for<'a> R::ReadItem<'a>: PartialEq {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -313,12 +355,16 @@ mod tests {

#[test]
fn all_types() {
fn test_copy<T, C: Region>(t: T)
fn test_copy<T, C: Region + Clone>(t: T)
where
T: CopyOnto<C>,
for<'a> <C as Region>::ReadItem<'a>: PartialEq,
{
let mut c = FlatStack::default();
c.copy(t);

let cc = c.clone();
assert_eq!(c, cc);
}

test_copy::<_, StringRegion>(&"a".to_string());
Expand Down

0 comments on commit a1f048a

Please sign in to comment.