Enable no_std

master
gramar 2 years ago
parent 9d162db0cf
commit 5ad0e47252

@ -17,10 +17,12 @@ panic = "unwind"
strip=true strip=true
[features] [features]
default = ["std"]
std = ["serde/std"]
# TODO: maybe add an FFI feature, to allow C projects to use it? idk if that's worth it really... # TODO: maybe add an FFI feature, to allow C projects to use it? idk if that's worth it really...
[dependencies] [dependencies]
serde = {version = "1.0.116", features = ["derive"], optional = true} serde = {version = "1.0.116", features = ["derive", "alloc"], optional = true}
# TODO: optional smallvec feature: instead of heap-allocating the first page, it can be placed on the stack. # TODO: optional smallvec feature: instead of heap-allocating the first page, it can be placed on the stack.

@ -33,7 +33,7 @@ where K: Collapse
/// Replace the held value with another, yielding the old one /// Replace the held value with another, yielding the old one
pub fn insert(&mut self, value: V) -> V pub fn insert(&mut self, value: V) -> V
{ {
std::mem::replace(&mut self.0.as_mut().unwrap().1, value) core::mem::replace(&mut self.0.as_mut().unwrap().1, value)
} }
/// Remove this entry from the `Map`, yielding the removed value /// Remove this entry from the `Map`, yielding the removed value
pub fn remove(self) -> V pub fn remove(self) -> V

@ -2,7 +2,7 @@
use super::*; use super::*;
/// An iterator over `Page`s /// An iterator over `Page`s
pub struct Pages<'a, K, V>(pub(crate) std::slice::Iter<'a, Page<K,V>>); pub struct Pages<'a, K, V>(pub(crate) core::slice::Iter<'a, Page<K,V>>);
impl<'a, K, V> Iterator for Pages<'a,K,V> impl<'a, K, V> Iterator for Pages<'a,K,V>
{ {
@ -18,7 +18,7 @@ impl<'a, K, V> Iterator for Pages<'a,K,V>
} }
/// A mutable iterator over `Page`s /// A mutable iterator over `Page`s
pub struct PagesMut<'a, K, V>(pub(crate) std::slice::IterMut<'a, Page<K,V>>); pub struct PagesMut<'a, K, V>(pub(crate) core::slice::IterMut<'a, Page<K,V>>);
impl<'a, K, V> Iterator for PagesMut<'a,K,V> impl<'a, K, V> Iterator for PagesMut<'a,K,V>
{ {
@ -34,10 +34,10 @@ impl<'a, K, V> Iterator for PagesMut<'a,K,V>
} }
impl<'a, K, V> ExactSizeIterator for PagesMut<'a,K,V>{} impl<'a, K, V> ExactSizeIterator for PagesMut<'a,K,V>{}
impl<'a, K, V> std::iter::FusedIterator for PagesMut<'a,K,V>{} impl<'a, K, V> core::iter::FusedIterator for PagesMut<'a,K,V>{}
/// An iterator over elements in a `Page`. /// An iterator over elements in a `Page`.
pub struct PageElements<'a, K, V>(pub(crate) std::slice::Iter<'a, Option<(K,V)>>); pub struct PageElements<'a, K, V>(pub(crate) core::slice::Iter<'a, Option<(K,V)>>);
impl<'a, K, V> Iterator for PageElements<'a,K,V> impl<'a, K, V> Iterator for PageElements<'a,K,V>
{ {
@ -57,10 +57,10 @@ impl<'a, K, V> Iterator for PageElements<'a,K,V>
(0, self.0.size_hint().1) (0, self.0.size_hint().1)
} }
} }
impl<'a, K, V> std::iter::FusedIterator for PageElements<'a,K,V>{} impl<'a, K, V> core::iter::FusedIterator for PageElements<'a,K,V>{}
/// A mutable iterator over elements in a `Page`. /// A mutable iterator over elements in a `Page`.
pub struct PageElementsMut<'a, K, V>(pub(crate) std::slice::IterMut<'a, Option<(K,V)>>); pub struct PageElementsMut<'a, K, V>(pub(crate) core::slice::IterMut<'a, Option<(K,V)>>);
impl<'a, K, V> Iterator for PageElementsMut<'a,K,V> impl<'a, K, V> Iterator for PageElementsMut<'a,K,V>
{ {
@ -79,7 +79,7 @@ impl<'a, K, V> Iterator for PageElementsMut<'a,K,V>
(0, self.0.size_hint().1) (0, self.0.size_hint().1)
} }
} }
impl<'a, K, V> std::iter::FusedIterator for PageElementsMut<'a,K,V>{} impl<'a, K, V> core::iter::FusedIterator for PageElementsMut<'a,K,V>{}
/// A consuming iterator over elements in a `Page`. /// A consuming iterator over elements in a `Page`.
pub struct IntoPageElements<K,V>(pub(crate) [Option<(K,V)>; MAX], pub(crate) usize); pub struct IntoPageElements<K,V>(pub(crate) [Option<(K,V)>; MAX], pub(crate) usize);
@ -104,7 +104,7 @@ impl<K,V> Iterator for IntoPageElements<K,V>
(0, Some(self.0.len())) (0, Some(self.0.len()))
} }
} }
impl<K, V> std::iter::FusedIterator for IntoPageElements<K,V>{} impl<K, V> core::iter::FusedIterator for IntoPageElements<K,V>{}
/// An iterator over entries in a `Map`. /// An iterator over entries in a `Map`.
pub struct Iter<'a, K, V>(pub(crate) Option<PageElements<'a,K,V>>, pub(crate) Pages<'a, K,V>); pub struct Iter<'a, K, V>(pub(crate) Option<PageElements<'a,K,V>>, pub(crate) Pages<'a, K,V>);
@ -131,7 +131,7 @@ where K: Collapse
(0, self.1.size_hint().1.map(|x| x * MAX)) (0, self.1.size_hint().1.map(|x| x * MAX))
} }
} }
impl<'a, K: Collapse, V> std::iter::FusedIterator for Iter<'a, K,V>{} impl<'a, K: Collapse, V> core::iter::FusedIterator for Iter<'a, K,V>{}
/// A mutable iterator over entries in a `Map`. /// A mutable iterator over entries in a `Map`.
pub struct IterMut<'a, K, V>(pub(crate) Option<PageElementsMut<'a,K,V>>, pub(crate) PagesMut<'a, K,V>); pub struct IterMut<'a, K, V>(pub(crate) Option<PageElementsMut<'a,K,V>>, pub(crate) PagesMut<'a, K,V>);
@ -158,10 +158,10 @@ where K: Collapse
(0, self.1.size_hint().1.map(|x| x * MAX)) (0, self.1.size_hint().1.map(|x| x * MAX))
} }
} }
impl<'a, K: Collapse, V> std::iter::FusedIterator for IterMut<'a, K,V>{} impl<'a, K: Collapse, V> core::iter::FusedIterator for IterMut<'a, K,V>{}
/// A consuming iterator over entries in a `Map`. /// A consuming iterator over entries in a `Map`.
pub struct IntoIter<K, V>(pub(crate) Option<IntoPageElements<K,V>>, pub(crate) std::vec::IntoIter<Page<K,V>>); pub struct IntoIter<K, V>(pub(crate) Option<IntoPageElements<K,V>>, pub(crate) vec::IntoIter<Page<K,V>>);
impl<K, V> Iterator for IntoIter<K,V> impl<K, V> Iterator for IntoIter<K,V>
where K: Collapse where K: Collapse
@ -187,7 +187,7 @@ where K: Collapse
} }
} }
impl<K: Collapse, V> std::iter::FusedIterator for IntoIter<K,V>{} impl<K: Collapse, V> core::iter::FusedIterator for IntoIter<K,V>{}
#[cfg(test)] #[cfg(test)]
mod tests mod tests

