/* -*- C++ -*- * src/lemon/concept/graph_component.h - Part of LEMON, a generic C++ optimization library * * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Combinatorial Optimization Research Group, EGRES). * * Permission to use, modify and distribute this software is granted * provided that this copyright notice appears in all copies. For * precise terms see the accompanying LICENSE file. * * This software is provided "AS IS" with no warranty of any kind, * express or implied, and with no claim as to its suitability for any * purpose. * */ ///\ingroup concept ///\file ///\brief The graph components. #ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H #define LEMON_CONCEPT_GRAPH_COMPONENT_H #include #include namespace lemon { namespace concept { /**************** Graph iterator concepts ****************/ /// Skeleton class for graph Node and Edge /// \note Because Node and Edge are forbidden to inherit from the same /// base class, this is a template. For Node you should instantiate it /// with character 'n' and for Edge with 'e'. template class GraphItem { public: /// Default constructor. /// @warning The default constructor sets the item /// to an undefined value. GraphItem() {} /// Copy constructor. /// Copy constructor. /// GraphItem(GraphItem const&) {} /// Invalid constructor \& conversion. /// This constructor initializes the item to be invalid. /// \sa Invalid for more details. GraphItem(Invalid) {} /// Assign operator for nodes. /// The nodes are assignable. /// GraphItem& operator=(GraphItem const&) { return *this; } /// Equality operator. /// Two iterators are equal if and only if they represents the /// same node in the graph or both are invalid. bool operator==(GraphItem) const { return false; } /// Inequality operator. /// \sa operator==(const Node& n) /// bool operator!=(GraphItem) const { return false; } // Technical requirement. Do we really need this? // bool operator<(GraphItem) const { return false; } template struct Constraints { void constraints() { _GraphItem i1; _GraphItem i2 = i1; _GraphItem i3 = INVALID; i1 = i2 = i3; bool b; // b = (ia == ib) && (ia != ib) && (ia < ib); b = (ia == ib) && (ia != ib); b = (ia == INVALID) && (ib != INVALID); } const _GraphItem &ia; const _GraphItem &ib; }; }; /// An empty base graph class. /// This class provides the minimal set of features needed for a graph /// structure. All graph concepts have to be conform to this base /// graph. /// /// \bug This is not true. The minimal graph concept is the /// BaseIterableGraphComponent. class BaseGraphComponent { public: typedef BaseGraphComponent Graph; /// Node class of the graph. /// This class represents the Nodes of the graph. /// typedef GraphItem<'n'> Node; /// Edge class of the graph. /// This class represents the Edges of the graph. /// typedef GraphItem<'e'> Edge; ///Gives back the target node of an edge. ///Gives back the target node of an edge. /// Node target(const Edge&) const { return INVALID;} ///Gives back the source node of an edge. ///Gives back the source node of an edge. /// Node source(const Edge&) const { return INVALID;} template struct Constraints { typedef typename _Graph::Node Node; typedef typename _Graph::Edge Edge; void constraints() { checkConcept, Node>(); checkConcept, Edge>(); { Node n; Edge e; n = graph.source(e); n = graph.target(e); } } const _Graph& graph; }; }; /// An empty iterable base graph class. /// This class provides beside the core graph features /// core iterable interface for the graph structure. /// Most of the base graphs should be conform to this concept. class BaseIterableGraphComponent : virtual public BaseGraphComponent { public: typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// Gives back the first Node in the iterating order. /// Gives back the first Node in the iterating order. /// void first(Node&) const {} /// Gives back the next Node in the iterating order. /// Gives back the next Node in the iterating order. /// void next(Node&) const {} /// Gives back the first Edge in the iterating order. /// Gives back the first Edge in the iterating order. /// void first(Edge&) const {} /// Gives back the next Edge in the iterating order. /// Gives back the next Edge in the iterating order. /// void next(Edge&) const {} /// Gives back the first of the Edges point to the given Node. /// Gives back the first of the Edges point to the given Node. /// void firstIn(Edge&, const Node&) const {} /// Gives back the next of the Edges points to the given Node. /// Gives back the next of the Edges points to the given Node. /// void nextIn(Edge&) const {} /// Gives back the first of the Edges start from the given Node. /// Gives back the first of the Edges start from the given Node. /// void firstOut(Edge&, const Node&) const {} /// Gives back the next of the Edges start from the given Node. /// Gives back the next of the Edges start from the given Node. /// void nextOut(Edge&) const {} template struct Constraints { void constraints() { checkConcept< BaseGraphComponent, _Graph >(); typename _Graph::Node node; typename _Graph::Edge edge; { graph.first(node); graph.next(node); } { graph.first(edge); graph.next(edge); } { graph.firstIn(edge, node); graph.nextIn(edge); } { graph.firstOut(edge, node); graph.nextOut(edge); } } const _Graph& graph; }; }; /// An empty idable base graph class. /// This class provides beside the core graph features /// core id functions for the graph structure. /// The most of the base graphs should be conform to this concept. /// The id's are unique and immutable. class IDableGraphComponent : virtual public BaseGraphComponent { public: typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// Gives back an unique integer id for the Node. /// Gives back an unique integer id for the Node. /// int id(const Node&) const { return -1;} /// Gives back an unique integer id for the Edge. /// Gives back an unique integer id for the Edge. /// int id(const Edge&) const { return -1;} template struct Constraints { void constraints() { checkConcept< BaseGraphComponent, _Graph >(); typename _Graph::Node node; int nid = graph.id(node); nid = graph.id(node); typename _Graph::Edge edge; int eid = graph.id(edge); eid = graph.id(edge); } const _Graph& graph; }; }; /// An empty max-idable base graph class. /// This class provides beside the core graph features /// core max id functions for the graph structure. /// The most of the base graphs should be conform to this concept. /// The id's are unique and immutable. class MaxIDableGraphComponent : virtual public BaseGraphComponent { public: /// Gives back an integer greater or equal to the maximum Node id. /// Gives back an integer greater or equal to the maximum Node id. /// int maxId(Node = INVALID) const { return -1;} /// Gives back an integer greater or equal to the maximum Edge id. /// Gives back an integer greater or equal to the maximum Edge id. /// int maxId(Edge = INVALID) const { return -1;} template struct Constraints { void constraints() { checkConcept(); int nid = graph.maxId(typename _Graph::Node()); ignore_unused_variable_warning(nid); int eid = graph.maxId(typename _Graph::Edge()); ignore_unused_variable_warning(eid); } const _Graph& graph; }; }; /// An empty extendable base graph class. /// This class provides beside the core graph features /// core graph extend interface for the graph structure. /// The most of the base graphs should be conform to this concept. class BaseExtendableGraphComponent : virtual public BaseGraphComponent { public: typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// Adds a new Node to the graph. /// Adds a new Node to the graph. /// Node addNode() { return INVALID; } /// Adds a new Edge connects the two Nodes to the graph. /// Adds a new Edge connects the two Nodes to the graph. /// Edge addEdge(const Node& from, const Node& to) { return INVALID; } template struct Constraints { void constraints() { checkConcept(); typename _Graph::Node node_a, node_b; node_a = graph.addNode(); typename _Graph::Edge edge; edge = graph.addEdge(node_a, node_b); } _Graph& graph; }; }; /// An empty erasable base graph class. /// This class provides beside the core graph features /// core erase functions for the graph structure. /// The most of the base graphs should be conform to this concept. class BaseErasableGraphComponent : virtual public BaseGraphComponent { public: typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// Erase a Node from the graph. /// Erase a Node from the graph. This function should not /// erase edges connecting to the Node. void erase(const Node&) {} /// Erase an Edge from the graph. /// Erase an Edge from the graph. /// void erase(const Edge&) {} template struct Constraints { void constraints() { checkConcept(); typename _Graph::Node node; graph.erase(node); typename _Graph::Edge edge; graph.erase(edge); } _Graph& graph; }; }; /// An empty clearable base graph class. /// This class provides beside the core graph features /// core clear functions for the graph structure. /// The most of the base graphs should be conform to this concept. class ClearableGraphComponent : virtual public BaseGraphComponent { public: /// Erase all the Nodes and Edges from the graph. /// Erase all the Nodes and Edges from the graph. /// void clear() {} template struct Constraints { void constraints() { checkConcept(); graph.clear(); } _Graph graph; }; }; /// Skeleton class for graph NodeIt and EdgeIt /// Skeleton class for graph NodeIt and EdgeIt. /// template class GraphIterator : public _Item { public: /// \todo Don't we need the Item type as typedef? /// Default constructor. /// @warning The default constructor sets the iterator /// to an undefined value. GraphIterator() {} /// Copy constructor. /// Copy constructor. /// GraphIterator(GraphIterator const&) {} /// Sets the iterator to the first item. /// Sets the iterator to the first item of \c the graph. /// explicit GraphIterator(const _Graph&) {} /// Invalid constructor \& conversion. /// This constructor initializes the item to be invalid. /// \sa Invalid for more details. GraphIterator(Invalid) {} /// Assign operator for items. /// The items are assignable. /// GraphIterator& operator=(GraphIterator const&) { return *this; } /// Next item. /// Assign the iterator to the next item. /// GraphIterator& operator++() { return *this; } // Node operator*() const { return INVALID; } /// Equality operator /// Two iterators are equal if and only if they point to the /// same object or both are invalid. bool operator==(const GraphIterator&) const { return true;} /// Inequality operator /// \sa operator==(Node n) /// bool operator!=(const GraphIterator&) const { return true;} template struct Constraints { void constraints() { // checkConcept< Item, _GraphIterator >(); _GraphIterator it1(g); /// \todo Do we need NodeIt(Node) kind of constructor? // _GraphIterator it2(bj); _GraphIterator it2; it2 = ++it1; ++it2 = it1; ++(++it1); /// \bug This should be: is_base_and_derived _Item bi = it1; bi = it2; } _Graph& g; }; }; /// Skeleton class for graph InEdgeIt and OutEdgeIt /// \note Because InEdgeIt and OutEdgeIt may not inherit from the same /// base class, the _selector is a additional template parameter. For /// InEdgeIt you should instantiate it with character 'i' and for /// OutEdgeIt with 'o'. /// \todo Is this a good name for this concept? template class GraphIncIterator : public Edge { public: /// Default constructor. /// @warning The default constructor sets the iterator /// to an undefined value. GraphIncIterator() {} /// Copy constructor. /// Copy constructor. /// GraphIncIterator(GraphIncIterator const&) {} /// Sets the iterator to the first edge incoming into or outgoing from the node. /// Sets the iterator to the first edge incoming into or outgoing from the node. /// explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {} /// Invalid constructor \& conversion. /// This constructor initializes the item to be invalid. /// \sa Invalid for more details. GraphIncIterator(Invalid) {} /// Assign operator for nodes. /// The nodes are assignable. /// GraphIncIterator& operator=(GraphIncIterator const&) { return *this; } /// Next edge. /// Assign the iterator to the next node. /// GraphIncIterator& operator++() { return *this; } // Node operator*() const { return INVALID; } /// Equality operator /// Two iterators are equal if and only if they point to the /// same object or both are invalid. bool operator==(const GraphIncIterator&) const { return true;} /// Inequality operator /// \sa operator==(Node n) /// bool operator!=(const GraphIncIterator&) const { return true;} template struct Constraints { typedef typename Graph::Node Node; void constraints() { checkConcept, _GraphIncIterator>(); _GraphIncIterator it1(graph, node); /// \todo Do we need OutEdgeIt(Edge) kind of constructor? // _GraphIncIterator it2(edge); _GraphIncIterator it2; it2 = ++it1; ++it2 = it1; ++(++it1); Edge e = it1; e = it2; } Edge& edge; Node& node; Graph& graph; }; }; /// An empty iterable base graph class. /// This class provides beside the core graph features /// iterator based iterable interface for the graph structure. /// This concept is part of the StaticGraphConcept. class IterableGraphComponent : virtual public BaseGraphComponent { public: typedef IterableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// This iterator goes through each node. /// This iterator goes through each node. /// typedef GraphIterator NodeIt; /// This iterator goes through each node. /// This iterator goes through each node. /// typedef GraphIterator EdgeIt; /// This iterator goes trough the incoming edges of a node. /// This iterator goes trough the \e inccoming edges of a certain node /// of a graph. typedef GraphIncIterator InEdgeIt; /// This iterator goes trough the outgoing edges of a node. /// This iterator goes trough the \e outgoing edges of a certain node /// of a graph. typedef GraphIncIterator OutEdgeIt; }; template struct Constraints { void constraints() { checkConcept< BaseGraphComponent, _Graph>(); checkConcept, typename _Graph::EdgeIt >(); checkConcept, typename _Graph::NodeIt >(); checkConcept, typename _Graph::InEdgeIt >(); checkConcept, typename _Graph::OutEdgeIt >(); } }; template class GraphMap : public ReadWriteMap { protected: GraphMap() {} public: explicit GraphMap(const Graph&) {} GraphMap(const Graph&, const _Value&) {} GraphMap(const GraphMap&) {} GraphMap& operator=(const GraphMap&) { return *this;} template struct Constraints { void constraints() { checkConcept, _Map >(); // Construction with a graph parameter _Map a(g); // Constructor with a graph and a default value parameter _Map a2(g,t); // Copy constructor. Do we need it? _Map b=c; // Copy operator. Do we need it? a=b; ignore_unused_variable_warning(a2); } const _Map &c; const Graph &g; const typename GraphMap::Value &t; }; }; /// An empty mappable base graph class. /// This class provides beside the core graph features /// map interface for the graph structure. /// This concept is part of the StaticGraphConcept. class MappableGraphComponent : virtual public BaseGraphComponent { public: typedef MappableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; /// ReadWrite map of the nodes. /// ReadWrite map of the nodes. /// template class NodeMap : public GraphMap { private: NodeMap(); public: // \todo call the right parent class constructor explicit NodeMap(const Graph&) {} NodeMap(const Graph&, const _Value&) {} NodeMap(const NodeMap&) {} NodeMap& operator=(const NodeMap&) { return *this;} }; /// ReadWrite map of the edges. /// ReadWrite map of the edges. /// template class EdgeMap : public GraphMap { private: EdgeMap(); public: // \todo call the right parent class constructor explicit EdgeMap(const Graph&) {} EdgeMap(const Graph&, const _Value&) {} EdgeMap(const EdgeMap&) {} EdgeMap& operator=(const EdgeMap&) { return *this;} }; template struct Constraints { struct Type { int value; Type() : value(0) {} Type(int _v) : value(_v) {} }; void constraints() { checkConcept(); { // int map test typedef typename _Graph::template NodeMap IntNodeMap; checkConcept, IntNodeMap >(); } { // bool map test typedef typename _Graph::template NodeMap BoolNodeMap; checkConcept, BoolNodeMap >(); } { // Type map test typedef typename _Graph::template NodeMap TypeNodeMap; checkConcept, TypeNodeMap >(); } { // int map test typedef typename _Graph::template EdgeMap IntEdgeMap; checkConcept, IntEdgeMap >(); } { // bool map test typedef typename _Graph::template EdgeMap BoolEdgeMap; checkConcept, BoolEdgeMap >(); } { // Type map test typedef typename _Graph::template EdgeMap TypeEdgeMap; checkConcept, TypeEdgeMap >(); } } _Graph& graph; }; }; class ExtendableGraphComponent : virtual public BaseGraphComponent { public: typedef ExtendableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; Node addNode() { return INVALID; } Edge addEdge(const Node& from, const Node& to) { return INVALID; } template struct Constraints { void constraints() { checkConcept(); typename _Graph::Node node_a, node_b; node_a = graph.addNode(); typename _Graph::Edge edge; edge = graph.addEdge(node_a, node_b); } _Graph& graph; }; }; class ErasableGraphComponent : virtual public BaseGraphComponent { public: typedef ErasableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; void erase(const Node&) {} void erase(const Edge&) {} template struct Constraints { void constraints() { checkConcept(); typename _Graph::Node node; graph.erase(node); typename _Graph::Edge edge; graph.erase(edge); } _Graph& graph; }; }; } } #endif