pub( crate ) mod private
{
use crate::prelude::*;
macro_rules! NODE_ID
{
() => { < < Self as GraphNodesNominalInterface >::NodeHandle as HasId >::Id };
}
macro_rules! EDGE_ID
{
() => { < < Self as GraphEdgesNominalInterface >::EdgeHandle as HasId >::Id };
}
pub trait GraphNodesNominalInterface
{
type NodeHandle : NodeBasicInterface;
#[ allow( non_snake_case ) ]
#[ inline ]
fn NodeId< Id >( id : Id ) -> NODE_ID!()
where
Id : Into< NODE_ID!() >
{
id.into()
}
#[ inline ]
fn node_id< Id >( &self, id : Id ) -> NODE_ID!()
where
Id : Into< NODE_ID!() >
{
id.into()
}
fn node< Id >( &self, id : Id ) -> &Self::NodeHandle
where
Id : Into< NODE_ID!() >
;
fn out_nodes_ids< 'a, 'b, Id >( &'a self, node_id : Id )
->
Box< dyn Iterator< Item = NODE_ID!() > + 'b >
where
Id : Into< NODE_ID!() >,
'a : 'b,
;
fn out_nodes< 'a, 'b, Id >( &'a self, node_id : Id )
->
Box< dyn Iterator< Item = ( NODE_ID!(), &< Self as GraphNodesNominalInterface >::NodeHandle ) > + 'b >
where
Id : Into< NODE_ID!() >,
'a : 'b,
{
Box::new( self.out_nodes_ids( node_id ).map( | id |
{
( id, self.node( id ) )
}))
}
}
pub trait GraphEdgesNominalInterface
where
Self : GraphNodesNominalInterface,
{
type EdgeHandle : EdgeBasicInterface;
#[ allow( non_snake_case ) ]
#[ inline ]
fn EdgeId< Id >( id : Id ) -> EDGE_ID!()
where
Id : Into< EDGE_ID!() >
{
id.into()
}
#[ inline ]
fn edge_id< Id >( &self, id : Id ) -> EDGE_ID!()
where
Id : Into< EDGE_ID!() >
{
Self::EdgeId( id )
}
fn edge< Id >( &self, id : Id ) -> &Self::EdgeHandle
where
Id : Into< EDGE_ID!() >
;
fn out_edges_ids< 'a, 'b, IntoId >( &'a self, node_id : IntoId )
->
Box< dyn Iterator< Item = EDGE_ID!() > + 'b >
where
IntoId : Into< NODE_ID!() >,
'a : 'b,
;
fn out_edges< 'a, 'b, IntoId >( &'a self, node_id : IntoId )
->
Box< dyn Iterator< Item = ( EDGE_ID!(), &< Self as GraphEdgesNominalInterface >::EdgeHandle ) > + 'b >
where
IntoId : Into< NODE_ID!() >,
'a : 'b,
{
Box::new( self.out_edges_ids( node_id ).map( | id |
{
( id, self.edge( id ) )
}))
}
}
pub trait GraphNodesEnumerableInterface
where
Self : GraphNodesNominalInterface,
{
fn nodes< 'a, 'b >( &'a self )
->
Box< dyn Iterator< Item = ( NODE_ID!(), &< Self as GraphNodesNominalInterface >::NodeHandle ) > + 'b >
where
'a : 'b,
;
fn nnodes( &self ) -> usize
{
self.nodes().count()
}
}
pub trait GraphEdgesEnumerableInterface
where
Self :
GraphNodesNominalInterface +
GraphEdgesNominalInterface +
,
{
fn edges< 'a, 'b >( &'a self )
->
Box< dyn Iterator< Item = ( EDGE_ID!(), &< Self as GraphEdgesNominalInterface >::EdgeHandle ) > + 'b >
where
'a : 'b,
;
fn nedges( &self ) -> usize
{
self.edges().count()
}
}
pub trait GraphNodesExtendableInterface
where
Self :
GraphNodesNominalInterface +
,
{
fn node_mut< Id >( &mut self, id : Id ) -> &mut Self::NodeHandle
where
Id : Into< NODE_ID!() >
;
fn node_add_out_nodes< IntoId1, IntoId2, Iter >
(
&mut self,
node_id : IntoId1,
out_nodes_iter : Iter,
)
where
IntoId1 : Into< NODE_ID!() >,
IntoId2 : Into< NODE_ID!() >,
Iter : IntoIterator< Item = IntoId2 >,
Iter::IntoIter : Clone,
;
fn node_add_out_node< IntoId1, IntoId2 >
(
&mut self,
node_id : IntoId1,
out_node_id : IntoId2,
)
where
IntoId1 : Into< NODE_ID!() >,
IntoId1 : Clone,
IntoId2 : Into< NODE_ID!() >,
IntoId2 : Clone,
{
self.node_add_out_nodes( node_id, core::iter::once( out_node_id ) );
}
fn node_making< Id >( &mut self, id : Id ) -> NODE_ID!()
where
Id : Into< NODE_ID!() >
;
fn make_with_edge_list< IntoIter, Id >( &mut self, into_iter : IntoIter )
where
Id : Into< NODE_ID!() >,
IntoIter : IntoIterator< Item = Id >,
IntoIter::IntoIter : core::iter::ExactSizeIterator< Item = Id >,
{
use wtools::iter::prelude::*;
let iter = into_iter.into_iter();
debug_assert_eq!( iter.len() % 2, 0 );
for mut chunk in &iter.chunks( 2 )
{
let id1 = chunk.next().unwrap().into();
let id2 = chunk.next().unwrap().into();
self.node_making( id1 );
self.node_making( id2 );
self.node_add_out_node( id1, id2 );
}
}
}
pub trait GraphEdgesExtendableInterface
where
Self :
GraphNodesNominalInterface +
GraphEdgesNominalInterface +
GraphNodesExtendableInterface +
,
{
fn _edge_id_generate( &mut self, node1 : NODE_ID!(), node2 : NODE_ID!() ) -> EDGE_ID!();
fn _edge_add( &mut self, edge_id : EDGE_ID!(), node1 : NODE_ID!(), node2 : NODE_ID!() );
fn _edge_make_for_nodes< IntoNodeId1, IntoNodeId2 >( &mut self, node1 : IntoNodeId1, node2 : IntoNodeId2 ) -> EDGE_ID!()
where
IntoNodeId1 : Into< NODE_ID!() >,
IntoNodeId2 : Into< NODE_ID!() >,
{
let node1 = node1.into();
let node2 = node2.into();
let edge = self._edge_id_generate( node1, node2 );
self._edge_add( edge, node1, node2 );
edge
}
}
pub trait GraphNodesKindGetterInterface
where
Self : GraphNodesNominalInterface,
{
type NodeKind : crate::NodeKindInterface;
fn node_kind( &self, node_id : NODE_ID!() ) -> Self::NodeKind;
}
pub trait GraphEdgesKindGetterInterface
where
Self :
GraphNodesNominalInterface +
GraphEdgesNominalInterface +
,
{
type EdgeKind : crate::EdgeKindInterface;
fn edge_kind( &self, edge_id : EDGE_ID!() ) -> Self::EdgeKind;
}
}
pub mod protected
{
pub use super::orphan::*;
}
pub use protected::*;
pub mod orphan
{
pub use super::exposed::*;
}
pub mod exposed
{
pub use super::prelude::*;
}
pub use exposed::*;
pub mod prelude
{
pub use super::private::
{
GraphNodesNominalInterface,
GraphEdgesNominalInterface,
GraphNodesEnumerableInterface,
GraphEdgesEnumerableInterface,
GraphNodesExtendableInterface,
GraphEdgesExtendableInterface,
GraphNodesKindGetterInterface,
GraphEdgesKindGetterInterface,
};
}