@ -26,16 +26,19 @@
//! //!
//! ### When not to use //! ### When not to use
//! Generally don't use this if your key would have a lot of collisions being represents in 8 bits, otherwise it might be a faster alternative to hash-based maps. You should check yourself before sticking with this crate instead of `std`'s vectorised map implementations. //! Generally don't use this if your key would have a lot of collisions being represents in 8 bits, otherwise it might be a faster alternative to hash-based maps. You should check yourself before sticking with this crate instead of `std`'s vectorised map implementations.
#![cfg_attr(not(test), no_std)]
#![cfg_attr(nightly, feature(test))] #![cfg_attr(nightly, feature(test))]
#![cfg_attr(nightly, feature(drain_filter))] #![cfg_attr(nightly, feature(drain_filter))]
#![cfg_attr(nightly, feature(never_type))] #![cfg_attr(nightly, feature(never_type))]
#[cfg(nightly)] extern crate test; #[cfg(nightly)] extern crate test;
extern crate alloc;
const MAX: usize = 256; const MAX: usize = 256;
use std::borrow::Borrow; use alloc::vec;
use alloc::vec::Vec;
use core::borrow::Borrow;
pub mod iter; pub mod iter;
use iter::*; use iter::*;
@ -138,7 +141,7 @@ where K: Collapse
/// This is a count that iterates over all slots, if possible store it in a temporary instead of re-calling it many times. /// This is a count that iterates over all slots, if possible store it in a temporary instead of re-calling it many times.
pub fn len(&self) -> usize pub fn len(&self) -> usize
{ {
self.0.iter().map(Option::as_ref).filter_map(std::convert::identity).count() self.0.iter().map(Option::as_ref).filter_map(core::convert::identity).count()
} }
/// An iterator over all entries currently in this page /// An iterator over all entries currently in this page
@ -166,11 +169,11 @@ where K: Collapse
fn replace(&mut self, k: K, v: V) -> Option<(K,V)> fn replace(&mut self, k: K, v: V) -> Option<(K,V)>
{ {
std::mem::replace(&mut self.0[usize::from(k.collapse())], Some((k,v))) core::mem::replace(&mut self.0[usize::from(k.collapse())], Some((k,v)))
} }
} }
impl<K: Collapse, V> std::iter::FromIterator<(K, V)> for Map<K,V> impl<K: Collapse, V> core::iter::FromIterator<(K, V)> for Map<K,V>
{ {
fn from_iter<I: IntoIterator<Item=(K, V)>>(iter: I) -> Self fn from_iter<I: IntoIterator<Item=(K, V)>>(iter: I) -> Self
{ {
@ -221,8 +224,8 @@ impl<K,V> Map<K,V>
#[allow(dead_code)] // Used in test cases, but compiler still warns about it #[allow(dead_code)] // Used in test cases, but compiler still warns about it
pub(crate) fn internal_size_bytes(&self) -> usize pub(crate) fn internal_size_bytes(&self) -> usize
{ {
self.0.capacity() * std::mem::size_of::<Page<K,V>>() self.0.capacity() * core::mem::size_of::<Page<K,V>>()
//self.0.iter().map(std::mem::size_of_val).sum::<usize>() //self.0.iter().map(core::mem::size_of_val).sum::<usize>()
} }
} }
@ -432,7 +435,7 @@ where K: Collapse
{ {
match page.search_mut(&key) { match page.search_mut(&key) {
Some((ref ok, ov)) if ok.eq(&key) => { Some((ref ok, ov)) if ok.eq(&key) => {
return Some(std::mem::replace(ov, value)); return Some(core::mem::replace(ov, value));
}, },
empty @ None => { empty @ None => {
return empty.replace((key, value)) return empty.replace((key, value))
@ -484,7 +487,7 @@ impl<K: Collapse, V> IntoIterator for Map<K,V>
} }
} }
impl<K: Collapse, V> std::iter::Extend<(K,V)> for Map<K,V> impl<K: Collapse, V> core::iter::Extend<(K,V)> for Map<K,V>
{ {
fn extend<T: IntoIterator<Item = (K,V)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K,V)>>(&mut self, iter: T) {
// we can probably optimise this better, right? // we can probably optimise this better, right?
@ -495,8 +498,8 @@ impl<K: Collapse, V> std::iter::Extend<(K,V)> for Map<K,V>
} }
} }
use std::hash::{Hash, Hasher,}; use core::hash::{Hash, Hasher,};
use std::ops::{Index, IndexMut}; use core::ops::{Index, IndexMut};
impl<T: ?Sized + Hash + Eq> Collapse for T impl<T: ?Sized + Hash + Eq> Collapse for T
{ {

@ -1,6 +1,6 @@
//! Because we can't #derive big arrays on stable smh //! Because we can't #derive big arrays on stable smh
use super::*; use super::*;
use std::{ use core::{
fmt::{self, Debug,}, fmt::{self, Debug,},
hash, hash,
}; };

@ -6,7 +6,7 @@
//! //!
//! If/when Rust gets specialisation, this will be unneeded. //! If/when Rust gets specialisation, this will be unneeded.
use super::*; use super::*;
use std::num::*; use core::num::*;
/// Sealed trait allowing for wrapping primitive types with a more efficient implemntation for the `Collapse` trait. /// Sealed trait allowing for wrapping primitive types with a more efficient implemntation for the `Collapse` trait.
/// This should not be used for much directly, instead use the newtype shim `Primitive<T>`. /// This should not be used for much directly, instead use the newtype shim `Primitive<T>`.

@ -12,12 +12,12 @@ use super::*;
/// A set of only non-zero bytes. /// A set of only non-zero bytes.
/// ///
/// This type is entirely space efficient and will only ever allocate `256` bytes of memory. /// This type is entirely space efficient and will only ever allocate `256` bytes of memory.
pub type NonZeroByteSet = Set<std::num::NonZeroU8>; pub type NonZeroByteSet = Set<core::num::NonZeroU8>;
/// A set of non-zero signed 8-bit integers. /// A set of non-zero signed 8-bit integers.
/// ///
/// This type is entirely space efficient and will only ever allocate `256` bytes of memory. /// This type is entirely space efficient and will only ever allocate `256` bytes of memory.
pub type NonZeroI8Set = Set<std::num::NonZeroI8>; pub type NonZeroI8Set = Set<core::num::NonZeroI8>;
/// A set of non-zero unsigned 8-bit integers. /// A set of non-zero unsigned 8-bit integers.
/// ///

Loading…
Cancel
Save