Skip to content

Commit

Permalink
no_std + no_alloc
Browse files Browse the repository at this point in the history
  • Loading branch information
tower120 authored May 10, 2024
1 parent 168276e commit ebf1500
Show file tree
Hide file tree
Showing 26 changed files with 137 additions and 84 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
- uses: actions/checkout@v4
- run: RUSTFLAGS="--deny warnings" cargo build
- run: RUSTFLAGS="--deny warnings" cargo build --all-features
- run: RUSTFLAGS="--deny warnings" cargo build --no-default-features

tests:
name: Run careful tests
Expand Down Expand Up @@ -55,4 +56,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: RUSTDOCFLAGS="--deny warnings" cargo doc --lib
- run: RUSTDOCFLAGS="--deny warnings" cargo doc --lib --all-features

docrs:
name: Build docrs
runs-on: ubuntu-latest
steps:
- uses: dtolnay/rust-toolchain@nightly
- uses: actions/checkout@v4
- run:
RUSTFLAGS="--deny warnings"
RUSTDOCFLAGS="--cfg docsrs"
cargo +nightly doc --lib --all-features
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

## 0.14.0
### Added
- Now library `no_std` friendly.

### Removed
- Helpers `any_value::move_out`, `any_value::move_out_w_size` removed as redundant.

Expand Down
17 changes: 13 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ version = "0.13.0"
edition = "2021"
description = "Type erased vector. Most operations can be done without type knowledge. Mostly zero overhead."
repository = "https://github.com/tower120/any_vec"
keywords = ["vec", "any", "container"]
categories = ["data-structures"]
keywords = ["vec", "any", "container", "no_std"]
categories = ["data-structures", "no-std", "no-std::no-alloc"]
exclude = [".github"]

[features]
default = ["alloc"]
# Include alloc crate. This allows to use mem::Heap.
alloc = []

[package.metadata.docs.rs]
features = []
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]

[dev-dependencies]
itertools = "0.10.3"
criterion = "0.3.5"
itertools = "0.12.1"
criterion = "0.5.1"
rand = "0.8.5"
impls = "1.0.3"

Expand Down
4 changes: 4 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ fn self_push_first_element<T: Trait + Cloneable>(any_vec: &mut AnyVec<T>){

`MemBuilder` interface, being stateful, allow to make `Mem`, which can work with complex custom allocators.

## no_std + no_alloc

This is `no_std` library, which can work without `alloc` too.

### Changelog

See [CHANGELOG.md](CHANGELOG.md) for version differences.
Expand Down
5 changes: 5 additions & 0 deletions doc.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@echo off
setlocal
set RUSTDOCFLAGS=--cfg docsrs
cargo +nightly doc --lib --no-deps %1
endlocal
2 changes: 1 addition & 1 deletion src/any_value/lazy_clone.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::any::TypeId;
use core::any::TypeId;
use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueTypeless, AnyValueSizeless};

/// Makes [`AnyValueCloneable`] actually [`Clone`]able.
Expand Down
10 changes: 5 additions & 5 deletions src/any_value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ pub use lazy_clone::LazyClone;
pub use wrapper::AnyValueWrapper;
pub use raw::{AnyValueRaw, AnyValueSizelessRaw, AnyValueTypelessRaw};

use std::any::TypeId;
use std::{mem, ptr};
use std::mem::{MaybeUninit, size_of};
use core::any::TypeId;
use core::{mem, ptr, slice};
use core::mem::{MaybeUninit, size_of};

