marci@325: // -*- c++ -*- marci@325: #ifndef HUGO_GRAPH_H marci@325: #define HUGO_GRAPH_H marci@325: marci@325: ///\file marci@651: ///\brief Declaration of GraphConcept. marci@325: marci@651: #include marci@325: marci@325: namespace hugo { marci@325: marci@651: /// @defgroup empty_graph The GraphConcept class marci@332: /// @{ marci@325: marci@325: /// An empty graph class. marci@325: marci@325: /// This class provides all the common features of a graph structure, marci@325: /// however completely without implementations and real data structures marci@325: /// behind the interface. marci@325: /// All graph algorithms should compile with this class, but it will not marci@325: /// run properly, of course. marci@325: /// marci@325: /// It can be used for checking the interface compatibility, marci@325: /// or it can serve as a skeleton of a new graph structure. marci@325: /// marci@325: /// Also, you will find here the full documentation of a certain graph marci@325: /// feature, the documentation of a real graph imlementation marci@325: /// like @ref ListGraph or marci@325: /// @ref SmartGraph will just refer to this structure. marci@651: class GraphConcept marci@325: { marci@325: public: marci@325: /// Defalult constructor. marci@651: GraphConcept() { } marci@325: marci@651: /// \brief Copy consructor. marci@651: /// marci@651: /// \todo It is not clear, what we expect from a copy constructor. marci@651: /// E.g. How to assign the nodes/edges to each other? What about maps? marci@651: GraphConcept(const GraphConcept&) { } marci@325: marci@651: /// \brief The base type of the node iterators. marci@651: /// marci@325: /// This is the base type of each node iterators, marci@325: /// thus each kind of node iterator will convert to this. marci@651: /// Sometimes it is said to be a trivial iterator. marci@325: class Node { marci@325: public: marci@325: /// @warning The default constructor sets the iterator marci@325: /// to an undefined value. marci@651: Node() { } //FIXME marci@325: marci@651: // /// Copy constructor. marci@651: // Node(const Node&) { } marci@651: marci@651: /// \brief Invalid constructor \& conversion. marci@651: /// marci@325: /// This constructor initializes the iterator to be invalid. marci@325: /// \sa Invalid for more details. marci@651: Node(const Invalid&) { } marci@651: marci@325: /// Two iterators are equal if and only if they point to the marci@325: /// same object or both are invalid. marci@325: bool operator==(Node n) const { return true; } marci@325: marci@325: /// \sa \ref operator==(Node n) marci@325: /// marci@325: bool operator!=(Node n) const { return true; } marci@325: marci@325: bool operator<(Node n) const { return true; } marci@325: }; marci@325: marci@325: /// The base type of the edge iterators. marci@325: class Edge { marci@325: public: marci@325: /// @warning The default constructor sets the iterator marci@325: /// to an undefined value. marci@651: Edge() { } //FIXME marci@651: marci@651: // /// Copy constructor. marci@651: // Edge(const Edge&) { } marci@651: marci@325: /// Initialize the iterator to be invalid marci@651: Edge(const Invalid&) { } marci@325: /// Two iterators are equal if and only if they point to the marci@325: /// same object or both are invalid. marci@325: bool operator==(Edge n) const { return true; } marci@325: bool operator!=(Edge n) const { return true; } marci@325: bool operator<(Edge n) const { return true; } marci@325: }; marci@325: marci@325: // class SymEdgeIt : public Edge {}; marci@325: marci@325: marci@325: // SymEdgeIt &first(SymEdgeIt &, Node) const { return i;} marci@325: marci@325: // Node getNext(Node) const {} marci@325: // InEdgeIt getNext(InEdgeIt) const {} marci@325: // OutEdgeIt getNext(OutEdgeIt) const {} marci@325: // //SymEdgeIt getNext(SymEdgeIt) const {} marci@325: // EdgeIt getNext(EdgeIt) const {} marci@325: marci@325: //SymEdgeIt &next(SymEdgeIt &) const {} marci@325: marci@651: marci@651: /// Gives back the head node of an edge. marci@651: Node head(const Edge&) const { return INVALID; } marci@651: /// Gives back the tail node of an edge. marci@651: Node tail(const Edge&) const { return INVALID; } marci@325: marci@325: // Node aNode(SymEdgeIt) const {} marci@325: // Node bNode(SymEdgeIt) const {} marci@325: marci@651: /// \brief Checks if a node iterator is valid marci@651: /// marci@651: /// \todo Maybe, it would be better if iterator converted to marci@651: /// bool directly, as Jacint prefers. marci@651: bool valid(const Node&) const { return true; } marci@651: /// \brief Checks if an edge iterator is valid marci@651: /// marci@651: /// \todo Maybe, it would be better if iterator converted to marci@651: /// bool directly, as Jacint prefers. marci@651: bool valid(const Edge&) const { return true; } marci@325: marci@651: /// \brief Gives back the \e id of a node. marci@651: /// marci@651: /// \warning Not all graph structures provide this feature. marci@325: /// marci@651: int id(const Node&) const { return 0; } marci@651: /// \brief Gives back the \e id of an edge. marci@325: /// marci@651: /// \warning Not all graph structures provide this feature. marci@651: /// marci@651: int id(const Edge&) const { return 0; } marci@325: marci@325: //void setInvalid(Node &) const {}; marci@325: //void setInvalid(Edge &) const {}; marci@325: marci@651: /// \brief Add a new node to the graph. marci@651: /// marci@325: /// \return the new node. marci@651: Node addNode() { return INVALID; } marci@651: /// \brief Add a new edge to the graph. marci@325: /// marci@651: /// Add a new edge to the graph with tail node \c tail marci@651: /// and head node \c head. marci@651: /// \return the new edge. marci@651: Edge addEdge(const Node& tail, const Node& head) { return INVALID; } marci@325: marci@651: /// \brief Resets the graph. marci@651: /// marci@325: /// This function deletes all edges and nodes of the graph. marci@325: /// It also frees the memory allocated to store them. marci@651: /// \todo What happens with the maps? marci@651: void clear() { } marci@325: marci@651: /// Read/write/reference map of the nodes to type \c T. marci@325: marci@651: /// Read/write/reference map of the nodes to type \c T. marci@651: /// \sa MemoryMapConcept marci@325: /// \todo We may need copy constructor marci@325: /// \todo We may need conversion from other nodetype marci@325: /// \todo We may need operator= marci@325: /// \warning Making maps that can handle bool type (NodeMap) marci@325: /// needs extra attention! marci@325: marci@325: template class NodeMap marci@325: { marci@325: public: marci@325: typedef T ValueType; marci@325: typedef Node KeyType; marci@325: marci@651: NodeMap(const GraphConcept& g) { } marci@651: NodeMap(const GraphConcept& g, T t) { } marci@325: marci@651: template NodeMap(const NodeMap& m) { } marci@325: marci@325: /// Sets the value of a node. marci@325: marci@325: /// Sets the value associated with node \c i to the value \c t. marci@325: /// marci@325: void set(Node i, T t) {} marci@325: /// Gets the value of a node. marci@325: T get(Node i) const {return *(T*)0;} //FIXME: Is it necessary marci@325: T &operator[](Node i) {return *(T*)0;} marci@325: const T &operator[](Node i) const {return *(T*)0;} marci@325: marci@325: /// Updates the map if the graph has been changed marci@325: marci@325: /// \todo Do we need this? marci@325: /// marci@651: void update() { } marci@651: //void update(T a) { } //FIXME: Is it necessary marci@325: }; marci@325: marci@325: ///Read/write/reference map of the edges to type \c T. marci@325: marci@651: /// Read/write/reference map of the edges to type \c T. marci@651: /// It behaves exactly in the same way as \ref NodeMap. marci@325: /// \sa NodeMap marci@651: /// \sa MemoryMapConcept marci@325: /// \todo We may need copy constructor marci@325: /// \todo We may need conversion from other edgetype marci@325: /// \todo We may need operator= marci@325: template class EdgeMap marci@325: { marci@325: public: marci@325: typedef T ValueType; marci@325: typedef Edge KeyType; marci@325: marci@651: EdgeMap(const GraphConcept& g) {} marci@651: EdgeMap(const GraphConcept& g, T t) {} marci@325: marci@325: void set(Edge i, T t) {} marci@325: T get(Edge i) const {return *(T*)0;} marci@325: T &operator[](Edge i) {return *(T*)0;} marci@325: marci@651: void update() { } marci@651: //void update(T a) { } //FIXME: Is it necessary marci@325: }; marci@325: }; marci@325: marci@651: marci@651: /// \brief Node-iterable graph concept. marci@325: /// marci@651: /// A graph class which provides functions to marci@651: /// iterate on its nodes. marci@651: class NodeIterableGraphConcept : virtual public GraphConcept marci@334: { marci@334: public: marci@334: marci@651: /// \brief This iterator goes trough the nodes of the graph. marci@651: /// marci@651: /// This iterator goes trough the \e nodes of the graph. marci@651: /// Its usage is quite simple, for example you can count the number marci@651: /// of nodes in graph \c g of type \c Graph as follows. marci@651: /// \code marci@651: /// int count=0; marci@651: /// for(Graph::NodeIt n(g); g.valid(n); g.next(n)) ++count; marci@651: /// \endcode marci@651: class NodeIt : public Node { marci@651: public: marci@651: /// @warning The default constructor sets the iterator. marci@651: /// to an undefined value. marci@651: NodeIt() { } marci@651: // /// Copy constructor marci@651: //NodeIt(const NodeIt& n) { } marci@651: /// Initialize the iterator to be invalid. marci@651: NodeIt(const Invalid&) { } marci@651: /// \brief This constructor sets the iterator to first node. marci@651: /// marci@651: /// This constructor set the iterator to the first marci@651: /// node of the graph \c g. marci@651: /// marci@651: ///@param g the graph marci@651: NodeIt(const GraphConcept& g) { } marci@651: }; marci@334: marci@651: /// The first node. marci@651: NodeIt &first(NodeIt &i) const { return i; } marci@651: marci@651: /// Go to the next node. marci@651: NodeIt &next(NodeIt &i) const { return i; } marci@651: }; marci@651: marci@651: marci@651: /// \brief Edge-iterable graph concept. marci@651: /// marci@651: /// A graph class which provides functions to marci@651: /// iterate on its edges. marci@651: class EdgeIterableGraphConcept : virtual public GraphConcept marci@651: { marci@651: public: marci@651: marci@651: /// \brief This iterator goes trough the edges of the graph. marci@651: /// marci@651: /// This iterator goes trough the \e edges of the graph. marci@651: /// Its usage is quite simple, for example you can count the number marci@651: /// of edges in graph \c g of type \c Graph as follows. marci@651: /// \code marci@651: /// int count=0; marci@651: /// for(Graph::EdgeIt e(g); g.valid(e); g.next(e)) ++count; marci@651: /// \endcode marci@651: class EdgeIt : public Edge { marci@651: public: marci@651: /// @warning The default constructor sets the iterator. marci@651: /// to an undefined value. marci@651: EdgeIt() { } marci@651: // /// Copy constructor marci@651: // EdgeIt(const EdgeIt&) { } marci@651: /// Initialize the iterator to be invalid. marci@651: EdgeIt(const Invalid&) { } marci@651: /// \brief This constructor sets the iterator to first edge. marci@651: /// marci@651: /// This constructor set the iterator to the first marci@651: /// edge of the graph \c g. marci@651: /// marci@651: ///@param g the graph marci@651: EdgeIt(const GraphConcept& g) { } marci@651: }; marci@651: marci@651: /// The first edge. marci@651: EdgeIt &first(EdgeIt &i) const { return i; } marci@651: marci@651: /// Go to the next edge. marci@651: EdgeIt &next(EdgeIt &i) const { return i; } marci@651: }; marci@651: marci@651: marci@651: /// \brief Out-edge-iterable graph concept. marci@651: /// marci@651: /// A graph class which provides functions to marci@651: /// iterate on out-edges of any node. marci@651: class OutEdgeIterableGraphConcept : virtual public GraphConcept marci@651: { marci@651: public: marci@651: marci@651: /// \brief This iterator goes trough the outgoing edges of a node. marci@651: /// marci@334: /// This iterator goes trough the \e outgoing edges of a certain node marci@334: /// of a graph. marci@334: /// Its usage is quite simple, for example you can count the number marci@334: /// of outgoing edges of a node \c n marci@651: /// in graph \c g of type \c Graph as follows. marci@334: /// \code marci@651: /// int count=0; marci@651: /// for(Graph::OutEdgeIt e(g, n); g.valid(e); g.next(e)) ++count; marci@334: /// \endcode marci@334: class OutEdgeIt : public Edge { marci@334: public: marci@651: /// @warning The default constructor sets the iterator. marci@334: /// to an undefined value. marci@651: OutEdgeIt() { } marci@651: /// Initialize the iterator to be invalid. marci@651: OutEdgeIt(const Invalid&) { } marci@651: /// \brief This constructor sets the iterator to first outgoing edge. marci@651: /// marci@334: /// This constructor set the iterator to the first outgoing edge of marci@334: /// node marci@334: ///@param n the node marci@651: ///@param g the graph marci@651: OutEdgeIt(const GraphConcept& g, const Node& n) { } marci@334: }; marci@651: marci@651: /// The first outgoing edge. marci@651: OutEdgeIt &first(OutEdgeIt &i, const Node& n) const { return i; } marci@651: marci@651: /// Go to the next outgoing edge. marci@651: OutEdgeIt &next(OutEdgeIt &i) const { return i; } marci@651: marci@651: Node aNode(const OutEdgeIt&) const { return Node(); } marci@651: Node bNode(const OutEdgeIt&) const { return Node(); } marci@334: }; marci@334: marci@651: marci@651: /// \brief In-edge-iterable graph concept. marci@651: /// marci@651: /// A Graph class which provides a function to marci@334: /// iterate on in-edges of any node. marci@651: class InEdgeIterableGraphConcept : virtual public GraphConcept marci@334: { marci@334: public: marci@334: marci@651: /// \brief This iterator goes trough the incoming edges of a node. marci@651: /// marci@334: /// This iterator goes trough the \e incoming edges of a certain node marci@334: /// of a graph. marci@334: /// Its usage is quite simple, for example you can count the number marci@334: /// of incoming edges of a node \c n marci@651: /// in graph \c g of type \c Graph as follows. marci@334: /// \code marci@651: /// int count=0; marci@651: /// for(Graph::InEdgeIt e(g, n); g.valid(e); g.next(e)) ++count; marci@334: /// \endcode marci@334: class InEdgeIt : public Edge { marci@334: public: marci@334: /// @warning The default constructor sets the iterator marci@334: /// to an undefined value. marci@651: InEdgeIt() { } marci@334: /// Initialize the iterator to be invalid marci@651: InEdgeIt(const Invalid&) { } marci@651: /// \brief This constructor sets the iterator to first incomig edge. marci@651: /// marci@334: /// This constructor set the iterator to the first incomig edge of marci@334: /// node marci@334: ///@param n the node marci@651: ///@param g the graph marci@651: InEdgeIt(const GraphConcept& g, const Node& n) { } marci@334: }; marci@651: marci@651: /// The first incoming edge. marci@651: InEdgeIt &first(InEdgeIt &i, const Node& n) const { return i; } marci@651: marci@651: /// Go to the next incoming edge. marci@651: InEdgeIt &next(InEdgeIt &i) const { return i; } marci@651: marci@651: Node aNode(const InEdgeIt&) const { return Node(); } marci@651: Node bNode(const InEdgeIt&) const { return Node(); } marci@334: }; marci@334: marci@334: alpar@826: /// \brief Node-erasable graph concept. marci@651: /// marci@651: /// A graph class which provides a function to marci@333: /// delete any of its nodes. alpar@826: class NodeErasableGraphConcept : virtual public GraphConcept marci@333: { marci@333: public: marci@333: /// Deletes a node. marci@651: void erase(const Node& n) { } marci@333: }; marci@333: marci@651: alpar@826: /// \brief Edge-erasable graph concept. marci@651: /// marci@651: /// A graph class which provides a function to delete any marci@333: /// of its edges. alpar@826: class EdgeErasableGraphConcept : virtual public GraphConcept marci@333: { marci@333: public: marci@333: /// Deletes a node. marci@651: void erase(const Edge& n) { } marci@333: }; marci@333: marci@651: marci@651: /// \brief An empty graph class which provides a function to marci@651: /// get the number of its nodes. marci@651: /// marci@325: /// This graph class provides a function for getting the number of its marci@325: /// nodes. marci@325: /// Clearly, for physical graph structures it can be expected to have such a marci@325: /// function. For wrappers or graphs which are given in an implicit way, marci@325: /// the implementation can be circumstantial, that is why this composes a marci@325: /// separate concept. marci@651: class NodeCountingGraphConcept : virtual public GraphConcept marci@325: { marci@325: public: marci@325: /// Returns the number of nodes. marci@651: int nodeNum() const { return 0; } marci@325: }; marci@325: marci@651: marci@651: /// \brief An empty graph class which provides a function to marci@651: /// get the number of its edges. marci@651: /// marci@325: /// This graph class provides a function for getting the number of its marci@325: /// edges. marci@325: /// Clearly, for physical graph structures it can be expected to have such a marci@325: /// function. For wrappers or graphs which are given in an implicit way, marci@325: /// the implementation can be circumstantial, that is why this composes a marci@325: /// separate concept. marci@651: class EdgeCountingGraphConcept : virtual public GraphConcept marci@325: { marci@325: public: marci@325: /// Returns the number of edges. marci@651: int edgeNum() const { return 0; } marci@651: }; marci@651: marci@652: class FullFeatureGraphConcept : virtual public NodeIterableGraphConcept, marci@652: virtual public EdgeIterableGraphConcept, marci@652: virtual public OutEdgeIterableGraphConcept, marci@652: virtual public InEdgeIterableGraphConcept, marci@652: virtual public NodeCountingGraphConcept { marci@651: public: marci@651: FullFeatureGraphConcept() { } marci@652: using EdgeIterableGraphConcept::next; marci@652: using NodeIterableGraphConcept::next; marci@652: using OutEdgeIterableGraphConcept::next; marci@652: using InEdgeIterableGraphConcept::next; marci@325: }; marci@332: marci@332: /// @} marci@325: marci@325: } //namespace hugo marci@325: marci@325: marci@332: marci@651: // class EmptyBipGraph : public Graph Concept marci@325: // { marci@325: // class ANode {}; marci@325: // class BNode {}; marci@325: marci@325: // ANode &next(ANode &) {} marci@325: // BNode &next(BNode &) {} marci@325: marci@325: // ANode &getFirst(ANode &) const {} marci@325: // BNode &getFirst(BNode &) const {} marci@325: marci@325: // enum NodeClass { A = 0, B = 1 }; marci@325: // NodeClass getClass(Node n) {} marci@325: marci@325: // } marci@325: marci@325: #endif // HUGO_GRAPH_H