#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
#![cfg_attr(
all(feature = "aarch64_prefetch", target_arch = "aarch64"),
feature(stdarch_aarch64_prefetch)
)]
#![cfg_attr(feature = "iter_advance_by", feature(iter_advance_by))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(unconditional_recursion)]
#![allow(clippy::duplicated_attributes)]
#![allow(clippy::len_without_is_empty)]
#![allow(clippy::type_complexity)]
#![allow(clippy::too_many_arguments)]
pub mod array;
pub mod bal_paren;
pub mod bits;
pub mod dict;
pub mod func;
pub mod list;
pub mod rank_sel;
pub mod traits;
pub mod utils;
#[cfg(feature = "cli")]
pub mod cli;
#[cfg(feature = "fuzz")]
pub mod fuzz;
pub mod prelude {
pub use crate::array::*;
pub use crate::bal_paren::*;
pub use crate::bit_field_vec;
pub use crate::bit_vec;
pub use crate::bits::*;
pub use crate::dict::*;
pub use crate::func::*;
pub use crate::list::*;
pub use crate::rank_sel::*;
pub use crate::rank_small;
pub use crate::traits::bit_field_slice;
pub use crate::traits::bit_vec_ops;
pub use crate::traits::indexed_dict;
pub use crate::traits::{bit_vec_ops::BitLength, iter::*, rank_sel::*};
}
#[ambassador::delegatable_trait_remote]
pub(crate) trait Index<Idx> {
type Output;
fn index(&self, index: Idx) -> &Self::Output;
}
pub const RAYON_MIN_LEN: usize = 100_000;
macro_rules! panic_if_out_of_bounds {
($index: expr, $len: expr) => {
if $index >= $len {
panic!("Index out of bounds: {} >= {}", $index, $len)
}
};
}
pub(crate) use panic_if_out_of_bounds;
macro_rules! panic_if_value {
($value: expr, $mask: expr, $bit_width: expr) => {
if $value & $mask != $value {
panic!("Value {} does not fit in {} bits", $value, $bit_width);
}
};
}
pub(crate) use panic_if_value;
macro_rules! debug_assert_bounds {
($index: expr, $len: expr) => {
debug_assert!(
$index < $len || ($index == 0 && $len == 0),
"Index out of bounds: {} >= {}",
$index,
$len
);
};
}
pub(crate) use debug_assert_bounds;
pub fn init_env_logger() -> anyhow::Result<()> {
use jiff::{
SpanRound,
fmt::friendly::{Designator, Spacing, SpanPrinter},
};
use std::io::Write;
let mut builder =
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"));
let start = std::time::Instant::now();
let printer = SpanPrinter::new()
.spacing(Spacing::None)
.designator(Designator::Compact);
let span_round = SpanRound::new()
.largest(jiff::Unit::Day)
.smallest(jiff::Unit::Millisecond)
.days_are_24_hours();
builder.format(move |buf, record| {
let Ok(ts) = jiff::Timestamp::try_from(std::time::SystemTime::now()) else {
return Err(std::io::Error::other("Failed to get timestamp"));
};
let style = buf.default_level_style(record.level());
let elapsed = start.elapsed();
let span = jiff::Span::new()
.seconds(elapsed.as_secs() as i64)
.milliseconds(elapsed.subsec_millis() as i64);
let span = span.round(span_round).expect("Failed to round span");
writeln!(
buf,
"{} {} {style}{}{style:#} [{:?}] {} - {}",
ts.strftime("%F %T%.3f"),
printer.span_to_string(&span),
record.level(),
std::thread::current().id(),
record.target(),
record.args()
)
});
builder.init();
Ok(())
}