/// Marker for unknown type.
pub struct Unknown;
Expand Down Expand Up @@ -98,7 +98,7 @@ pub trait AnyValueTypeless: AnyValueSizeless {
/// Aligned.
#[inline]
fn as_bytes(&self) -> &[u8]{
unsafe{std::slice::from_raw_parts(
unsafe{slice::from_raw_parts(
self.as_bytes_ptr(),
self.size()
)}
Expand Down Expand Up @@ -151,7 +151,7 @@ pub trait AnyValueSizelessMut: AnyValueSizeless {
pub trait AnyValueTypelessMut: AnyValueTypeless + AnyValueSizelessMut {
#[inline(always)]
fn as_bytes_mut(&mut self) -> &mut [u8]{
unsafe{std::slice::from_raw_parts_mut(
unsafe{slice::from_raw_parts_mut(
self.as_bytes_mut_ptr(),
self.size()
)}
Expand Down
4 changes: 2 additions & 2 deletions src/any_value/raw.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::any::TypeId;
use std::ptr::NonNull;
use core::any::TypeId;
use core::ptr::NonNull;
use crate::any_value::{AnyValue, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut};
use crate::any_value::Unknown;

Expand Down
4 changes: 2 additions & 2 deletions src/any_value/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::any::TypeId;
use std::mem::size_of;
use core::any::TypeId;
use core::mem::size_of;
use crate::any_value::{AnyValue, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut};

/// Helper struct to convert concrete type to [`AnyValueMut`].
Expand Down
40 changes: 20 additions & 20 deletions src/any_vec.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::alloc::Layout;
use std::any::TypeId;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ops::{Deref, DerefMut, Range, RangeBounds};
use std::ptr::NonNull;
use std::{ptr, slice};
use std::slice::{from_raw_parts, from_raw_parts_mut};
use core::alloc::Layout;
use core::any::TypeId;
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::ops::{Deref, DerefMut, Range, RangeBounds};
use core::ptr::NonNull;
use core::{fmt, ptr, slice};
use core::slice::{from_raw_parts, from_raw_parts_mut};
use crate::{AnyVecTyped, into_range, mem, ops};
use crate::any_value::{AnyValue, AnyValueSizeless};
use crate::any_vec_raw::{AnyVecRaw, DropFn};
Expand Down Expand Up @@ -49,9 +49,9 @@ pub mod traits{
/// Does not enforce anything. Default.
pub trait None {}

pub use std::marker::Sync;
pub use core::marker::Sync;

pub use std::marker::Send;
pub use core::marker::Send;

/// Enforce type [`Clone`]-ability.
pub trait Cloneable{}
Expand Down Expand Up @@ -95,7 +95,7 @@ impl<T: Clone + Send + Sync> SatisfyTraits<dyn Cloneable + Send + Sync> for T{}
/// You can get it with [`AnyVec::into_raw_parts`], or build/edit
/// it manually. And with [`AnyVec::from_raw_parts`], you can construct
/// [`AnyVec`].
pub struct RawParts<M: MemBuilder = mem::Default>
pub struct RawParts<M: MemBuilder/* = mem::Default*/>
where
M::Mem: MemRawParts
{
Expand Down Expand Up @@ -622,7 +622,7 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> AnyVec<Traits, M>
/// If the returned [`TempValue`] goes out of scope without being dropped (due to
/// [`mem::forget`], for example), the vector will lost and leak last element.
///
/// [`mem::forget`]: std::mem::forget
/// [`mem::forget`]: core::mem::forget
///
#[inline]
pub fn pop(&mut self) -> Option<Pop<Traits, M>> {
Expand All @@ -645,7 +645,7 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> AnyVec<Traits, M>
/// [`mem::forget`], for example), the vector may have lost and leaked
/// elements with indices >= index.
///
/// [`mem::forget`]: std::mem::forget
/// [`mem::forget`]: core::mem::forget
///
#[inline]
pub fn remove(&mut self, index: usize) -> Remove<Traits, M> {
Expand All @@ -666,7 +666,7 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> AnyVec<Traits, M>
/// [`mem::forget`], for example), the vector may have lost and leaked
/// elements with indices >= index.
///
/// [`mem::forget`]: std::mem::forget
/// [`mem::forget`]: core::mem::forget
///
#[inline]
pub fn swap_remove(&mut self, index: usize) -> SwapRemove<Traits, M> {
Expand Down Expand Up @@ -694,7 +694,7 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> AnyVec<Traits, M>
/// [`mem::forget`], for example), the vector may have lost and leaked
/// elements with indices in and past the range.
///
/// [`mem::forget`]: std::mem::forget
/// [`mem::forget`]: core::mem::forget
///
#[inline]
pub fn drain(&mut self, range: impl RangeBounds<usize>) -> Drain<Traits, M> {
Expand Down Expand Up @@ -725,7 +725,7 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> AnyVec<Traits, M>
/// [`mem::forget`], for example), the vector may have lost and leaked
/// elements with indices in and past the range.
///
/// [`mem::forget`]: std::mem::forget
/// [`mem::forget`]: core::mem::forget
///
#[inline]
pub fn splice<I: IntoIterator>(&mut self, range: impl RangeBounds<usize>, replace_with: I)
Expand Down Expand Up @@ -814,7 +814,7 @@ impl<Traits: ?Sized + Cloneable + Trait, M: MemBuilder> Clone for AnyVec<Traits,
}

impl<Traits: ?Sized + Trait, M: MemBuilder> Debug for AnyVec<Traits, M>{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("AnyVec")
.field("typeid", &self.element_typeid())
.field("len", &self.len())
Expand Down Expand Up @@ -873,7 +873,7 @@ impl<'a, T: 'static, M: MemBuilder + 'a> IntoIterator for AnyVecRef<'a, T, M>{
}
}
impl<'a, T: 'static + Debug, M: MemBuilder + 'a> Debug for AnyVecRef<'a, T, M>{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
Expand Down Expand Up @@ -909,7 +909,7 @@ impl<'a, T: 'static, M: MemBuilder + 'a> IntoIterator for AnyVecMut<'a, T, M>{
}
}
impl<'a, T: 'static + Debug, M: MemBuilder + 'a> Debug for AnyVecMut<'a, T, M>{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
12 changes: 6 additions & 6 deletions src/any_vec_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Type dispatched analog of `enum{*AnyVecRaw, *AnyVec<Traits>}`.
use std::marker::PhantomData;
use std::ptr::NonNull;
use core::marker::PhantomData;
use core::ptr::NonNull;
use crate::any_value::Unknown;
use crate::any_vec_raw::AnyVecRaw;
use crate::AnyVec;
Expand Down Expand Up @@ -121,10 +121,10 @@ impl<Traits: ?Sized + Trait, M: MemBuilder> IAnyVecPtr for AnyVecPtr<Traits, M>
///
/// All unsafe, because dereferencing pointer is unsafe.
pub(crate) mod utils{
use std::{mem, ptr};
use std::any::TypeId;
use std::mem::size_of;
use std::ptr::NonNull;
use core::{mem, ptr};
use core::any::TypeId;
use core::mem::size_of;
use core::ptr::NonNull;
use crate::any_value::Unknown;
use crate::any_vec_ptr::IAnyVecRawPtr;
use crate::AnyVecTyped;
Expand Down
8 changes: 4 additions & 4 deletions src/any_vec_raw.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{cmp, mem, ptr};
use std::alloc::Layout;
use std::any::TypeId;
use std::mem::size_of;
use core::{cmp, mem, ptr};
use core::alloc::Layout;
use core::any::TypeId;
use core::mem::size_of;
use crate::any_value::{AnyValue, Unknown, AnyValueSizeless};
use crate::assert_types_equal;
use crate::clone_type::CloneFn;
Expand Down
14 changes: 7 additions & 7 deletions src/any_vec_typed.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::ops::{Range, RangeBounds};
use std::ptr::NonNull;
use std::slice;
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::ops::{Range, RangeBounds};
use core::ptr::NonNull;
use core::{fmt, slice};
use crate::any_value::{AnyValueSizeless, AnyValueWrapper};
use crate::any_vec_raw::AnyVecRaw;
use crate::ops::{Iter, pop, remove, swap_remove, TempValue};
Expand Down Expand Up @@ -284,7 +284,7 @@ impl<'a, T: 'static, M: MemBuilder + 'a> AnyVecTyped<'a, T, M>{
}

impl<'a, T: 'static + Debug, M: MemBuilder> Debug for AnyVecTyped<'a, T, M>{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(*self.as_slice()).fmt(f)
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/element.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::any::TypeId;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use core::any::TypeId;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut};
use crate::any_vec_raw::AnyVecRaw;
use crate::any_vec_ptr::{AnyVecPtr, IAnyVecPtr, IAnyVecRawPtr};
Expand Down
8 changes: 4 additions & 4 deletions src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::iter::{FusedIterator};
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::ptr::NonNull;
use core::iter::{FusedIterator};
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr::NonNull;
use crate::any_vec_ptr::{AnyVecPtr, AnyVecRawPtr, IAnyVecRawPtr};
use crate::any_vec_ptr::utils::element_ptr_at;
use crate::any_vec_raw::AnyVecRaw;
Expand Down
22 changes: 17 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#![no_std]
#![cfg_attr(miri, feature(alloc_layout_extra) )]
#![cfg_attr(docsrs, feature(doc_cfg))]

//! Type erased vector [`AnyVec`]. Allow to store elements of the same type.
//! Have same performance and *operations* as [`std::vec::Vec`].
//! Have same performance and *operations* as `std::vec::Vec`.
//!
//! You can downcast type erased [`AnyVec`] to concrete [`AnyVecTyped`] with `downcast`-family.
//! Or use [`AnyVec`] type erased operations, which works with [`any_value`].
Expand Down Expand Up @@ -115,7 +117,7 @@
//!
//! [`MemBuilder`]: mem::MemBuilder
//! [`Mem`]: mem::Mem
//! [`Allocator`]: std::alloc::Allocator
//! [`Allocator`]: core::alloc::Allocator
//! [`clone_empty_in`]: AnyVec::clone_empty_in
//!
//! # AnyValue
Expand All @@ -135,6 +137,16 @@
//! [AnyValue]: any_value::AnyValue
//! [AnyValueMut]: any_value::AnyValueMut
//! [AnyValueCloneable]: any_value::AnyValueCloneable
//!
//! # No `alloc`
//!
//! This library is `no_std` and can work without `alloc`.
//! For this - disable default `alloc` feature. [mem::Heap] will become unavailable
//! after that, and you'll have to specify [MemBuilder] for [AnyVec]. You can use
//! [mem::Stack], or specify your own [Mem].
//!
//! [MemBuilder]: mem::MemBuilder
//! [Mem]: mem::Mem
mod any_vec;
mod clone_type;
Expand All @@ -143,7 +155,7 @@ mod any_vec_raw;
mod any_vec_typed;
mod iter;

use std::any::TypeId;
use core::any::TypeId;
pub use crate::any_vec::{AnyVec, AnyVecMut, AnyVecRef, RawParts, SatisfyTraits, traits};
pub use any_vec_typed::AnyVecTyped;
pub use iter::{ElementIterator, Iter, IterMut, IterRef};
Expand All @@ -153,8 +165,8 @@ pub mod any_value;
pub mod ops;
pub mod element;

use std::ptr;
use std::ops::{Bound, Range, RangeBounds};
use core::ptr;
use core::ops::{Bound, Range, RangeBounds};
use crate::any_value::Unknown;

/// This is faster then ptr::copy,
Expand Down
Loading

0 comments on commit ebf1500

Please sign in to comment.