diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 529a79aa..cb5f83ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - stable - beta - nightly - - 1.65.0 + - 1.66.0 env: RUSTFLAGS: "-C target-cpu=native -C opt-level=3" ROARINGRS_BENCH_OFFLINE: "true" diff --git a/Cargo.toml b/Cargo.toml index 90fa6a87..726f3d2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,16 +16,19 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -bytemuck = "1.7.3" -byteorder = "1.4.3" -serde = { version = "1.0.139", optional = true } +bytemuck = { version = "1.14.3", optional = true } +byteorder = { version = "1.5.0", optional = true } +serde = { version = "1.0.196", optional = true } [features] +default = ["std"] +serde = ["dep:serde", "std"] simd = [] +std = ["dep:bytemuck", "dep:byteorder"] [dev-dependencies] -proptest = "1.2.0" -serde_json = "1.0.85" +proptest = "1.4.0" +serde_json = "1.0.113" bincode = "1.3.3" [profile.test] diff --git a/src/bitmap/arbitrary.rs b/src/bitmap/arbitrary.rs index f1dda728..de4c4d27 100644 --- a/src/bitmap/arbitrary.rs +++ b/src/bitmap/arbitrary.rs @@ -3,13 +3,15 @@ mod test { use crate::bitmap::container::Container; use crate::bitmap::store::{ArrayStore, BitmapStore, Store}; use crate::RoaringBitmap; + use alloc::boxed::Box; + use alloc::vec::Vec; + use core::fmt::{Debug, Formatter}; use proptest::bits::{BitSetLike, BitSetStrategy, SampledBitSetStrategy}; use proptest::collection::{vec, SizeRange}; use proptest::prelude::*; - use std::fmt::{Debug, Formatter}; impl Debug for BitmapStore { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { if self.len() < 16 { write!(f, "BitmapStore<{:?}>", self.iter().collect::>()) } else { @@ -82,7 +84,7 @@ mod test { } impl Debug for ArrayStore { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { if self.len() < 16 { write!(f, "ArrayStore<{:?}>", self.as_slice()) } else { @@ -151,7 +153,7 @@ mod test { } impl Debug for Store { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { Store::Array(a) => write!(f, "Store({:?})", a), Store::Bitmap(b) => write!(f, "Store({:?})", b), diff --git a/src/bitmap/cmp.rs b/src/bitmap/cmp.rs index ad4a7d0a..366ff090 100644 --- a/src/bitmap/cmp.rs +++ b/src/bitmap/cmp.rs @@ -1,6 +1,6 @@ -use std::borrow::Borrow; -use std::cmp::Ordering; -use std::iter::Peekable; +use core::borrow::Borrow; +use core::cmp::Ordering; +use core::iter::Peekable; use super::container::Container; use crate::RoaringBitmap; diff --git a/src/bitmap/container.rs b/src/bitmap/container.rs index 773f9099..9116863a 100644 --- a/src/bitmap/container.rs +++ b/src/bitmap/container.rs @@ -1,8 +1,10 @@ -use std::fmt; -use std::ops::{ +use core::fmt; +use core::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; +use alloc::vec::Vec; + use super::store::{self, Store}; use super::util; diff --git a/src/bitmap/fmt.rs b/src/bitmap/fmt.rs index 7dca8170..a3a6a95a 100644 --- a/src/bitmap/fmt.rs +++ b/src/bitmap/fmt.rs @@ -1,4 +1,6 @@ -use std::fmt; +use core::fmt; + +use alloc::vec::Vec; use crate::RoaringBitmap; diff --git a/src/bitmap/inherent.rs b/src/bitmap/inherent.rs index 540ef0d3..abb5acbb 100644 --- a/src/bitmap/inherent.rs +++ b/src/bitmap/inherent.rs @@ -1,5 +1,7 @@ -use std::cmp::Ordering; -use std::ops::RangeBounds; +use core::cmp::Ordering; +use core::ops::RangeBounds; + +use alloc::vec::Vec; use crate::RoaringBitmap; diff --git a/src/bitmap/iter.rs b/src/bitmap/iter.rs index 35eddc82..541c49ed 100644 --- a/src/bitmap/iter.rs +++ b/src/bitmap/iter.rs @@ -1,5 +1,6 @@ -use std::iter::{self, FromIterator}; -use std::{slice, vec}; +use alloc::vec::{self, Vec}; +use core::iter::{self, FromIterator}; +use core::slice; use super::container::Container; use crate::{NonSortedIntegers, RoaringBitmap}; @@ -99,7 +100,7 @@ impl RoaringBitmap { /// /// ```rust /// use roaring::RoaringBitmap; - /// use std::iter::FromIterator; + /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); diff --git a/src/bitmap/mod.rs b/src/bitmap/mod.rs index 9b34bdcd..b3bbd080 100644 --- a/src/bitmap/mod.rs +++ b/src/bitmap/mod.rs @@ -14,8 +14,11 @@ mod iter; mod ops; #[cfg(feature = "serde")] mod serde; +#[cfg(feature = "std")] mod serialization; +use alloc::vec::Vec; + use self::cmp::Pairs; pub use self::iter::IntoIter; pub use self::iter::Iter; diff --git a/src/bitmap/multiops.rs b/src/bitmap/multiops.rs index 0fd9040a..fd8f5282 100644 --- a/src/bitmap/multiops.rs +++ b/src/bitmap/multiops.rs @@ -1,11 +1,12 @@ -use std::{ - borrow::Cow, +use core::{ cmp::Reverse, convert::Infallible, mem, ops::{BitOrAssign, BitXorAssign}, }; +use alloc::{borrow::Cow, vec::Vec}; + use crate::{MultiOps, RoaringBitmap}; use super::{container::Container, store::Store}; diff --git a/src/bitmap/ops.rs b/src/bitmap/ops.rs index 09c440db..bfdd0ce3 100644 --- a/src/bitmap/ops.rs +++ b/src/bitmap/ops.rs @@ -1,5 +1,7 @@ -use std::mem; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; +use core::mem; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; + +use alloc::vec::Vec; use crate::bitmap::container::Container; use crate::bitmap::Pairs; @@ -440,8 +442,8 @@ impl BitXorAssign<&RoaringBitmap> for RoaringBitmap { #[cfg(test)] mod test { use crate::{MultiOps, RoaringBitmap}; + use core::convert::Infallible; use proptest::prelude::*; - use std::convert::Infallible; // fast count tests proptest! { diff --git a/src/bitmap/serde.rs b/src/bitmap/serde.rs index f2d1d5ba..26c5d6ab 100644 --- a/src/bitmap/serde.rs +++ b/src/bitmap/serde.rs @@ -16,7 +16,7 @@ impl<'de> Deserialize<'de> for RoaringBitmap { impl<'de> Visitor<'de> for BitmapVisitor { type Value = RoaringBitmap; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("roaring bitmap") } diff --git a/src/bitmap/serialization.rs b/src/bitmap/serialization.rs index 6ae84df4..f60bbad1 100644 --- a/src/bitmap/serialization.rs +++ b/src/bitmap/serialization.rs @@ -1,9 +1,9 @@ use bytemuck::cast_slice_mut; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use std::convert::{Infallible, TryFrom}; +use core::convert::{Infallible, TryFrom}; +use core::ops::RangeInclusive; use std::error::Error; use std::io; -use std::ops::RangeInclusive; use crate::bitmap::container::{Container, ARRAY_LIMIT}; use crate::bitmap::store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}; diff --git a/src/bitmap/store/array_store/mod.rs b/src/bitmap/store/array_store/mod.rs index a121c103..b08bc9b6 100644 --- a/src/bitmap/store/array_store/mod.rs +++ b/src/bitmap/store/array_store/mod.rs @@ -2,12 +2,15 @@ mod scalar; mod vector; mod visitor; +use alloc::boxed::Box; +use alloc::vec::Vec; + use crate::bitmap::store::array_store::visitor::{CardinalityCounter, VecWriter}; -use std::cmp::Ordering; -use std::cmp::Ordering::*; -use std::convert::{TryFrom, TryInto}; -use std::fmt::{Display, Formatter}; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitXor, RangeInclusive, Sub, SubAssign}; +use core::cmp::Ordering; +use core::cmp::Ordering::*; +use core::convert::TryFrom; +use core::fmt::{Display, Formatter}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitXor, RangeInclusive, Sub, SubAssign}; use super::bitmap_store::{bit, key, BitmapStore, BITMAP_LENGTH}; @@ -214,11 +217,11 @@ impl ArrayStore { self.vec.get(n as usize).cloned() } - pub fn iter(&self) -> std::slice::Iter { + pub fn iter(&self) -> core::slice::Iter { self.vec.iter() } - pub fn into_iter(self) -> std::vec::IntoIter { + pub fn into_iter(self) -> alloc::vec::IntoIter { self.vec.into_iter() } @@ -263,7 +266,7 @@ pub enum ErrorKind { } impl Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self.kind { ErrorKind::Duplicate => { write!(f, "Duplicate element found at index: {}", self.index) @@ -275,6 +278,7 @@ impl Display for Error { } } +#[cfg(feature = "std")] impl std::error::Error for Error {} impl TryFrom> for ArrayStore { diff --git a/src/bitmap/store/array_store/scalar.rs b/src/bitmap/store/array_store/scalar.rs index 455afdae..d7b699c4 100644 --- a/src/bitmap/store/array_store/scalar.rs +++ b/src/bitmap/store/array_store/scalar.rs @@ -1,7 +1,7 @@ //! Scalar arithmetic binary set operations on `ArrayStore`'s inner types use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; -use std::cmp::Ordering::*; +use core::cmp::Ordering::*; #[inline] pub fn or(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { diff --git a/src/bitmap/store/array_store/vector.rs b/src/bitmap/store/array_store/vector.rs index 14f3f035..1a4d69ff 100644 --- a/src/bitmap/store/array_store/vector.rs +++ b/src/bitmap/store/array_store/vector.rs @@ -11,9 +11,9 @@ #![cfg(feature = "simd")] use super::scalar; +use core::simd::cmp::{SimdPartialEq, SimdPartialOrd}; use core::simd::{ - mask16x8, simd_swizzle, u16x8, LaneCount, Mask, Simd, SimdElement, SimdPartialEq, - SimdPartialOrd, SupportedLaneCount, ToBitMask, + mask16x8, simd_swizzle, u16x8, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount, }; // a one-pass SSE union algorithm @@ -35,8 +35,8 @@ pub fn or(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { #[inline] fn handle_vector(old: u16x8, new: u16x8, f: impl FnOnce(u16x8, u8)) { - let tmp: u16x8 = Shr1::swizzle2(new, old); - let mask = 255 - tmp.simd_eq(new).to_bitmask(); + let tmp: u16x8 = Shr1::concat_swizzle(new, old); + let mask = 255 - tmp.simd_eq(new).to_bitmask() as u8; f(new, mask); } @@ -119,8 +119,8 @@ pub fn or(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { } pub fn and(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { - let st_a = (lhs.len() / u16x8::LANES) * u16x8::LANES; - let st_b = (rhs.len() / u16x8::LANES) * u16x8::LANES; + let st_a = (lhs.len() / u16x8::LEN) * u16x8::LEN; + let st_b = (rhs.len() / u16x8::LEN) * u16x8::LEN; let mut i: usize = 0; let mut j: usize = 0; @@ -128,20 +128,20 @@ pub fn and(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) let mut v_a: u16x8 = load(&lhs[i..]); let mut v_b: u16x8 = load(&rhs[j..]); loop { - let mask = matrix_cmp_u16(v_a, v_b).to_bitmask(); + let mask = matrix_cmp_u16(v_a, v_b).to_bitmask() as u8; visitor.visit_vector(v_a, mask); - let a_max: u16 = lhs[i + u16x8::LANES - 1]; - let b_max: u16 = rhs[j + u16x8::LANES - 1]; + let a_max: u16 = lhs[i + u16x8::LEN - 1]; + let b_max: u16 = rhs[j + u16x8::LEN - 1]; if a_max <= b_max { - i += u16x8::LANES; + i += u16x8::LEN; if i == st_a { break; } v_a = load(&lhs[i..]); } if b_max <= a_max { - j += u16x8::LANES; + j += u16x8::LEN; if j == st_b { break; } @@ -177,12 +177,12 @@ pub fn xor(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) // written vector was "old" #[inline] fn handle_vector(old: u16x8, new: u16x8, f: impl FnOnce(u16x8, u8)) { - let tmp1: u16x8 = Shr2::swizzle2(new, old); - let tmp2: u16x8 = Shr1::swizzle2(new, old); + let tmp1: u16x8 = Shr2::concat_swizzle(new, old); + let tmp2: u16x8 = Shr1::concat_swizzle(new, old); let eq_l: mask16x8 = tmp2.simd_eq(tmp1); let eq_r: mask16x8 = tmp2.simd_eq(new); let eq_l_or_r: mask16x8 = eq_l | eq_r; - let mask: u8 = eq_l_or_r.to_bitmask(); + let mask: u8 = eq_l_or_r.to_bitmask() as u8; f(tmp2, 255 - mask); } @@ -282,8 +282,8 @@ pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) return; } - let st_a = (lhs.len() / u16x8::LANES) * u16x8::LANES; - let st_b = (rhs.len() / u16x8::LANES) * u16x8::LANES; + let st_a = (lhs.len() / u16x8::LEN) * u16x8::LEN; + let st_b = (rhs.len() / u16x8::LEN) * u16x8::LEN; let mut i = 0; let mut j = 0; @@ -296,18 +296,18 @@ pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) loop { // a_found_in_b will contain a mask indicate for each entry in A // whether it is seen in B - let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask(); + let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask() as u8; runningmask_a_found_in_b |= a_found_in_b; // we always compare the last values of A and B - let a_max: u16 = lhs[i + u16x8::LANES - 1]; - let b_max: u16 = rhs[j + u16x8::LANES - 1]; + let a_max: u16 = lhs[i + u16x8::LEN - 1]; + let b_max: u16 = rhs[j + u16x8::LEN - 1]; if a_max <= b_max { // Ok. In this code path, we are ready to write our v_a // because there is no need to read more from B, they will // all be large values. let bitmask_belongs_to_difference = runningmask_a_found_in_b ^ 0xFF; visitor.visit_vector(v_a, bitmask_belongs_to_difference); - i += u16x8::LANES; + i += u16x8::LEN; if i == st_a { break; } @@ -316,7 +316,7 @@ pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) } if b_max <= a_max { // in this code path, the current v_b has become useless - j += u16x8::LANES; + j += u16x8::LEN; if j == st_b { break; } @@ -334,11 +334,11 @@ pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) let mut buffer: [u16; 8] = [0; 8]; // buffer to do a masked load buffer[..rhs.len() - j].copy_from_slice(&rhs[j..]); v_b = Simd::from_array(buffer); - let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask(); + let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask() as u8; runningmask_a_found_in_b |= a_found_in_b; let bitmask_belongs_to_difference: u8 = runningmask_a_found_in_b ^ 0xFF; visitor.visit_vector(v_a, bitmask_belongs_to_difference); - i += u16x8::LANES; + i += u16x8::LEN; } } @@ -390,7 +390,7 @@ where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { - unsafe { std::ptr::read_unaligned(src as *const _ as *const Simd) } + unsafe { core::ptr::read_unaligned(src as *const _ as *const Simd) } } /// write `v` to slice `out` @@ -416,7 +416,7 @@ where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { - unsafe { std::ptr::write_unaligned(out as *mut _ as *mut Simd, v) } + unsafe { core::ptr::write_unaligned(out as *mut _ as *mut Simd, v) } } /// Compare all lanes in `a` to all lanes in `b` @@ -435,30 +435,30 @@ where // However, we currently only support u16x8 so it's not really necessary fn matrix_cmp_u16(a: Simd, b: Simd) -> Mask { a.simd_eq(b) - | a.simd_eq(b.rotate_lanes_left::<1>()) - | a.simd_eq(b.rotate_lanes_left::<2>()) - | a.simd_eq(b.rotate_lanes_left::<3>()) - | a.simd_eq(b.rotate_lanes_left::<4>()) - | a.simd_eq(b.rotate_lanes_left::<5>()) - | a.simd_eq(b.rotate_lanes_left::<6>()) - | a.simd_eq(b.rotate_lanes_left::<7>()) + | a.simd_eq(b.rotate_elements_left::<1>()) + | a.simd_eq(b.rotate_elements_left::<2>()) + | a.simd_eq(b.rotate_elements_left::<3>()) + | a.simd_eq(b.rotate_elements_left::<4>()) + | a.simd_eq(b.rotate_elements_left::<5>()) + | a.simd_eq(b.rotate_elements_left::<6>()) + | a.simd_eq(b.rotate_elements_left::<7>()) } use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; -use core::simd::{Swizzle2, Which, Which::First as A, Which::Second as B}; +use core::simd::Swizzle; /// Append to vectors to an imaginary 16 lane vector, shift the lanes right by 1, then /// truncate to the low order 8 lanes pub struct Shr1; -impl Swizzle2<8, 8> for Shr1 { - const INDEX: [Which; 8] = [B(7), A(0), A(1), A(2), A(3), A(4), A(5), A(6)]; +impl Swizzle<8> for Shr1 { + const INDEX: [usize; 8] = [15, 0, 1, 2, 3, 4, 5, 6]; } /// Append to vectors to an imaginary 16 lane vector, shift the lanes right by 2, then /// truncate to the low order 8 lanes pub struct Shr2; -impl Swizzle2<8, 8> for Shr2 { - const INDEX: [Which; 8] = [B(6), B(7), A(0), A(1), A(2), A(3), A(4), A(5)]; +impl Swizzle<8> for Shr2 { + const INDEX: [usize; 8] = [14, 15, 0, 1, 2, 3, 4, 5]; } /// Assuming that a and b are sorted, returns an array of the sorted output. @@ -469,15 +469,15 @@ impl Swizzle2<8, 8> for Shr2 { fn simd_merge_u16(a: Simd, b: Simd) -> [Simd; 2] { let mut tmp: Simd = lanes_min_u16(a, b); let mut max: Simd = lanes_max_u16(a, b); - tmp = tmp.rotate_lanes_left::<1>(); + tmp = tmp.rotate_elements_left::<1>(); let mut min: Simd = lanes_min_u16(tmp, max); for _ in 0..6 { max = lanes_max_u16(tmp, max); - tmp = min.rotate_lanes_left::<1>(); + tmp = min.rotate_elements_left::<1>(); min = lanes_min_u16(tmp, max); } max = lanes_max_u16(tmp, max); - min = min.rotate_lanes_left::<1>(); + min = min.rotate_elements_left::<1>(); [min, max] } diff --git a/src/bitmap/store/array_store/visitor.rs b/src/bitmap/store/array_store/visitor.rs index 5ee84b32..56a1a46b 100644 --- a/src/bitmap/store/array_store/visitor.rs +++ b/src/bitmap/store/array_store/visitor.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + #[cfg(feature = "simd")] use crate::bitmap::store::array_store::vector::swizzle_to_front; @@ -47,7 +49,7 @@ impl BinaryOperationVisitor for VecWriter { // first write the entire vector self.vec.extend_from_slice(&result.as_array()[..]); // next truncate the masked out values - self.vec.truncate(self.vec.len() - (result.lanes() - mask.count_ones() as usize)); + self.vec.truncate(self.vec.len() - (result.len() - mask.count_ones() as usize)); } fn visit_scalar(&mut self, value: u16) { diff --git a/src/bitmap/store/bitmap_store.rs b/src/bitmap/store/bitmap_store.rs index e1e332bd..6a8c2b37 100644 --- a/src/bitmap/store/bitmap_store.rs +++ b/src/bitmap/store/bitmap_store.rs @@ -1,7 +1,10 @@ -use std::borrow::Borrow; -use std::cmp::Ordering; -use std::fmt::{Display, Formatter}; -use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, RangeInclusive, SubAssign}; +use core::borrow::Borrow; +use core::cmp::Ordering; +use core::fmt::{Display, Formatter}; +use core::ops::{BitAndAssign, BitOrAssign, BitXorAssign, RangeInclusive, SubAssign}; + +use alloc::boxed::Box; +use alloc::vec::Vec; use super::ArrayStore; @@ -382,7 +385,7 @@ pub enum ErrorKind { } impl Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self.kind { ErrorKind::Cardinality { expected, actual } => { write!(f, "Expected cardinality was {} but was {}", expected, actual) @@ -391,6 +394,7 @@ impl Display for Error { } } +#[cfg(feature = "std")] impl std::error::Error for Error {} pub struct BitmapIter> { diff --git a/src/bitmap/store/mod.rs b/src/bitmap/store/mod.rs index b3ff3e53..c80b2078 100644 --- a/src/bitmap/store/mod.rs +++ b/src/bitmap/store/mod.rs @@ -1,11 +1,12 @@ mod array_store; mod bitmap_store; -use std::mem; -use std::ops::{ +use alloc::{boxed::Box, vec}; +use core::mem; +use core::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; -use std::{slice, vec}; +use core::slice; pub use self::bitmap_store::BITMAP_LENGTH; use self::Store::{Array, Bitmap}; diff --git a/src/bitmap/util.rs b/src/bitmap/util.rs index d6fc7db6..3565c34a 100644 --- a/src/bitmap/util.rs +++ b/src/bitmap/util.rs @@ -1,4 +1,4 @@ -use std::ops::{Bound, RangeBounds, RangeInclusive}; +use core::ops::{Bound, RangeBounds, RangeInclusive}; /// Returns the container key and the index /// in this container for a given integer. @@ -38,7 +38,7 @@ where #[cfg(test)] mod test { use super::{convert_range_to_inclusive, join, split}; - use std::ops::Bound; + use core::ops::Bound; #[test] fn test_split_u32() { diff --git a/src/lib.rs b/src/lib.rs index e87e4fdd..b44c19c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,16 +7,20 @@ //! [roaring-java]: https://github.com/lemire/RoaringBitmap //! [roaring-paper]: https://arxiv.org/pdf/1402.6407v4 +#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "simd", feature(portable_simd))] #![warn(missing_docs)] #![warn(unsafe_op_in_unsafe_fn)] #![warn(variant_size_differences)] #![allow(unknown_lints)] // For clippy +#[cfg(feature = "std")] extern crate byteorder; -use std::error::Error; -use std::fmt; +#[macro_use] +extern crate alloc; + +use core::fmt; /// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). pub mod bitmap; @@ -46,7 +50,8 @@ impl fmt::Display for NonSortedIntegers { } } -impl Error for NonSortedIntegers {} +#[cfg(feature = "std")] +impl std::error::Error for NonSortedIntegers {} /// A [`Iterator::collect`] blanket implementation that provides extra methods for [`RoaringBitmap`] /// and [`RoaringTreemap`]. diff --git a/src/treemap/cmp.rs b/src/treemap/cmp.rs index c55fd228..3334f865 100644 --- a/src/treemap/cmp.rs +++ b/src/treemap/cmp.rs @@ -1,5 +1,5 @@ -use std::collections::btree_map; -use std::iter::Peekable; +use alloc::collections::btree_map; +use core::iter::Peekable; use crate::RoaringBitmap; use crate::RoaringTreemap; diff --git a/src/treemap/fmt.rs b/src/treemap/fmt.rs index 76f6e172..86840116 100644 --- a/src/treemap/fmt.rs +++ b/src/treemap/fmt.rs @@ -1,4 +1,6 @@ -use std::fmt; +use core::fmt; + +use alloc::vec::Vec; use crate::RoaringTreemap; diff --git a/src/treemap/inherent.rs b/src/treemap/inherent.rs index f14fa659..98ef7831 100644 --- a/src/treemap/inherent.rs +++ b/src/treemap/inherent.rs @@ -1,6 +1,7 @@ -use std::collections::btree_map::{BTreeMap, Entry}; -use std::iter; -use std::ops::RangeBounds; +use alloc::collections::btree_map::{BTreeMap, Entry}; +use alloc::vec::Vec; +use core::iter; +use core::ops::RangeBounds; use crate::RoaringBitmap; use crate::RoaringTreemap; diff --git a/src/treemap/iter.rs b/src/treemap/iter.rs index 285a0c5c..a5239bc5 100644 --- a/src/treemap/iter.rs +++ b/src/treemap/iter.rs @@ -1,6 +1,5 @@ -use std::collections::btree_map; -use std::collections::BTreeMap; -use std::iter::{self, FromIterator}; +use alloc::collections::{btree_map, BTreeMap}; +use core::iter::{self, FromIterator}; use super::util; use crate::bitmap::IntoIter as IntoIter32; @@ -160,7 +159,7 @@ impl RoaringTreemap { /// /// ```rust /// use roaring::RoaringTreemap; - /// use std::iter::FromIterator; + /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); @@ -180,7 +179,7 @@ impl RoaringTreemap { /// /// ```rust /// use roaring::{RoaringBitmap, RoaringTreemap}; - /// use std::iter::FromIterator; + /// use core::iter::FromIterator; /// /// let original = (0..6000).collect::(); /// let mut bitmaps = original.bitmaps(); @@ -200,7 +199,7 @@ impl RoaringTreemap { /// /// ```rust /// use roaring::RoaringTreemap; - /// use std::iter::FromIterator; + /// use core::iter::FromIterator; /// /// let original = (0..6000).collect::(); /// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); diff --git a/src/treemap/mod.rs b/src/treemap/mod.rs index 036b961a..45eea164 100644 --- a/src/treemap/mod.rs +++ b/src/treemap/mod.rs @@ -1,5 +1,5 @@ use crate::RoaringBitmap; -use std::collections::BTreeMap; +use alloc::collections::BTreeMap; mod fmt; mod multiops; @@ -14,6 +14,7 @@ mod iter; mod ops; #[cfg(feature = "serde")] mod serde; +#[cfg(feature = "std")] mod serialization; pub use self::iter::{IntoIter, Iter}; diff --git a/src/treemap/multiops.rs b/src/treemap/multiops.rs index 4ad2a8e2..f43bdf71 100644 --- a/src/treemap/multiops.rs +++ b/src/treemap/multiops.rs @@ -1,9 +1,8 @@ -use std::{ - borrow::Borrow, - cmp::Ordering, +use alloc::{ collections::{binary_heap::PeekMut, BTreeMap, BinaryHeap}, - mem, + vec::Vec, }; +use core::{borrow::Borrow, cmp::Ordering, mem}; use crate::{MultiOps, RoaringBitmap, RoaringTreemap}; @@ -15,28 +14,28 @@ where fn union(self) -> Self::Output { try_simple_multi_op_owned::<_, _, UnionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, IntersectionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, DifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } @@ -140,7 +139,7 @@ where // the unwrap is safe since we're iterating on our keys let current_bitmap = treemap.map.remove(&k).unwrap(); let new_bitmap = - O::op_owned(std::iter::once(current_bitmap).chain( + O::op_owned(core::iter::once(current_bitmap).chain( treemaps.iter_mut().map(|treemap| treemap.map.remove(&k).unwrap_or_default()), )); if !new_bitmap.is_empty() { @@ -172,7 +171,7 @@ where // the unwrap is safe since we're iterating on our keys let current_bitmap = treemap.map.get(&k).unwrap(); let new_bitmap = O::op_ref( - std::iter::once(current_bitmap) + core::iter::once(current_bitmap) .chain(treemaps.iter().map(|treemap| treemap.map.get(&k).unwrap_or(&empty_bitmap))), ); if !new_bitmap.is_empty() { @@ -300,28 +299,28 @@ where fn union(self) -> Self::Output { try_simple_multi_op_ref::<_, _, UnionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, IntersectionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, DifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), + self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } diff --git a/src/treemap/ops.rs b/src/treemap/ops.rs index 5961c7cf..17e1b4a8 100644 --- a/src/treemap/ops.rs +++ b/src/treemap/ops.rs @@ -1,6 +1,7 @@ -use std::collections::btree_map::Entry; -use std::mem; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; +use alloc::collections::btree_map::Entry; +use alloc::vec::Vec; +use core::mem; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use crate::RoaringTreemap; diff --git a/src/treemap/serde.rs b/src/treemap/serde.rs index 67665779..46e7c2aa 100644 --- a/src/treemap/serde.rs +++ b/src/treemap/serde.rs @@ -16,7 +16,7 @@ impl<'de> Deserialize<'de> for RoaringTreemap { impl<'de> Visitor<'de> for TreemapVisitor { type Value = RoaringTreemap; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("roaring bitmap") } diff --git a/src/treemap/util.rs b/src/treemap/util.rs index 88c8ccae..55839c64 100644 --- a/src/treemap/util.rs +++ b/src/treemap/util.rs @@ -1,4 +1,4 @@ -use std::ops::{Bound, RangeBounds, RangeInclusive}; +use core::ops::{Bound, RangeBounds, RangeInclusive}; #[inline] pub fn split(value: u64) -> (u32, u32) { diff --git a/tests/iter.rs b/tests/iter.rs index 14746ea9..bbffedc9 100644 --- a/tests/iter.rs +++ b/tests/iter.rs @@ -1,7 +1,7 @@ +use core::iter::FromIterator; use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; -use std::iter::FromIterator; use roaring::RoaringBitmap; diff --git a/tests/push.rs b/tests/push.rs index e617c493..0919d39a 100644 --- a/tests/push.rs +++ b/tests/push.rs @@ -1,6 +1,6 @@ extern crate roaring; +use core::iter::FromIterator; use roaring::{RoaringBitmap, RoaringTreemap}; -use std::iter::FromIterator; /// macro created to reduce code duplication macro_rules! test_from_sorted_iter { diff --git a/tests/serialization.rs b/tests/serialization.rs index 42efdd43..78325017 100644 --- a/tests/serialization.rs +++ b/tests/serialization.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "std")] + extern crate roaring; use roaring::RoaringBitmap; diff --git a/tests/treemap_iter.rs b/tests/treemap_iter.rs index ddde2efc..bdb53636 100644 --- a/tests/treemap_iter.rs +++ b/tests/treemap_iter.rs @@ -2,11 +2,11 @@ extern crate roaring; mod iter; use roaring::RoaringTreemap; +use core::iter::FromIterator; use iter::outside_in; use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; -use std::iter::FromIterator; #[test] fn range() { diff --git a/tests/treemap_rank.rs b/tests/treemap_rank.rs index c05b4e6e..e9c74219 100644 --- a/tests/treemap_rank.rs +++ b/tests/treemap_rank.rs @@ -1,9 +1,9 @@ extern crate roaring; +use core::ops::RangeInclusive; use proptest::collection::{btree_set, vec}; use proptest::prelude::*; use roaring::RoaringTreemap; -use std::ops::RangeInclusive; const BITMAP_MAX: u64 = u32::MAX as u64; diff --git a/tests/treemap_serialization.rs b/tests/treemap_serialization.rs index bf38bb3d..4c8f6be9 100644 --- a/tests/treemap_serialization.rs +++ b/tests/treemap_serialization.rs @@ -1,5 +1,7 @@ +#![cfg(feature = "std")] + +use core::iter::FromIterator; use roaring::RoaringTreemap; -use std::iter::FromIterator; fn serialize_deserialize(dataset: Dataset) where