# HG changeset patch # User alpar # Date 1084120193 0 # Node ID 5961cce7ec5370b5b5cb0c0735eaffcb6c4aa9af # Parent eb532eef617005c7ebd5134595091b96a202eaa6 The file src/work/alpar/fullgraph.h renamed and moved to src/hugo/full_graph.h. Compilation tests for FullGraph added to src/test/graph_test.h. diff -r eb532eef6170 -r 5961cce7ec53 src/hugo/full_graph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugo/full_graph.h Sun May 09 16:29:53 2004 +0000 @@ -0,0 +1,295 @@ +// -*- mode:C++ -*- + +#ifndef HUGO_FULL_GRAPH_H +#define HUGO_FULL_GRAPH_H + +///\ingroup graphs +///\file +///\brief FullGraph and SymFullGraph classes. + +#include +#include + +#include + +namespace hugo { + +/// \addtogroup graphs +/// @{ + + ///A full graph class. + + ///This is a simple and fast directed full graph implementation. + ///It it completely static, so you can neither add nor delete either + ///edges or nodes. + ///Otherwise it conforms to the graph interface documented under + ///the description of \ref GraphSkeleton. + ///\sa \ref GraphSkeleton. + ///\todo Shouldn't we avoid loops? + /// + ///\author Alpar Juttner + class FullGraph { + int NodeNum; + int EdgeNum; + public: + template class EdgeMap; + template class NodeMap; + + class Node; + class Edge; + class NodeIt; + class EdgeIt; + class OutEdgeIt; + class InEdgeIt; + + template class NodeMap; + template class EdgeMap; + + public: + + ///Creates a full graph with \c n nodes. + FullGraph(int n) : NodeNum(n), EdgeNum(NodeNum*NodeNum) { } + /// + FullGraph(const FullGraph &_g) + : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { } + + int nodeNum() const { return NodeNum; } //FIXME: What is this? + int edgeNum() const { return EdgeNum; } //FIXME: What is this? + + int maxNodeId() const { return NodeNum; } //FIXME: What is this? + int maxEdgeId() const { return EdgeNum; } //FIXME: What is this? + + Node tail(Edge e) const { return e.n%NodeNum; } + Node head(Edge e) const { return e.n/NodeNum; } + + Node aNode(OutEdgeIt e) const { return tail(e); } + Node aNode(InEdgeIt e) const { return head(e); } + + Node bNode(OutEdgeIt e) const { return head(e); } + Node bNode(InEdgeIt e) const { return tail(e); } + + NodeIt& first(NodeIt& v) const { + v=NodeIt(*this); return v; } + EdgeIt& first(EdgeIt& e) const { + e=EdgeIt(*this); return e; } + OutEdgeIt& first(OutEdgeIt& e, const Node v) const { + e=OutEdgeIt(*this,v); return e; } + InEdgeIt& first(InEdgeIt& e, const Node v) const { + e=InEdgeIt(*this,v); return e; } + + bool valid(Edge e) const { return e.n!=-1; } + bool valid(Node n) const { return n.n!=-1; } + + template It getNext(It it) const + { It tmp(it); return next(tmp); } + + NodeIt& next(NodeIt& it) const { + it.n=(it.n+2)%(NodeNum+1)-1; + return it; + } + OutEdgeIt& next(OutEdgeIt& it) const + { it.n+=NodeNum; if(it.n>=EdgeNum) it.n=-1; return it; } + InEdgeIt& next(InEdgeIt& it) const + { if(!((++it.n)%NodeNum)) it.n=-1; return it; } + EdgeIt& next(EdgeIt& it) const { --it.n; return it; } + + int id(Node v) const { return v.n; } + int id(Edge e) const { return e.n; } + + class Node { + friend class FullGraph; + template friend class NodeMap; + + friend class Edge; + friend class OutEdgeIt; + friend class InEdgeIt; + friend class SymEdge; + + protected: + int n; + friend int FullGraph::id(Node v) const; + Node(int nn) {n=nn;} + public: + Node() {} + Node (Invalid) { n=-1; } + bool operator==(const Node i) const {return n==i.n;} + bool operator!=(const Node i) const {return n!=i.n;} + bool operator<(const Node i) const {return n NodeIt. + NodeIt(const FullGraph& G, const Node &n) : Node(n) { } + }; + + class Edge { + friend class FullGraph; + template friend class EdgeMap; + + friend class Node; + friend class NodeIt; + protected: + int n; //NodeNum*head+tail; + friend int FullGraph::id(Edge e) const; + + Edge(int nn) {n=nn;} + public: + Edge() { } + Edge (Invalid) { n=-1; } + bool operator==(const Edge i) const {return n==i.n;} + bool operator!=(const Edge i) const {return n!=i.n;} + bool operator<(const Edge i) const {return n class NodeMap + { + std::vector container; + + public: + typedef T ValueType; + typedef Node KeyType; + + NodeMap(const FullGraph &_G) : container(_G.NodeNum) { } + NodeMap(const FullGraph &_G,const T &t) : container(_G.NodeNum,t) { } + NodeMap(const NodeMap &m) : container(m.container) { } + + template friend class NodeMap; + ///\todo It can copy between different types. + template NodeMap(const NodeMap &m) + : container(m.container.size()) + { + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + void set(Node n, T a) { container[n.n]=a; } + //'T& operator[](Node n)' would be wrong here + typename std::vector::reference + operator[](Node n) { return container[n.n]; } + //'const T& operator[](Node n)' would be wrong here + typename std::vector::const_reference + operator[](Node n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const NodeMap& operator=(const NodeMap &m) + { + container = m.container; + return *this; + } + template + const NodeMap& operator=(const NodeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for Dynamic Maps + void update(T a) {} //Useless for Dynamic Maps + }; + + template class EdgeMap + { + std::vector container; + + public: + typedef T ValueType; + typedef Edge KeyType; + + EdgeMap(const FullGraph &_G) : container(_G.EdgeNum) { } + EdgeMap(const FullGraph &_G,const T &t) : container(_G.EdgeNum,t) { } + EdgeMap(const EdgeMap &m) : container(m.container) { } + + template friend class EdgeMap; + ///\todo It can copy between different types. + ///\todo We could use 'copy' + template EdgeMap(const EdgeMap &m) : + container(m.container.size()) + { + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + void set(Edge n, T a) { container[n.n]=a; } + //T get(Edge n) const { return container[n.n]; } + typename std::vector::reference + operator[](Edge n) { return container[n.n]; } + typename std::vector::const_reference + operator[](Edge n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const EdgeMap& operator=(const EdgeMap &m) + { + container = m.container; + return *this; + } + template + const EdgeMap& operator=(const EdgeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} + void update(T a) {} + }; + + }; + + /// @} + +} //namespace hugo + + + + +#endif //HUGO_FULL_GRAPH_H diff -r eb532eef6170 -r 5961cce7ec53 src/test/graph_test.cc --- a/src/test/graph_test.cc Sun May 09 16:22:49 2004 +0000 +++ b/src/test/graph_test.cc Sun May 09 16:29:53 2004 +0000 @@ -2,6 +2,7 @@ #include #include #include +#include #include"test_tools.h" @@ -10,11 +11,12 @@ G.addNode(), G.addEdge(), G.valid(), G.tail(), G.head() +\todo Checks for empty graphs and isolated points. */ using namespace hugo; -template void checkCompile(Graph &G) +template void checkCompileStaticGraph(Graph &G) { typedef typename Graph::Node Node; typedef typename Graph::NodeIt NodeIt; @@ -79,9 +81,9 @@ } Node n,m; - n=G.addNode(); + n=m=INVALID; Edge e; - e=G.addEdge(n,m); + e=INVALID; n=G.tail(e); n=G.head(e); @@ -91,7 +93,7 @@ { int i=G.id(n); i=i; } { int i=G.id(e); i=i; } - G.clear(); + // G.clear(); //NodeMap tests { @@ -160,6 +162,25 @@ } +template void checkCompile(Graph &G) +{ + checkCompileStaticGraph(G); + + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Edge Edge; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::InEdgeIt InEdgeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + + Node n,m; + n=G.addNode(); + m=G.addNode(); + + G.addEdge(n,m); +} + + template void checkNodeList(Graph &G, int nn) { typename Graph::NodeIt n(G); @@ -244,6 +265,7 @@ template void checkCompile(SymSmartGraph &); template void checkCompile(ListGraph &); template void checkCompile(SymListGraph &); +template void checkCompileStaticGraph(FullGraph &); //Due to some mysterious problems it does not work. template void checkCompile >(EdgeSet &); diff -r eb532eef6170 -r 5961cce7ec53 src/work/alpar/fullgraph.h --- a/src/work/alpar/fullgraph.h Sun May 09 16:22:49 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -// -*- mode:C++ -*- - -#ifndef HUGO_FULL_GRAPH_H -#define HUGO_FULL_GRAPH_H - -///\ingroup graphs -///\file -///\brief FullGraph and SymFullGraph classes. - -#include -#include - -#include - -namespace hugo { - -/// \addtogroup graphs -/// @{ - - ///A full graph class. - - ///This is a simple and fast directed full graph implementation. - ///It it completely static, so you can neither add nor delete either - ///edges or nodes. - ///Otherwise it conforms to the graph interface documented under - ///the description of \ref GraphSkeleton. - ///\sa \ref GraphSkeleton. - ///\todo Shouldn't we avoid loops? - /// - ///\author Alpar Juttner - class FullGraph { - int NodeNum; - int EdgeNum; - public: - template class EdgeMap; - template class NodeMap; - - class Node; - class Edge; - class NodeIt; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - template class NodeMap; - template class EdgeMap; - - public: - - ///Creates a full graph with \c n nodes. - FullGraph(int n) : NodeNum(n), EdgeNum(NodeNum*NodeNum) { } - /// - FullGraph(const FullGraph &_g) - : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { } - - int nodeNum() const { return NodeNum; } //FIXME: What is this? - int edgeNum() const { return EdgeNum; } //FIXME: What is this? - - int maxNodeId() const { return NodeNum; } //FIXME: What is this? - int maxEdgeId() const { return EdgeNum; } //FIXME: What is this? - - Node tail(Edge e) const { return e.n%NodeNum; } - Node head(Edge e) const { return e.n/NodeNum; } - - Node aNode(OutEdgeIt e) const { return tail(e); } - Node aNode(InEdgeIt e) const { return head(e); } - - Node bNode(OutEdgeIt e) const { return head(e); } - Node bNode(InEdgeIt e) const { return tail(e); } - - NodeIt& first(NodeIt& v) const { - v=NodeIt(*this); return v; } - EdgeIt& first(EdgeIt& e) const { - e=EdgeIt(*this); return e; } - OutEdgeIt& first(OutEdgeIt& e, const Node v) const { - e=OutEdgeIt(*this,v); return e; } - InEdgeIt& first(InEdgeIt& e, const Node v) const { - e=InEdgeIt(*this,v); return e; } - - bool valid(Edge e) const { return e.n!=-1; } - bool valid(Node n) const { return n.n!=-1; } - - template It getNext(It it) const - { It tmp(it); return next(tmp); } - - NodeIt& next(NodeIt& it) const { - it.n=(it.n+2)%(NodeNum+1)-1; - return it; - } - OutEdgeIt& next(OutEdgeIt& it) const - { it.n+=NodeNum; if(it.n>=EdgeNum) it.n=-1; return it; } - InEdgeIt& next(InEdgeIt& it) const - { if(!((++it.n)%NodeNum)) it.n=-1; return it; } - EdgeIt& next(EdgeIt& it) const { --it.n; return it; } - - int id(Node v) const { return v.n; } - int id(Edge e) const { return e.n; } - - class Node { - friend class FullGraph; - template friend class NodeMap; - - friend class Edge; - friend class OutEdgeIt; - friend class InEdgeIt; - friend class SymEdge; - - protected: - int n; - friend int FullGraph::id(Node v) const; - Node(int nn) {n=nn;} - public: - Node() {} - Node (Invalid) { n=-1; } - bool operator==(const Node i) const {return n==i.n;} - bool operator!=(const Node i) const {return n!=i.n;} - bool operator<(const Node i) const {return n NodeIt. - NodeIt(const FullGraph& G, const Node &n) : Node(n) { } - }; - - class Edge { - friend class FullGraph; - template friend class EdgeMap; - - friend class Node; - friend class NodeIt; - protected: - int n; //NodeNum*head+tail; - friend int FullGraph::id(Edge e) const; - - Edge(int nn) {n=nn;} - public: - Edge() { } - Edge (Invalid) { n=-1; } - bool operator==(const Edge i) const {return n==i.n;} - bool operator!=(const Edge i) const {return n!=i.n;} - bool operator<(const Edge i) const {return n class NodeMap - { - std::vector container; - - public: - typedef T ValueType; - typedef Node KeyType; - - NodeMap(const FullGraph &_G) : container(_G.NodeNum) { } - NodeMap(const FullGraph &_G,const T &t) : container(_G.NodeNum,t) { } - NodeMap(const NodeMap &m) : container(m.container) { } - - template friend class NodeMap; - ///\todo It can copy between different types. - template NodeMap(const NodeMap &m) - : container(m.container.size()) - { - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - void set(Node n, T a) { container[n.n]=a; } - //'T& operator[](Node n)' would be wrong here - typename std::vector::reference - operator[](Node n) { return container[n.n]; } - //'const T& operator[](Node n)' would be wrong here - typename std::vector::const_reference - operator[](Node n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const NodeMap& operator=(const NodeMap &m) - { - container = m.container; - return *this; - } - template - const NodeMap& operator=(const NodeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for Dynamic Maps - void update(T a) {} //Useless for Dynamic Maps - }; - - template class EdgeMap - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - EdgeMap(const FullGraph &_G) : container(_G.EdgeNum) { } - EdgeMap(const FullGraph &_G,const T &t) : container(_G.EdgeNum,t) { } - EdgeMap(const EdgeMap &m) : container(m.container) { } - - template friend class EdgeMap; - ///\todo It can copy between different types. - ///\todo We could use 'copy' - template EdgeMap(const EdgeMap &m) : - container(m.container.size()) - { - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - void set(Edge n, T a) { container[n.n]=a; } - //T get(Edge n) const { return container[n.n]; } - typename std::vector::reference - operator[](Edge n) { return container[n.n]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const EdgeMap& operator=(const EdgeMap &m) - { - container = m.container; - return *this; - } - template - const EdgeMap& operator=(const EdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} - void update(T a) {} - }; - - }; - - /// @} - -} //namespace hugo - - - - -#endif //HUGO_FULL_GRAPH_H