mod future;
pub use future::*;
mod critical_edge;
pub use critical_edge::*;
mod explicit;
pub use explicit::*;
mod implicit;
pub use implicit::*;
mod unchecked;
pub use unchecked::*;
mod private {
pub trait Sealed {}
}
use crate::scopegraph::{InnerScopeGraph, Scope};
use crate::{Label, ScopeGraph};
use private::Sealed;
use std::rc::Rc;
use std::{fmt::Debug, hash::Hash, marker::PhantomData};
#[allow(missing_docs)]
pub trait Completeness<LABEL: Label, DATA>: Sealed {
fn cmpl_new_scope(&self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope);
fn cmpl_new_complete_scope(
&self,
inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
scope: Scope,
);
type NewEdgeResult;
fn cmpl_new_edge(
&self,
inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
src: Scope,
lbl: LABEL,
dst: Scope,
) -> Self::NewEdgeResult;
type GetEdgesResult<'rslv>
where
Self: 'rslv,
LABEL: 'rslv,
DATA: 'rslv;
fn cmpl_get_edges<'rslv>(
&'rslv self,
inner_scope_graph: &'rslv InnerScopeGraph<LABEL, DATA>,
src: Scope,
lbl: LABEL,
) -> Self::GetEdgesResult<'rslv>
where
LABEL: 'rslv,
DATA: 'rslv;
}
#[doc(hidden)]
pub struct Witness(pub(crate) ());
pub trait UserClosed<LABEL: Label, DATA>: Completeness<LABEL, DATA> {
#[doc(hidden)]
fn close(&self, scope: Scope, label: &LABEL, witness: Witness);
}
pub trait Implicit<LABEL: Label, DATA>: Completeness<LABEL, DATA> {}
#[derive(Debug)]
struct ScopeExtPermInner<
'ext,
LABEL: Hash + Label + Debug,
DATA,
CMPL: UserClosed<LABEL, DATA>, > {
scope: Scope,
label: LABEL,
sg: &'ext CMPL,
_data: PhantomData<DATA>, }
impl<LABEL: Hash + Label + Debug, DATA, CMPL> Drop for ScopeExtPermInner<'_, LABEL, DATA, CMPL>
where
CMPL: UserClosed<LABEL, DATA>,
{
fn drop(&mut self) {
self.sg.close(self.scope, &self.label, Witness(()))
}
}
#[derive(Debug)]
pub struct ScopeExtPerm<'ext, LABEL: Hash + Label + Debug, DATA, CMPL: UserClosed<LABEL, DATA>>(
Rc<ScopeExtPermInner<'ext, LABEL, DATA, CMPL>>,
);
impl<LABEL: Hash + Label + Debug, DATA, CMPL: UserClosed<LABEL, DATA>> Clone
for ScopeExtPerm<'_, LABEL, DATA, CMPL>
{
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<'ext, LABEL: Hash + Label + Debug, DATA, CMPL: UserClosed<LABEL, DATA>>
ScopeExtPerm<'ext, LABEL, DATA, CMPL>
where
CMPL: UserClosed<LABEL, DATA>,
{
pub(super) fn scope(&self) -> &Scope {
&self.0.scope
}
pub(super) fn label(&self) -> &LABEL {
&self.0.label
}
#[doc(hidden)]
pub unsafe fn init<'storage>(
scope: Scope,
label: LABEL,
sg: &'ext ScopeGraph<'storage, LABEL, DATA, CMPL>,
) -> ScopeExtPerm<'ext, LABEL, DATA, CMPL> {
ScopeExtPerm(Rc::new(ScopeExtPermInner {
scope,
label,
sg: &sg.completeness,
_data: PhantomData,
}))
}
pub fn close(self) {
}
}
#[macro_export]
macro_rules! add_scope {
($sg:expr, $data:expr, [ $($lbl:expr),* ]) => {
{
let sg = $sg; let data = $data;
let scope = sg.add_scope_with(data, [$($lbl),*]);
(scope, $(unsafe { $crate::completeness::ScopeExtPerm::init(scope, $lbl, sg) }),*)
}
};
($sg:expr, [$($lbl:expr),* ]) => { add_scope!($sg, Default::default(), [$($lbl),*]) };
($sg:expr) => { add_scope!($sg, Default::default(), []).0 };
}
#[macro_export]
macro_rules! add_edge {
($sg:expr, $ext:expr, $tgt:expr) => {
sg.ext_edge($ext, $tgt)
};
($sg:expr, $src:expr, $lbl:expr, $tgt:expr) => {
sg.add_edge($src, $lbl, $tgt)
};
}