use {
crate::range::CharRange,
core::{char, cmp},
};
mod iter;
#[cfg(feature = "owned-set")]
mod owned;
#[cfg(feature = "par-iter")]
mod par_iter;
pub use self::iter::RangeIter;
#[cfg(feature = "owned-set")]
pub use self::owned::CharSetBuf;
#[derive(Debug, Eq, PartialEq, PartialOrd, Hash)]
#[repr(transparent)]
pub struct CharSet {
pub(self) ranges: [CharRange],
}
impl Ord for CharSet {
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.partial_cmp(other)
.unwrap_or_else(|| unreachable!("incomparable `CharRange`"))
}
}
impl CharSet {
#[allow(unsafe_code)]
pub fn from_raw(slice: &[CharRange]) -> &CharSet {
unsafe { &*(slice as *const [CharRange] as *const CharSet) }
}
}
impl CharSet {
pub fn empty() -> &'static Self {
Self::from_raw(&[])
}
pub fn contains(&self, c: char) -> bool {
self.search(c).is_ok()
}
pub fn len(&self) -> usize {
self.ranges().map(CharRange::len).sum()
}
pub fn is_empty(&self) -> bool {
self.ranges.is_empty()
}
#[inline]
fn search(&self, c: char) -> Result<usize, usize> {
self.ranges.binary_search_by(|r| r.cmp_char(c))
}
}