alpar@503: #include<iostream>
ladanyi@542: #include<hugo/smart_graph.h>
alpar@564: #include<hugo/skeletons/graph.h>
alpar@578: #include<hugo/list_graph.h>
alpar@592: #include<hugo/full_graph.h>
alpar@578: 
alpar@567: #include"test_tools.h"
alpar@567: 
alpar@503: /*
alpar@503: This test makes consistency checks of list graph structures.
alpar@503: 
alpar@503: G.addNode(), G.addEdge(), G.valid(), G.tail(), G.head()
alpar@503: 
alpar@592: \todo Checks for empty graphs and isolated points.
alpar@503: */
alpar@503: 
alpar@503: using namespace hugo;
alpar@503: 
alpar@592: template<class Graph> void checkCompileStaticGraph(Graph &G) 
alpar@503: {
alpar@503:   typedef typename Graph::Node Node;
alpar@503:   typedef typename Graph::NodeIt NodeIt;
alpar@503:   typedef typename Graph::Edge Edge;
alpar@503:   typedef typename Graph::EdgeIt EdgeIt;
alpar@503:   typedef typename Graph::InEdgeIt InEdgeIt;
alpar@503:   typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@503:   
alpar@503:   {
alpar@503:     Node i; Node j(i); Node k(INVALID);
alpar@503:     i=j;
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503:   {
alpar@503:     NodeIt i; NodeIt j(i); NodeIt k(INVALID); NodeIt l(G);
alpar@503:     i=j;
alpar@503:     j=G.first(i);
alpar@503:     j=G.next(i);
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     Node n(i);
alpar@503:     n=i;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503:   {
alpar@503:     Edge i; Edge j(i); Edge k(INVALID);
alpar@503:     i=j;
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503:   {
alpar@503:     EdgeIt i; EdgeIt j(i); EdgeIt k(INVALID); EdgeIt l(G);
alpar@503:     i=j;
alpar@503:     j=G.first(i);
alpar@503:     j=G.next(i);
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     Edge e(i);
alpar@503:     e=i;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503:   {
alpar@503:     Node n;
alpar@503:     InEdgeIt i; InEdgeIt j(i); InEdgeIt k(INVALID); InEdgeIt l(G,n);
alpar@503:     i=j;
alpar@503:     j=G.first(i,n);
alpar@503:     j=G.next(i);
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     Edge e(i);
alpar@503:     e=i;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503:   {
alpar@503:     Node n;
alpar@503:     OutEdgeIt i; OutEdgeIt j(i); OutEdgeIt k(INVALID); OutEdgeIt l(G,n);
alpar@503:     i=j;
alpar@503:     j=G.first(i,n);
alpar@503:     j=G.next(i);
alpar@503:     bool b=G.valid(i); b=b;
alpar@503:     Edge e(i);
alpar@503:     e=i;
alpar@503:     b=(i==j); b=(i!=j); b=(i<j);
alpar@503:   }
alpar@503: 
alpar@503:   Node n,m;
alpar@592:   n=m=INVALID;
alpar@503:   Edge e;
alpar@592:   e=INVALID;
alpar@503:   n=G.tail(e);
alpar@503:   n=G.head(e);
alpar@503: 
alpar@503:   //aNode, bNode ?
alpar@503: 
alpar@503:   // id tests
alpar@503:   { int i=G.id(n); i=i; }
alpar@503:   { int i=G.id(e); i=i; }
alpar@503:   
alpar@592:   //  G.clear();
alpar@503: 
alpar@503:   //NodeMap tests
alpar@503:   {
alpar@503:     Node k;
alpar@515:     typename Graph::template NodeMap<int> m(G);
alpar@515:     typename Graph::template NodeMap<int> const &cm = m;  //Const map
alpar@515:     //Inicialize with default value
alpar@515:     typename Graph::template NodeMap<int> mdef(G,12);
alpar@515:     typename Graph::template NodeMap<int> mm(cm);   //Copy
alpar@515:     typename Graph::template NodeMap<double> dm(cm); //Copy from another type
alpar@503:     int v;
alpar@503:     v=m[k]; m[k]=v; m.set(k,v);
alpar@503:     v=cm[k];
alpar@503:     
alpar@503:     m=cm;  
alpar@503:     dm=cm; //Copy from another type
alpar@503:   }  
alpar@503:   { //bool NodeMap
alpar@503:     Node k;
alpar@515:     typename Graph::template NodeMap<bool> m(G);
alpar@515:     typename Graph::template NodeMap<bool> const &cm = m;  //Const map
alpar@515:     //Inicialize with default value
alpar@515:     typename Graph::template NodeMap<bool> mdef(G,12);
alpar@515:     typename Graph::template NodeMap<bool> mm(cm);   //Copy
alpar@515:     typename Graph::template NodeMap<int> dm(cm); //Copy from another type
alpar@503:     bool v;
alpar@503:     v=m[k]; m[k]=v; m.set(k,v);
alpar@503:     v=cm[k];
alpar@503:     
alpar@503:     m=cm;  
alpar@503:     dm=cm; //Copy from another type
alpar@504:     m=dm; //Copy to another type
alpar@503:   }
alpar@503:   //EdgeMap tests
alpar@503:   {
alpar@503:     Edge k;
alpar@515:     typename Graph::template EdgeMap<int> m(G);
alpar@515:     typename Graph::template EdgeMap<int> const &cm = m;  //Const map
alpar@515:     //Inicialize with default value
alpar@515:     typename Graph::template EdgeMap<int> mdef(G,12);
alpar@515:     typename Graph::template EdgeMap<int> mm(cm);   //Copy
alpar@515:     typename Graph::template EdgeMap<double> dm(cm); //Copy from another type
alpar@503:     int v;
alpar@503:     v=m[k]; m[k]=v; m.set(k,v);
alpar@503:     v=cm[k];
alpar@503:     
alpar@503:     m=cm;  
alpar@503:     dm=cm; //Copy from another type
alpar@503:   }  
alpar@503:   { //bool EdgeMap
alpar@503:     Edge k;
alpar@515:     typename Graph::template EdgeMap<bool> m(G);
alpar@515:     typename Graph::template EdgeMap<bool> const &cm = m;  //Const map
alpar@515:     //Inicialize with default value
alpar@515:     typename Graph::template EdgeMap<bool> mdef(G,12);
alpar@515:     typename Graph::template EdgeMap<bool> mm(cm);   //Copy
alpar@515:     typename Graph::template EdgeMap<int> dm(cm); //Copy from another type
alpar@503:     bool v;
alpar@503:     v=m[k]; m[k]=v; m.set(k,v);
alpar@503:     v=cm[k];
alpar@503:     
alpar@503:     m=cm;  
alpar@503:     dm=cm; //Copy from another type
alpar@504:     m=dm; //Copy to another type
alpar@503:   }
alpar@503:   
alpar@503: }
alpar@503: 
alpar@592: template<class Graph> void checkCompile(Graph &G) 
alpar@592: {
alpar@592:   checkCompileStaticGraph(G);
alpar@592: 
alpar@592:   typedef typename Graph::Node Node;
alpar@592:   typedef typename Graph::NodeIt NodeIt;
alpar@592:   typedef typename Graph::Edge Edge;
alpar@592:   typedef typename Graph::EdgeIt EdgeIt;
alpar@592:   typedef typename Graph::InEdgeIt InEdgeIt;
alpar@592:   typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@592:   
alpar@592:   Node n,m;
alpar@592:   n=G.addNode();
alpar@592:   m=G.addNode();
alpar@592:   
alpar@592:   G.addEdge(n,m);
alpar@592: }
alpar@592: 
alpar@592: 
alpar@503: template<class Graph> void checkNodeList(Graph &G, int nn)
alpar@503: {
alpar@503:   typename Graph::NodeIt n(G);
alpar@503:   for(int i=0;i<nn;i++) {
alpar@503:     check(G.valid(n),"Wrong Node list linking.");
alpar@503:     G.next(n);
alpar@503:   }
alpar@503:   check(!G.valid(n),"Wrong Node list linking.");
alpar@503: }
alpar@503: 
alpar@503: template<class Graph> void checkEdgeList(Graph &G, int nn)
alpar@503: {
alpar@503:   typedef typename Graph::EdgeIt EdgeIt;
alpar@503: 
alpar@503:   EdgeIt e(G);
alpar@503:   for(int i=0;i<nn;i++) {
alpar@503:     check(G.valid(e),"Wrong Edge list linking.");
alpar@503:     G.next(e);
alpar@503:   }
alpar@503:   check(!G.valid(e),"Wrong Edge list linking.");
alpar@503: }
alpar@503: 
alpar@503: template<class Graph> void checkOutEdgeList(Graph &G,
alpar@503: 					    typename Graph::Node n,
alpar@503: 					    int nn)
alpar@503: {
alpar@503:   typename Graph::OutEdgeIt e(G,n);
alpar@503:   for(int i=0;i<nn;i++) {
alpar@503:     check(G.valid(e),"Wrong OutEdge list linking.");
alpar@503:     G.next(e);
alpar@503:   }
alpar@503:   check(!G.valid(e),"Wrong OutEdge list linking.");
alpar@503: }
alpar@503: 
alpar@503: template<class Graph> void checkInEdgeList(Graph &G,
alpar@503: 					    typename Graph::Node n,
alpar@503: 					    int nn)
alpar@503: {
alpar@503:   typename Graph::InEdgeIt e(G,n);
alpar@503:   for(int i=0;i<nn;i++) {
alpar@503:     check(G.valid(e),"Wrong InEdge list linking.");
alpar@503:     G.next(e);
alpar@503:   }
alpar@503:   check(!G.valid(e),"Wrong InEdge list linking.");
alpar@503: }
alpar@503: 
alpar@503: //Checks head(), tail() as well;
alpar@503: template<class Graph> void bidirPetersen(Graph &G)
alpar@503: {
alpar@503:   typedef typename Graph::Edge Edge;
alpar@503:   typedef typename Graph::EdgeIt EdgeIt;
alpar@503:   
alpar@503:   checkEdgeList(G,15);
alpar@503:   
alpar@503:   std::vector<Edge> ee;
alpar@503:   
alpar@503:   for(EdgeIt e(G);G.valid(e);G.next(e)) ee.push_back(e);
alpar@503: 
alpar@503:   for(typename std::vector<Edge>::iterator p=ee.begin();p!=ee.end();p++)
alpar@503:     G.addEdge(G.head(*p),G.tail(*p));
alpar@503: }
alpar@503: 
alpar@503: template<class Graph> void checkPetersen(Graph &G)
alpar@503: {
alpar@503:   typedef typename Graph::Node Node;
alpar@503: 
alpar@503:   typedef typename Graph::EdgeIt EdgeIt;
alpar@503:   typedef typename Graph::NodeIt NodeIt;
alpar@503: 
alpar@503:   checkNodeList(G,10);
alpar@503:   checkEdgeList(G,30);
alpar@503: 
alpar@503:   for(NodeIt n(G);G.valid(n);G.next(n)) {
alpar@503:     checkInEdgeList(G,n,3);
alpar@503:     checkOutEdgeList(G,n,3);
alpar@503:     G.next(n);
alpar@503:   }  
alpar@503: }
alpar@503: 
alpar@564: template void checkCompile<GraphSkeleton>(GraphSkeleton &);
alpar@503: template void checkCompile<SmartGraph>(SmartGraph &);
alpar@503: template void checkCompile<SymSmartGraph>(SymSmartGraph &);
alpar@578: template void checkCompile<ListGraph>(ListGraph &);
alpar@578: template void checkCompile<SymListGraph>(SymListGraph &);
alpar@592: template void checkCompileStaticGraph<FullGraph>(FullGraph &);
alpar@550: 
alpar@579: //Due to some mysterious problems it does not work.
alpar@579: template void checkCompile<EdgeSet <ListGraph> >(EdgeSet <ListGraph> &);
alpar@579: //template void checkCompile<EdgeSet <NodeSet> >(EdgeSet <NodeSet> &);
alpar@503: 
alpar@503: int main() 
alpar@503: {
alpar@503:   {
alpar@503:     SmartGraph G;
alpar@503:     addPetersen(G);
alpar@503:     bidirPetersen(G);
alpar@503:     checkPetersen(G);
alpar@503:   }
alpar@578:   {
alpar@578:     ListGraph G;
alpar@578:     addPetersen(G);
alpar@578:     bidirPetersen(G);
alpar@578:     checkPetersen(G);
alpar@578:   }
alpar@503:   {
alpar@503:     SymSmartGraph G;
alpar@503:     addPetersen(G);
alpar@503:     checkPetersen(G);
alpar@503:   }
alpar@578:   {
alpar@578:     SymListGraph G;
alpar@578:     addPetersen(G);
alpar@578:     checkPetersen(G);
alpar@578:   }
alpar@503: 
alpar@503:   //\todo map tests.
alpar@503:   //\todo copy constr tests.
alpar@503: 
alpar@503:   std::cout << __FILE__ ": All tests passed.\n";
alpar@503: 
alpar@579:   return 0;
alpar@503: }