use super::RT_RANGE;
use super::VirtualSystem;
use crate::signal::Number;
use crate::system::{Result, Signals as _, Sigset as SigsetTrait};
use std::collections::BTreeSet;
use std::num::NonZero;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[repr(transparent)]
pub struct Sigset(BTreeSet<Number>);
impl SigsetTrait for Sigset {
fn full() -> Self {
let named = VirtualSystem::NAMED_SIGNALS.iter().filter_map(|(_, n)| *n);
let realtime = RT_RANGE.map(|num| Number::from_raw_unchecked(NonZero::new(num).unwrap()));
Self(BTreeSet::from_iter(named.chain(realtime)))
}
fn insert(&mut self, signal: Number) -> Result<()> {
self.0.insert(signal);
Ok(())
}
fn remove(&mut self, signal: Number) -> Result<()> {
self.0.remove(&signal);
Ok(())
}
fn contains(&self, signal: Number) -> Result<bool> {
Ok(self.0.contains(&signal))
}
fn from_signals<I>(iter: I) -> Result<Self>
where
I: IntoIterator<Item = Number>,
{
Ok(Self(BTreeSet::from_iter(iter)))
}
}
impl From<Number> for Sigset {
fn from(signal: Number) -> Self {
let mut set = Sigset::default();
set.0.insert(signal);
set
}
}
impl FromIterator<Number> for Sigset {
fn from_iter<T: IntoIterator<Item = Number>>(iter: T) -> Self {
Self(BTreeSet::from_iter(iter))
}
}
#[derive(Debug)]
pub struct IntoIter(std::collections::btree_set::IntoIter<Number>);
impl Iterator for IntoIter {
type Item = Number;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl IntoIterator for Sigset {
type Item = Number;
type IntoIter = IntoIter;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
IntoIter(self.0.into_iter())
}
}
#[derive(Debug)]
pub struct Iter<'a>(std::collections::btree_set::Iter<'a, Number>);
impl<'a> Iterator for Iter<'a> {
type Item = &'a Number;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<'a> IntoIterator for &'a Sigset {
type Item = &'a Number;
type IntoIter = Iter<'a>;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
Iter(self.0.iter())
}
}
impl Extend<Number> for Sigset {
#[inline(always)]
fn extend<I: IntoIterator<Item = Number>>(&mut self, iter: I) {
self.0.extend(iter);
}
}
impl<'a> Extend<&'a Number> for Sigset {
#[inline(always)]
fn extend<I: IntoIterator<Item = &'a Number>>(&mut self, iter: I) {
self.0.extend(iter);
}
}
impl Sigset {
#[inline(always)]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline(always)]
pub fn iter(&self) -> Iter<'_> {
self.into_iter()
}
pub(super) fn difference_to_vec(&self, other: &Sigset) -> Vec<Number> {
self.0.difference(&other.0).copied().collect()
}
}