From aca910eb8844058defeebe70acdecf618d3c1847 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sat, 24 Nov 2018 22:56:09 +0100 Subject: [PATCH] std feature (by default) and compiling for no-std --- Cargo.toml | 4 ++++ src/bits.rs | 6 +++--- src/lib.rs | 9 +++++++++ src/macros.rs | 30 +++++++++++++++--------------- src/slice.rs | 21 +++++++++++++++------ src/vec.rs | 14 ++++++++++---- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 893a819b..5c11eb9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,7 @@ license-file = "LICENSE.txt" repository = "https://github.com/myrrlyn/bitvec" [dependencies] + +[features] +default = ["std"] +std = [] \ No newline at end of file diff --git a/src/bits.rs b/src/bits.rs index d1a72d2a..5656030f 100644 --- a/src/bits.rs +++ b/src/bits.rs @@ -5,7 +5,7 @@ storage of a primitive, and is the constraint for the storage type of a `BitVec`. !*/ -use std::{ +use core::{ cmp::Eq, convert::From, default::Default, @@ -80,7 +80,7 @@ pub trait Bits: const MASK: u8 = Self::WIDTH - 1; /// The maximum number of this type that can be held in a `BitVec`. - const MAX_ELT: usize = std::usize::MAX >> Self::BITS; + const MAX_ELT: usize = core::usize::MAX >> Self::BITS; /// Set a specific bit in an element to a given value. fn set(&mut self, place: u8, value: bool) { @@ -114,7 +114,7 @@ pub trait Bits: /// Joins a `usize` element cursor and `u8` bit cursor into a single /// `usize` cursor. fn join(elt: usize, bit: u8) -> usize { - assert!(elt <= std::usize::MAX >> Self::BITS, "Element count out of range!"); + assert!(elt <= core::usize::MAX >> Self::BITS, "Element count out of range!"); assert!(bit <= Self::MASK, "Bit count out of range!"); (elt << Self::BITS) | bit as usize } diff --git a/src/lib.rs b/src/lib.rs index 0b06f7d9..6304969c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,9 @@ iteration in both directions, bit shifts, and, of course, access to the underlying storage as a slice. !*/ +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + #[macro_use] mod macros; @@ -41,6 +44,12 @@ mod endian; mod slice; mod vec; +#[cfg(feature = "std")] +extern crate core; + +#[cfg(not(feature = "std"))] +extern crate alloc; + pub use crate::{ bits::Bits, endian::{ diff --git a/src/macros.rs b/src/macros.rs index 05b32ae0..4b0777da 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -89,7 +89,7 @@ macro_rules! bitvec { }}; ( __bv_impl__ $endian:ident , $bits:ty ; $element:expr; $rep:expr ) => {{ - std::iter::repeat( $element as u8 > 0 ) + core::iter::repeat( $element as u8 > 0 ) .take( $rep ) .collect ::< $crate :: BitVec < $endian , $bits > > () }}; @@ -99,20 +99,20 @@ macro_rules! bitvec { macro_rules! __bitslice_shift { ( $( $t:ty ),+ ) => { $( #[doc(hidden)] - impl std::ops::ShlAssign< $t > + impl core::ops::ShlAssign< $t > for crate::BitSlice { fn shl_assign(&mut self, shamt: $t ) { - std::ops::ShlAssign::::shl_assign(self, shamt as usize); + core::ops::ShlAssign::::shl_assign(self, shamt as usize); } } #[doc(hidden)] - impl std::ops::ShrAssign< $t > + impl core::ops::ShrAssign< $t > for crate::BitSlice { fn shr_assign(&mut self, shamt: $t ) { - std::ops::ShrAssign::::shr_assign(self, shamt as usize); + core::ops::ShrAssign::::shr_assign(self, shamt as usize); } } )+ }; @@ -122,42 +122,42 @@ macro_rules! __bitslice_shift { macro_rules! __bitvec_shift { ( $( $t:ty ),+ ) => { $( #[doc(hidden)] - impl std::ops::Shl< $t > + impl core::ops::Shl< $t > for $crate :: BitVec { - type Output = >::Output; + type Output = >::Output; fn shl(self, shamt: $t ) -> Self::Output { - std::ops::Shl::::shl(self, shamt as usize) + core::ops::Shl::::shl(self, shamt as usize) } } #[doc(hidden)] - impl std::ops::ShlAssign< $t > + impl core::ops::ShlAssign< $t > for $crate :: BitVec { fn shl_assign(&mut self, shamt: $t ) { - std::ops::ShlAssign::::shl_assign(self, shamt as usize) + core::ops::ShlAssign::::shl_assign(self, shamt as usize) } } #[doc(hidden)] - impl std::ops::Shr< $t > + impl core::ops::Shr< $t > for $crate :: BitVec { - type Output = >::Output; + type Output = >::Output; fn shr(self, shamt: $t ) -> Self::Output { - std::ops::Shr::::shr(self, shamt as usize) + core::ops::Shr::::shr(self, shamt as usize) } } #[doc(hidden)] - impl std::ops::ShrAssign< $t > + impl core::ops::ShrAssign< $t > for $crate :: BitVec { fn shr_assign(&mut self, shamt: $t ) { - std::ops::ShrAssign::::shr_assign(self, shamt as usize) + core::ops::ShrAssign::::shr_assign(self, shamt as usize) } } )+ }; diff --git a/src/slice.rs b/src/slice.rs index cd05a46d..4bac5124 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -35,8 +35,7 @@ reference or mutable reference, and has the advantage that now it can be a count bits using `.into()`. !*/ -use std::{ - borrow::ToOwned, +use core::{ cmp::{ Eq, Ord, @@ -82,6 +81,12 @@ use std::{ slice, }; +#[cfg(feature = "std")] +use std::borrow::ToOwned; + +#[cfg(not(feature = "std"))] +use alloc::borrow::ToOwned; + /** A compact slice of bits, whose cursor and storage type can be customized. `BitSlice` is a newtype wrapper over `[T]`, and as such can only be held by @@ -556,7 +561,11 @@ where E: crate::Endian, T: crate::Bits { /// Formats a partial element of the data slice. pub(crate) fn fmt_bits(fmt: &mut Formatter, elt: &T, bits: u8) -> fmt::Result { - use std::fmt::Write; + use core::fmt::Write; + + #[cfg(not(feature = "std"))] + use alloc::string::String; + let mut out = String::with_capacity(bits as usize); for bit in 0 .. bits { let cur = E::curr::(bit); @@ -927,7 +936,7 @@ where E: crate::Endian, T: crate::Bits { /// assert_eq!(numr, &nums[2] as &BitSlice); /// ``` fn add_assign(&mut self, addend: &'a BitSlice) { - use std::iter::repeat; + use core::iter::repeat; // zero-extend the addend if it’s shorter than self let mut addend_iter = addend.into_iter().rev().chain(repeat(false)); let mut c = false; @@ -962,7 +971,7 @@ where E: crate::Endian, T: crate::Bits, I: IntoIterator { /// assert_eq!("000100", &format!("{}", lhs)); /// ``` fn bitand_assign(&mut self, rhs: I) { - use std::iter::repeat; + use core::iter::repeat; for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) { let val = self.get(idx) & other; self.set(idx, val); @@ -1011,7 +1020,7 @@ where E: crate::Endian, T: crate::Bits, I: IntoIterator { /// assert_eq!("011001", &format!("{}", lhs)); /// ``` fn bitxor_assign(&mut self, rhs: I) { - use std::iter::repeat; + use core::iter::repeat; for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) { let val = self.get(idx) ^ other; self.set(idx, val); diff --git a/src/vec.rs b/src/vec.rs index f56f93f3..8eee6152 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -7,7 +7,7 @@ The `BitSlice` module discusses the design decisions for the separation between slice and vector types. !*/ -use std::{ +use core::{ borrow::{ Borrow, BorrowMut, @@ -71,6 +71,12 @@ use std::{ ptr, }; +#[cfg(feature = "std")] +use std::borrow::ToOwned; + +#[cfg(not(feature = "std"))] +use alloc::{borrow::ToOwned, boxed::Box, vec::Vec}; + /** A compact `Vec` of bits, whose cursor and storage type can be customized. `BitVec` is a newtype wrapper over `Vec`, and as such is exactly three words in @@ -174,7 +180,7 @@ where E: crate::Endian, T: crate::Bits { /// assert!(bv[0]); /// ``` pub fn push(&mut self, value: bool) { - assert!(self.len() < std::usize::MAX, "Vector will overflow!"); + assert!(self.len() < core::usize::MAX, "Vector will overflow!"); let bit = self.bits(); // Get a cursor to the bit that matches the semantic count. let cursor = E::curr::(bit); @@ -1061,7 +1067,7 @@ where E: crate::Endian, T: crate::Bits { /// assert_eq!(a, bitvec![1, 0, 0, 0, 0]); /// ``` fn add_assign(&mut self, mut addend: Self) { - use std::iter::repeat; + use core::iter::repeat; // If the other vec is longer, swap them and try again. if addend.len() > self.len() { mem::swap(self, &mut addend); @@ -1579,7 +1585,7 @@ where E: crate::Endian, T: crate::Bits { let buf = self.as_mut(); let ptr = buf.as_mut_ptr(); let len = buf.len(); - unsafe { std::ptr::write_bytes(ptr, 0, len); } + unsafe { core::ptr::write_bytes(ptr, 0, len); } return; } for idx in shamt .. len {