pub(crate) mod apply_cache;
pub(crate) mod type_cons;
pub use rustc_hash::FxHasher;
pub use oxidd_core::error::OutOfMemory;
pub use oxidd_core::util::{
num, AllocResult, Borrowed, IsFloatingPoint, OptBool, Rng, SatCountCache, SatCountNumber,
};
#[allow(unused)]
macro_rules! manager_data {
($name:ident$(<$($gen:ident),*>)? for $dd:ident$(<$($dd_gen:ident),*>)?, operator: $op:ty, cache_max_arity: $arity:expr $(, where $($where:tt)*)?) => {
#[derive(::oxidd_derive::ManagerEventSubscriber)]
#[subscribe(manager = <$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Manager<'id>, no_trait_bounds)]
pub struct $name<'id, $($($gen),*)?> $(where $($where)*)? {
apply_cache: $crate::util::apply_cache::ApplyCache<
<$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Manager<'id>,
$op,
$arity,
>,
}
impl<'id, $($($gen),*)?> $name<'id, $($($gen),*)?> $(where $($where)*)? {
unsafe fn new(apply_cache_capacity: usize) -> Self {
Self {
apply_cache: unsafe {
$crate::util::apply_cache::new_apply_cache(apply_cache_capacity)
},
}
}
}
impl<'id, $($($gen),*)?> ::oxidd_core::util::DropWith<<$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Edge<'id>>
for $name<'id, $($($gen),*)?> $(where $($where)*)?
{
fn drop_with(
self,
drop_edge: impl Fn(<$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Edge<'id>),
) {
self.apply_cache.drop_with(drop_edge)
}
}
impl<'id, $($($gen),*)?> ::oxidd_core::HasApplyCache<<$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Manager<'id>, $op>
for $name<'id, $($($gen),*)?> $(where $($where)*)?
{
type ApplyCache = $crate::util::apply_cache::ApplyCache<
<$dd$(<$($dd_gen),*>)? as $crate::util::type_cons::DD>::Manager<'id>,
$op,
$arity,
>;
#[inline]
fn apply_cache(&self) -> &Self::ApplyCache {
&self.apply_cache
}
#[inline]
fn apply_cache_mut(&mut self) -> &mut Self::ApplyCache {
&mut self.apply_cache
}
}
};
}
#[allow(unused)]
pub(crate) use manager_data;
#[allow(unused)]
macro_rules! dd_index_based {
($dd:ident$(<$($gen:ident),*>)? {
node: $nc:ty,
edge_tag: $et:ty,
terminal_manager: $tmc:ty,
rules: $rc:ident for $r:ty,
manager_data: $mdc:ident for $md:ident$(<$($md_gen:ident),*>)?,
terminals: $terminals:expr,
} $(where $($where:tt)*)?) => {
type $dd$(<$($gen),*>)? = $crate::util::type_cons::IndexDD<$nc, $et, $tmc, $rc, $mdc, $terminals>;
pub struct $rc;
impl$(<$($gen),*>)? ::oxidd_manager_index::manager::DiagramRulesCons<$nc, $et, $tmc, $mdc, $terminals>
for $rc $(where $($where)*)?
{
type T<'id> = $r;
}
pub struct $mdc;
impl$(<$($gen),*>)? ::oxidd_manager_index::manager::ManagerDataCons<$nc, $et, $tmc, $rc, $terminals>
for $mdc $(where $($where)*)?
{
type T<'id> = $md<'id, $($($md_gen),*)?>;
}
};
}
#[allow(unused)]
pub(crate) use dd_index_based;
#[allow(unused)]
macro_rules! dd_pointer_based {
($dd:ident$(<$($gen:ident),*>)? {
node: $nc:ty,
edge_tag: $et:ty,
terminal_manager: $tmc:ty,
rules: $rc:ident for $r:ty,
manager_data: $mdc:ident for $md:ident$(<$($md_gen:ident),*>)?,
tag_bits: $tag_bits:expr,
} $(where $($where:tt)*)?) => {
type $dd$(<$($gen),*>)? = $crate::util::type_cons::PointerDD<
$nc,
$et,
$tmc,
$rc,
$mdc,
{ $crate::PAGE_SIZE },
$tag_bits,
>;
pub struct $rc;
impl$(<$($gen),*>)?
::oxidd_manager_pointer::manager::DiagramRulesCons<
$nc,
$et,
$tmc,
$mdc,
{ $crate::PAGE_SIZE },
$tag_bits,
> for $rc $(where $($where)*)?
{
type T<'id> = $r;
}
pub struct $mdc;
impl$(<$($gen),*>)?
::oxidd_manager_pointer::manager::ManagerDataCons<
$nc,
$et,
$tmc,
$rc,
{ $crate::PAGE_SIZE },
$tag_bits,
> for $mdc $(where $($where)*)?
{
type T<'id> = $md<'id, $($($md_gen),*)?>;
}
};
}
#[allow(unused)]
pub(crate) use dd_pointer_based;
#[allow(unused)]
macro_rules! manager_ref_index_based {
(pub struct $name:ident$(<$($gen:ident),*>)?($inner:ty) with $mgr_data:ty $(where $($where:tt)*)?) => {
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name$(<$($gen),*>)?($inner) $(where $($where)*)?;
impl$(<$($gen),*>)? Clone for $name$(<$($gen),*>)? $(where $($where)*)? {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<'__a, '__id, $($($gen),*)?> From<&'__a <$inner as $crate::ManagerRef>::Manager<'__id>> for $name$(<$($gen),*>)? $(where $($where)*)? {
#[inline]
fn from(manager: &'__a <$inner as $crate::ManagerRef>::Manager<'__id>) -> Self {
Self(<$inner as From<&'__a <$inner as $crate::ManagerRef>::Manager<'__id>>>::from(manager))
}
}
impl$(<$($gen),*>)? $crate::ManagerRef for $name$(<$($gen),*>)? $(where $($where)*)? {
type Manager<'__id> = <$inner as $crate::ManagerRef>::Manager<'__id>;
#[inline]
fn with_manager_shared<__F, __T>(&self, f: __F) -> __T
where
__F: for<'__id> FnOnce(&Self::Manager<'__id>) -> __T,
{
self.0.with_manager_shared(f)
}
#[inline]
fn with_manager_exclusive<__F, __T>(&self, f: __F) -> __T
where
__F: for<'__id> FnOnce(&mut Self::Manager<'__id>) -> __T,
{
self.0.with_manager_exclusive(f)
}
}
impl$(<$($gen),*>)? $crate::RawManagerRef for $name$(<$($gen),*>)? $(where $($where)*)? {
#[inline]
fn into_raw(self) -> *const std::ffi::c_void {
self.0.into_raw()
}
#[inline]
unsafe fn from_raw(raw: *const std::ffi::c_void) -> Self {
Self(unsafe { ::oxidd_manager_index::manager::ManagerRef::from_raw(raw) })
}
}
impl$(<$($gen),*>)? $crate::HasWorkers for $name$(<$($gen),*>)? $(where $($where)*)? {
type WorkerPool = <$inner as $crate::HasWorkers>::WorkerPool;
#[inline]
fn workers(&self) -> &Self::WorkerPool {
self.0.workers()
}
}
impl$(<$($gen),*>)? $name$(<$($gen),*>)? $(where $($where)*)? {
pub fn new_manager(
inner_node_capacity: usize,
terminal_node_capacity: usize,
apply_cache_capacity: usize,
threads: u32,
) -> Self {
assert!(
(inner_node_capacity + terminal_node_capacity) as u64 <= (1 << u32::BITS),
"`inner_node_capacity ({inner_node_capacity}) + terminal_node_capacity ({terminal_node_capacity})` must be <= 2^32"
);
Self(::oxidd_manager_index::manager::new_manager(
inner_node_capacity as u32,
terminal_node_capacity as u32,
threads,
unsafe { <$mgr_data>::new(apply_cache_capacity) },
))
}
}
};
}
#[allow(unused)]
pub(crate) use manager_ref_index_based;
#[allow(unused)]
macro_rules! manager_ref_pointer_based {
(pub struct $name:ident($inner:ty) with $mgr_data:ty) => {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name($inner);
impl<'__a, '__id> From<&'__a <$inner as $crate::ManagerRef>::Manager<'__id>> for $name {
#[inline]
fn from(manager: &'__a <$inner as $crate::ManagerRef>::Manager<'__id>) -> Self {
Self(<$inner as From<
&'__a <$inner as $crate::ManagerRef>::Manager<'__id>,
>>::from(manager))
}
}
impl $crate::ManagerRef for $name {
type Manager<'id> = <$inner as $crate::ManagerRef>::Manager<'id>;
#[inline]
fn with_manager_shared<F, T>(&self, f: F) -> T
where
F: for<'id> FnOnce(&Self::Manager<'id>) -> T,
{
self.0.with_manager_shared(f)
}
#[inline]
fn with_manager_exclusive<F, T>(&self, f: F) -> T
where
F: for<'id> FnOnce(&mut Self::Manager<'id>) -> T,
{
self.0.with_manager_exclusive(f)
}
}
impl $crate::RawManagerRef for $name {
#[inline]
fn into_raw(self) -> *const std::ffi::c_void {
self.0.into_raw()
}
#[inline]
unsafe fn from_raw(raw: *const std::ffi::c_void) -> Self {
Self(unsafe { ::oxidd_manager_pointer::manager::ManagerRef::from_raw(raw) })
}
}
impl $crate::HasWorkers for $name {
type WorkerPool = <$inner as $crate::HasWorkers>::WorkerPool;
#[inline]
fn workers(&self) -> &Self::WorkerPool {
self.0.workers()
}
}
impl $name {
#[allow(unused_variables)]
pub fn new_manager(
inner_node_capacity: usize,
apply_cache_capacity: usize,
threads: u32,
) -> Self {
Self(::oxidd_manager_pointer::manager::new_manager(
unsafe { <$mgr_data>::new(apply_cache_capacity) },
threads,
))
}
}
};
}
#[allow(unused)]
pub(crate) use manager_ref_pointer_based;
#[allow(unused)]
macro_rules! derive_raw_function_index_based {
(for: $name:ident$(<$($gen:ident),*>)?, inner: $inner:ty $(, where $($where:tt)*)?) => {
impl$(<$($gen),*>)? $crate::RawFunction for $name$(<$($gen),*>)? $(where $($where)*)? {
#[inline]
fn into_raw(self) -> (*const std::ffi::c_void, usize) {
let (ptr, index) = self.0.into_inner().into_raw();
(ptr, index as usize)
}
#[inline]
unsafe fn from_raw(ptr: *const std::ffi::c_void, index: usize) -> Self {
Self(<$inner>::from(unsafe {
::oxidd_manager_index::manager::Function::from_raw(ptr, index as u32)
}))
}
}
};
}
#[allow(unused)]
pub(crate) use derive_raw_function_index_based;
#[allow(unused)]
macro_rules! derive_raw_function_pointer_based {
(for: $name:ident, inner: $inner:ident) => {
impl $crate::RawFunction for $name {
#[inline]
fn into_raw(self) -> (*const std::ffi::c_void, usize) {
(self.0.into_inner().into_raw(), 0)
}
#[inline]
unsafe fn from_raw(ptr: *const std::ffi::c_void, _index: usize) -> Self {
Self($inner::from(unsafe {
::oxidd_manager_pointer::manager::Function::from_raw(ptr)
}))
}
}
};
}
#[allow(unused)]
pub(crate) use derive_raw_function_pointer_based;