/* -*- 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 shoul instantiate it /// with character 'n' and for Edge with 'e'. template class GraphItem { public: GraphItem() {} GraphItem(Invalid) {} // We explicitely list these: GraphItem(GraphItem const&) {} GraphItem& operator=(GraphItem const&) { return *this; } bool operator==(GraphItem) const { return false; } bool operator!=(GraphItem) const { return false; } // Technical requirement. Do we really need this? bool operator<(GraphItem) const { return false; } }; template struct GraphItemConcept { void constraints() { GI i1; GI i2 = i1; GI i3 = INVALID; i1 = i2 = i3; bool b; b = (ia == ib) && (ia != ib) && (ia < ib); b = (ia == INVALID) && (ib != INVALID); } const GI &ia; const GI &ib; }; template struct GraphIteratorConcept { void constraints() { function_requires< GraphItemConcept >(); Iter it1(g); /// \todo Do we need NodeIt(Node) kind of constructor? // Iter it2(bj); Iter it2; it2 = ++it1; ++it2 = it1; ++(++it1); /// \bug This should be: is_base_and_derived BaseItem bi = it1; bi = it2; } BaseItem bj; Graph g; }; template struct GraphIncIteratorConcept { typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; void constraints() { function_requires< GraphItemConcept >(); Iter it1(graph, node); /// \todo Do we need OutEdgeIt(Edge) kind of constructor? // Iter it2(edge); Iter it2; it2 = ++it1; ++it2 = it1; ++(++it1); Edge e = it1; e = it2; } Edge edge; Node node; Graph graph; }; /// 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. /// class Node { public: /// Default constructor. /// @warning The default constructor sets the iterator /// to an undefined value. Node() {} /// Copy constructor. /// Copy constructor. /// Node(const Node&) {} /// Invalid constructor \& conversion. /// This constructor initializes the iterator to be invalid. /// \sa Invalid for more details. Node(Invalid) {} Node& operator=(const Node&) { 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==(const Node&) const { return true;} /// Inequality operator. /// \sa operator==(const Node& n) /// bool operator!=(const Node&) const { return true;} /// Comparison operator. /// This is a strict ordering between the nodes. /// /// This ordering can be different from the iterating order of nodes. /// \todo Possibly we don't need it. bool operator<(const Node&) const { return true;} }; /// Edge class of the graph. /// This class represents the Edges of the graph. /// class Edge { public: /// Default constructor. /// @warning The default constructor sets the iterator /// to an undefined value. Edge() {} /// Copy constructor. /// Copy constructor. /// Edge(const Edge&) {} /// Invalid constructor \& conversion. /// This constructor initializes the iterator to be invalid. /// \sa Invalid for more details. Edge(Invalid) {} Edge& operator=(const Edge&) { return *this;} /// Equality operator. /// Two iterators are equal if and only if they represents the /// same edge in the graph or both are invalid. bool operator==(const Edge&) const { return true;} /// Inequality operator. /// \sa operator==(const Edge& n) /// bool operator!=(const Edge&) const { return true;} /// Comparison operator. /// This is a strict ordering between the edges. /// /// This ordering can be different from the iterating order of edges. /// \todo Possibly we don't need it. bool operator<(const Edge&) const { return true;} }; ///Gives back the head node of an edge. ///Gives back the head node of an edge. /// Node head(const Edge&) const { return INVALID;} ///Gives back the tail node of an edge. ///Gives back the tail node of an edge. /// Node tail(const Edge&) const { return INVALID;} }; /// Concept check structure for BaseGraph. /// Concept check structure for BaseGraph. /// template struct BaseGraphComponentConcept { typedef typename Graph::Node Node; typedef typename Graph::Edge Edge; void constraints() { function_requires< GraphItemConcept >(); function_requires< GraphItemConcept >(); { Node n; Edge e; n = graph.tail(e); n = graph.head(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 {} }; /// Concept check structure for IterableBaseGraph. /// Concept check structure for IterableBaseGraph. /// template struct BaseIterableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); 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;} }; /// Concept check structure for IdableBaseGraph. /// Concept check structure for IdableBaseGraph. /// template struct IDableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); 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 maxEdgeId() 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 maxNodeId() const { return -1;} }; /// Concept check structure for MaxIdableBaseGraph. /// Concept check structure for MaxIdableBaseGraph. /// template struct MaxIDableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); int nid = graph.maxEdgeId(); ignore_unused_variable_warning(nid); int eid = graph.maxNodeId(); 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; } }; /// Concept check structure for ExtendableBaseGraph. /// Concept check structure for ExtendableBaseGraph. /// template struct BaseExtendableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); 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&) {} }; /// Concept check structure for ErasableBaseGraph. /// Concept check structure for ErasableBaseGraph. /// template struct BaseErasableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); 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 BaseClearableGraphComponent : virtual public BaseGraphComponent { public: /// Erase all the Nodes and Edges from the graph. /// Erase all the Nodes and Edges from the graph. /// void clear() {} }; /// Concept check function for ErasableBaseGraph. /// Concept check function for ErasableBaseGraph. /// template struct BaseClearableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); graph.clear(); } Graph& graph; }; class IterableGraphComponent : virtual public BaseIterableGraphComponent { public: typedef IterableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; class NodeIt : public Node { public: NodeIt() {} NodeIt(Invalid) {} // explicit NodeIt(Node) {} explicit NodeIt(const Graph&) {} NodeIt& operator++() { return *this; } // Node operator*() const { return INVALID; } bool operator==(const NodeIt&) const { return true;} bool operator!=(const NodeIt&) const { return true;} }; class EdgeIt : public Edge { public: EdgeIt() {} EdgeIt(Invalid) {} // explicit EdgeIt(Edge) {} explicit EdgeIt(const Graph&) {} EdgeIt& operator++() { return *this; } // Edge operator*() const { return INVALID; } bool operator==(const EdgeIt&) const { return true;} bool operator!=(const EdgeIt&) const { return true;} }; class InEdgeIt : public Edge { public: InEdgeIt() {} InEdgeIt(Invalid) {} // explicit InEdgeIt(Edge) {} explicit InEdgeIt(const Graph&, const Node&) {} InEdgeIt& operator++() { return *this; } // Edge operator*() const { return INVALID; } bool operator==(const InEdgeIt&) const { return true;} bool operator!=(const InEdgeIt&) const { return true;} }; class OutEdgeIt : public Edge { public: OutEdgeIt() {} OutEdgeIt(Invalid) {} // explicit OutEdgeIt(Edge) {} explicit OutEdgeIt(const Graph&, const Node&) {} OutEdgeIt& operator++() { return *this; } // Edge operator*() const { return INVALID; } bool operator==(const OutEdgeIt&) const { return true;} bool operator!=(const OutEdgeIt&) const { return true;} }; }; template struct IterableGraphComponentConcept { void constraints() { function_requires< BaseIterableGraphComponentConcept >(); 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; function_requires< GraphIteratorConcept >(); function_requires< GraphIteratorConcept >(); function_requires< GraphIncIteratorConcept >(); function_requires< GraphIncIteratorConcept >(); } }; class IdMappableGraphComponent : virtual public BaseGraphComponent { typedef IdMappableGraphComponent Graph; public: typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; class NodeIdMap : public ReadMap { public: NodeIdMap(const Graph&) {} int maxId() const { return -1;} }; class EdgeIdMap : public ReadMap { public: EdgeIdMap(const Graph&) {} int maxId() const { return -1;} }; }; template struct IdMappableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); { typedef typename Graph::EdgeIdMap EdgeIdMap; function_requires >(); EdgeIdMap edge_map(graph); int n = edge_map.maxId(); ignore_unused_variable_warning(n); } { typedef typename Graph::NodeIdMap NodeIdMap; function_requires >(); NodeIdMap node_map(graph); int n = node_map.maxId(); ignore_unused_variable_warning(n); } } Graph& graph; }; class MappableGraphComponent : virtual public BaseGraphComponent { public: typedef MappableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; template class NodeMap : public ReferenceMap { public: NodeMap(const Graph&) {} NodeMap(const Graph&, const Value&) {} NodeMap(const NodeMap&) {} NodeMap& operator=(const NodeMap&) { return *this;} }; template class EdgeMap : public ReferenceMap { public: EdgeMap(const Graph&) {} EdgeMap(const Graph&, const Value&) {} EdgeMap(const EdgeMap&) {} EdgeMap& operator=(const EdgeMap&) { return *this;} }; }; template struct MappableGraphComponentConcept { struct Type { int value; Type() : value(0) {} Type(int _v) : value(_v) {} }; void constraints() { function_requires< BaseGraphComponentConcept >(); { // int map test typedef typename Graph::template NodeMap IntNodeMap; function_requires >(); } { // bool map test typedef typename Graph::template NodeMap BoolNodeMap; function_requires >(); } { // Type map test typedef typename Graph::template NodeMap TypeNodeMap; function_requires >(); } { // int map test typedef typename Graph::template EdgeMap IntEdgeMap; function_requires >(); } { // bool map test typedef typename Graph::template EdgeMap BoolEdgeMap; function_requires >(); } { // Type map test typedef typename Graph::template EdgeMap TypeEdgeMap; function_requires >(); } } 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 ExtendableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); 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 ErasableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); typename Graph::Node node; graph.erase(node); typename Graph::Edge edge; graph.erase(edge); } Graph& graph; }; class ClearableGraphComponent : virtual public BaseGraphComponent { public: typedef ClearableGraphComponent Graph; typedef BaseGraphComponent::Node Node; typedef BaseGraphComponent::Edge Edge; void clear() {} }; template struct ClearableGraphComponentConcept { void constraints() { function_requires< BaseGraphComponentConcept >(); graph.clear(); } Graph& graph; }; } } #endif