# HG changeset patch # User deba # Date 1162305672 0 # Node ID 1ef281b2b10e645599ee275af98217ae66a82187 # Parent 8c5c4b5ae31c7e32d89f52def67ebac7b0b107b4 The implementation of the graph copy is changed Make explicit more constructors diff -r 8c5c4b5ae31c -r 1ef281b2b10e lemon/graph_utils.h --- a/lemon/graph_utils.h Tue Oct 31 14:31:13 2006 +0000 +++ b/lemon/graph_utils.h Tue Oct 31 14:41:12 2006 +0000 @@ -83,9 +83,6 @@ typedef Graph:: UEdge UEdge; \ typedef Graph:: UEdgeIt UEdgeIt; \ typedef Graph:: IncEdgeIt IncEdgeIt; -// typedef Graph::template UEdgeMap BoolUEdgeMap; -// typedef Graph::template UEdgeMap IntUEdgeMap; -// typedef Graph::template UEdgeMap DoubleUEdgeMap; ///\brief Creates convenience typedefs for the bipartite undirected graph ///types and iterators @@ -103,6 +100,8 @@ ///template typedefs in C++. #define BPUGRAPH_TYPEDEFS(Graph) \ UGRAPH_TYPEDEFS(Graph) \ + typedef Graph::ANode ANode; \ + typedef Graph::BNode BNode; \ typedef Graph::ANodeIt ANodeIt; \ typedef Graph::BNodeIt BNodeIt; @@ -379,10 +378,9 @@ ///\se AllEdgeLookup ///\sa ConEdgeIt template - inline typename Graph::Edge findEdge(const Graph &g, - typename Graph::Node u, - typename Graph::Node v, - typename Graph::Edge prev = INVALID) { + inline typename Graph::Edge + findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v, + typename Graph::Edge prev = INVALID) { return _graph_utils_bits::FindEdgeSelector::find(g, u, v, prev); } @@ -506,10 +504,9 @@ ///\sa ConEdgeIt template - inline typename Graph::UEdge findUEdge(const Graph &g, - typename Graph::Node u, - typename Graph::Node v, - typename Graph::UEdge p = INVALID) { + inline typename Graph::UEdge + findUEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v, + typename Graph::UEdge p = INVALID) { return _graph_utils_bits::FindUEdgeSelector::find(g, u, v, p); } @@ -588,79 +585,133 @@ } } + namespace _graph_utils_bits { + + template + class MapCopyBase { + public: + virtual void copy(const Graph& source, const RefMap& refMap) = 0; + + virtual ~MapCopyBase() {} + }; + + template + class MapCopy : public MapCopyBase { + public: + + MapCopy(TargetMap& tmap, const SourceMap& map) + : _tmap(tmap), _map(map) {} + + virtual void copy(const Graph& graph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(graph); it != INVALID; ++it) { + _tmap.set(refMap[it], _map[it]); + } + } + + private: + TargetMap& _tmap; + const SourceMap& _map; + }; + + template + class RefCopy : public MapCopyBase { + public: + + RefCopy(Ref& map) : _map(map) {} + + virtual void copy(const Graph& graph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(graph); it != INVALID; ++it) { + _map.set(it, refMap[it]); + } + } + + private: + Ref& _map; + }; + + template + class CrossRefCopy : public MapCopyBase { + public: + + CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {} + + virtual void copy(const Graph& graph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(graph); it != INVALID; ++it) { + _cmap.set(refMap[it], it); + } + } + + private: + CrossRef& _cmap; + }; + + } + /// \brief Class to copy a graph. /// /// Class to copy a graph to another graph (duplicate a graph). The /// simplest way of using it is through the \c copyGraph() function. template class GraphCopy { - public: + private: + typedef typename Source::Node Node; typedef typename Source::NodeIt NodeIt; typedef typename Source::Edge Edge; typedef typename Source::EdgeIt EdgeIt; - typedef typename Source::template NodeMapNodeRefMap; - typedef typename Source::template EdgeMapEdgeRefMap; + typedef typename Target::Node TNode; + typedef typename Target::Edge TEdge; + + typedef typename Source::template NodeMap NodeRefMap; + typedef typename Source::template EdgeMap EdgeRefMap; + + + public: + /// \brief Constructor for the GraphCopy. /// /// It copies the content of the \c _source graph into the - /// \c _target graph. It creates also two references, one beetween - /// the two nodeset and one beetween the two edgesets. + /// \c _target graph. GraphCopy(Target& _target, const Source& _source) - : source(_source), target(_target), - nodeRefMap(_source), edgeRefMap(_source) { - for (NodeIt it(source); it != INVALID; ++it) { - nodeRefMap[it] = target.addNode(); + : source(_source), target(_target) {} + + /// \brief Destructor of the GraphCopy + /// + /// Destructor of the GraphCopy + ~GraphCopy() { + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + delete nodeMapCopies[i]; } - for (EdgeIt it(source); it != INVALID; ++it) { - edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], - nodeRefMap[source.target(it)]); + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + delete edgeMapCopies[i]; } + } /// \brief Copies the node references into the given map. /// /// Copies the node references into the given map. template - const GraphCopy& nodeRef(NodeRef& map) const { - for (NodeIt it(source); it != INVALID; ++it) { - map.set(it, nodeRefMap[it]); - } + GraphCopy& nodeRef(NodeRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); return *this; } /// \brief Reverse and copies the node references into the given map. /// /// Reverse and copies the node references into the given map. - template - const GraphCopy& nodeCrossRef(NodeRef& map) const { - for (NodeIt it(source); it != INVALID; ++it) { - map.set(nodeRefMap[it], it); - } - return *this; - } - - /// \brief Copies the edge references into the given map. - /// - /// Copies the edge references into the given map. - template - const GraphCopy& edgeRef(EdgeRef& map) const { - for (EdgeIt it(source); it != INVALID; ++it) { - map.set(it, edgeRefMap[it]); - } - return *this; - } - - /// \brief Reverse and copies the edge references into the given map. - /// - /// Reverse and copies the edge references into the given map. - template - const GraphCopy& edgeCrossRef(EdgeRef& map) const { - for (EdgeIt it(source); it != INVALID; ++it) { - map.set(edgeRefMap[it], it); - } + template + GraphCopy& nodeCrossRef(NodeCrossRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); return *this; } @@ -671,8 +722,29 @@ /// and the copied map's key type is the source graph's node /// type. template - const GraphCopy& nodeMap(TargetMap& tMap, const SourceMap& sMap) const { - copyMap(tMap, sMap, NodeIt(source), nodeRefMap); + GraphCopy& nodeMap(TargetMap& tmap, const SourceMap& map) { + nodeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Copies the edge references into the given map. + /// + /// Copies the edge references into the given map. + template + GraphCopy& edgeRef(EdgeRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Reverse and copies the edge references into the given map. + /// + /// Reverse and copies the edge references into the given map. + template + GraphCopy& edgeCrossRef(EdgeCrossRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); return *this; } @@ -683,34 +755,44 @@ /// and the copied map's key type is the source graph's edge /// type. template - const GraphCopy& edgeMap(TargetMap& tMap, const SourceMap& sMap) const { - copyMap(tMap, sMap, EdgeIt(source), edgeRefMap); + GraphCopy& edgeMap(TargetMap& tmap, const SourceMap& map) { + edgeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); return *this; } - /// \brief Gives back the stored node references. + /// \brief Executes the copies. /// - /// Gives back the stored node references. - const NodeRefMap& nodeRef() const { - return nodeRefMap; + /// Executes the copies. + void run() { + NodeRefMap nodeRefMap(source); + for (NodeIt it(source); it != INVALID; ++it) { + nodeRefMap[it] = target.addNode(); + } + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + nodeMapCopies[i]->copy(source, nodeRefMap); + } + EdgeRefMap edgeRefMap(source); + for (EdgeIt it(source); it != INVALID; ++it) { + edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], + nodeRefMap[source.target(it)]); + } + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + edgeMapCopies[i]->copy(source, edgeRefMap); + } } - /// \brief Gives back the stored edge references. - /// - /// Gives back the stored edge references. - const EdgeRefMap& edgeRef() const { - return edgeRefMap; - } - - void run() const {} - private: const Source& source; Target& target; - NodeRefMap nodeRefMap; - EdgeRefMap edgeRefMap; + std::vector<_graph_utils_bits::MapCopyBase* > + nodeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + edgeMapCopies; + }; /// \brief Copy a graph to another graph. @@ -719,7 +801,7 @@ /// The usage of the function: /// ///\code - /// copyGraph(trg, src).nodeRef(nr).edgeCrossRef(ecr); + /// copyGraph(trg, src).nodeRef(nr).edgeCrossRef(ecr).run(); ///\endcode /// /// After the copy the \c nr map will contain the mapping from the @@ -737,7 +819,8 @@ /// The simplest way of using it is through the \c copyUGraph() function. template class UGraphCopy { - public: + private: + typedef typename Source::Node Node; typedef typename Source::NodeIt NodeIt; typedef typename Source::Edge Edge; @@ -745,111 +828,79 @@ typedef typename Source::UEdge UEdge; typedef typename Source::UEdgeIt UEdgeIt; - typedef typename Source:: - template NodeMap NodeRefMap; - - typedef typename Source:: - template UEdgeMap UEdgeRefMap; + typedef typename Target::Node TNode; + typedef typename Target::Edge TEdge; + typedef typename Target::UEdge TUEdge; - private: + typedef typename Source::template NodeMap NodeRefMap; + typedef typename Source::template UEdgeMap UEdgeRefMap; struct EdgeRefMap { - EdgeRefMap(UGraphCopy& _gc) : gc(_gc) {} + EdgeRefMap(const Target& _target, const Source& _source, + const UEdgeRefMap& _uedge_ref, const NodeRefMap& _node_ref) + : target(_target), source(_source), + uedge_ref(_uedge_ref), node_ref(_node_ref) {} + typedef typename Source::Edge Key; typedef typename Target::Edge Value; - Value operator[](const Key& key) { - return gc.target.direct(gc.uEdgeRef[key], - gc.target.direction(key)); + Value operator[](const Key& key) const { + bool forward = (source.direction(key) == + (node_ref[source.source((UEdge)key)] == + target.source(uedge_ref[(UEdge)key]))); + return target.direct(uedge_ref[key], forward); } - UGraphCopy& gc; + const Target& target; + const Source& source; + const UEdgeRefMap& uedge_ref; + const NodeRefMap& node_ref; }; + - public: + public: - /// \brief Constructor for the UGraphCopy. + + /// \brief Constructor for the GraphCopy. /// /// It copies the content of the \c _source graph into the - /// \c _target graph. It creates also two references, one beetween - /// the two nodeset and one beetween the two edgesets. + /// \c _target graph. UGraphCopy(Target& _target, const Source& _source) - : source(_source), target(_target), - nodeRefMap(_source), edgeRefMap(*this), uEdgeRefMap(_source) { - for (NodeIt it(source); it != INVALID; ++it) { - nodeRefMap[it] = target.addNode(); + : source(_source), target(_target) {} + + /// \brief Destructor of the GraphCopy + /// + /// Destructor of the GraphCopy + ~UGraphCopy() { + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + delete nodeMapCopies[i]; } - for (UEdgeIt it(source); it != INVALID; ++it) { - uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], - nodeRefMap[source.target(it)]); + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + delete edgeMapCopies[i]; } + for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) { + delete uEdgeMapCopies[i]; + } + } /// \brief Copies the node references into the given map. /// /// Copies the node references into the given map. template - const UGraphCopy& nodeRef(NodeRef& map) const { - for (NodeIt it(source); it != INVALID; ++it) { - map.set(it, nodeRefMap[it]); - } + UGraphCopy& nodeRef(NodeRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); return *this; } /// \brief Reverse and copies the node references into the given map. /// /// Reverse and copies the node references into the given map. - template - const UGraphCopy& nodeCrossRef(NodeRef& map) const { - for (NodeIt it(source); it != INVALID; ++it) { - map.set(nodeRefMap[it], it); - } - return *this; - } - - /// \brief Copies the edge references into the given map. - /// - /// Copies the edge references into the given map. - template - const UGraphCopy& edgeRef(EdgeRef& map) const { - for (EdgeIt it(source); it != INVALID; ++it) { - map.set(edgeRefMap[it], it); - } - return *this; - } - - /// \brief Reverse and copies the undirected edge references into the - /// given map. - /// - /// Reverse and copies the undirected edge references into the given map. - template - const UGraphCopy& edgeCrossRef(EdgeRef& map) const { - for (EdgeIt it(source); it != INVALID; ++it) { - map.set(it, edgeRefMap[it]); - } - return *this; - } - - /// \brief Copies the undirected edge references into the given map. - /// - /// Copies the undirected edge references into the given map. - template - const UGraphCopy& uEdgeRef(EdgeRef& map) const { - for (UEdgeIt it(source); it != INVALID; ++it) { - map.set(it, uEdgeRefMap[it]); - } - return *this; - } - - /// \brief Reverse and copies the undirected edge references into the - /// given map. - /// - /// Reverse and copies the undirected edge references into the given map. - template - const UGraphCopy& uEdgeCrossRef(EdgeRef& map) const { - for (UEdgeIt it(source); it != INVALID; ++it) { - map.set(uEdgeRefMap[it], it); - } + template + UGraphCopy& nodeCrossRef(NodeCrossRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); return *this; } @@ -860,9 +911,29 @@ /// and the copied map's key type is the source graph's node /// type. template - const UGraphCopy& nodeMap(TargetMap& tMap, - const SourceMap& sMap) const { - copyMap(tMap, sMap, NodeIt(source), nodeRefMap); + UGraphCopy& nodeMap(TargetMap& tmap, const SourceMap& map) { + nodeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Copies the edge references into the given map. + /// + /// Copies the edge references into the given map. + template + UGraphCopy& edgeRef(EdgeRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Reverse and copies the edge references into the given map. + /// + /// Reverse and copies the edge references into the given map. + template + UGraphCopy& edgeCrossRef(EdgeCrossRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); return *this; } @@ -873,56 +944,84 @@ /// and the copied map's key type is the source graph's edge /// type. template - const UGraphCopy& edgeMap(TargetMap& tMap, - const SourceMap& sMap) const { - copyMap(tMap, sMap, EdgeIt(source), edgeRefMap); + UGraphCopy& edgeMap(TargetMap& tmap, const SourceMap& map) { + edgeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Copies the uEdge references into the given map. + /// + /// Copies the uEdge references into the given map. + template + UGraphCopy& uEdgeRef(UEdgeRef& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Reverse and copies the uEdge references into the given map. + /// + /// Reverse and copies the uEdge references into the given map. + template + UGraphCopy& uEdgeCrossRef(UEdgeCrossRef& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); return *this; } /// \brief Make copy of the given map. /// /// Makes copy of the given map for the newly created graph. - /// The new map's key type is the target graph's edge type, - /// and the copied map's key type is the source graph's edge + /// The new map's key type is the target graph's uEdge type, + /// and the copied map's key type is the source graph's uEdge /// type. template - const UGraphCopy& uEdgeMap(TargetMap& tMap, - const SourceMap& sMap) const { - copyMap(tMap, sMap, UEdgeIt(source), uEdgeRefMap); + UGraphCopy& uEdgeMap(TargetMap& tmap, const SourceMap& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); return *this; } - /// \brief Gives back the stored node references. + /// \brief Executes the copies. /// - /// Gives back the stored node references. - const NodeRefMap& nodeRef() const { - return nodeRefMap; + /// Executes the copies. + void run() { + NodeRefMap nodeRefMap(source); + for (NodeIt it(source); it != INVALID; ++it) { + nodeRefMap[it] = target.addNode(); + } + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + nodeMapCopies[i]->copy(source, nodeRefMap); + } + UEdgeRefMap uEdgeRefMap(source); + EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap); + for (UEdgeIt it(source); it != INVALID; ++it) { + uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], + nodeRefMap[source.target(it)]); + } + for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) { + uEdgeMapCopies[i]->copy(source, uEdgeRefMap); + } + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + edgeMapCopies[i]->copy(source, edgeRefMap); + } } - /// \brief Gives back the stored edge references. - /// - /// Gives back the stored edge references. - const EdgeRefMap& edgeRef() const { - return edgeRefMap; - } - - /// \brief Gives back the stored uedge references. - /// - /// Gives back the stored uedge references. - const UEdgeRefMap& uEdgeRef() const { - return uEdgeRefMap; - } - - void run() const {} - private: const Source& source; Target& target; - NodeRefMap nodeRefMap; - EdgeRefMap edgeRefMap; - UEdgeRefMap uEdgeRefMap; + std::vector<_graph_utils_bits::MapCopyBase* > + nodeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + edgeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + uEdgeMapCopies; + }; /// \brief Copy a graph to another graph. @@ -931,7 +1030,7 @@ /// The usage of the function: /// ///\code - /// copyUGraph(trg, src).nodeRef(nr).edgeCrossRef(ecr); + /// copyUGraph(trg, src).nodeRef(nr).edgeCrossRef(ecr).run(); ///\endcode /// /// After the copy the \c nr map will contain the mapping from the @@ -971,7 +1070,7 @@ /// \brief Constructor. /// /// Constructor for creating id map. - IdMap(const Graph& _graph) : graph(&_graph) {} + explicit IdMap(const Graph& _graph) : graph(&_graph) {} /// \brief Gives back the \e id of the item. /// @@ -994,12 +1093,12 @@ /// \brief Constructor. /// /// Constructor for creating an id-to-item map. - InverseMap(const Graph& _graph) : graph(&_graph) {} + explicit InverseMap(const Graph& _graph) : graph(&_graph) {} /// \brief Constructor. /// /// Constructor for creating an id-to-item map. - InverseMap(const IdMap& idMap) : graph(idMap.graph) {} + explicit InverseMap(const IdMap& idMap) : graph(idMap.graph) {} /// \brief Gives back the given item from its id. /// @@ -1066,7 +1165,7 @@ /// /// Construct a new InvertableMap for the graph. /// - InvertableMap(const Graph& graph) : Map(graph) {} + explicit InvertableMap(const Graph& graph) : Map(graph) {} /// \brief Forward iterator for values. /// @@ -1192,7 +1291,8 @@ /// \brief Constructor of the InverseMap. /// /// Constructor of the InverseMap. - InverseMap(const InvertableMap& _inverted) : inverted(_inverted) {} + explicit InverseMap(const InvertableMap& _inverted) + : inverted(_inverted) {} /// The value type of the InverseMap. typedef typename InvertableMap::Key Value; @@ -1264,7 +1364,7 @@ /// \brief Constructor. /// /// Constructor for descriptor map. - DescriptorMap(const Graph& _graph) : Map(_graph) { + explicit DescriptorMap(const Graph& _graph) : Map(_graph) { Item it; const typename Map::Notifier* notifier = Map::getNotifier(); for (notifier->first(it); it != INVALID; notifier->next(it)) { @@ -1273,6 +1373,7 @@ } } + protected: /// \brief Add a new key to the map. @@ -1386,7 +1487,7 @@ /// \brief Constructor of the InverseMap. /// /// Constructor of the InverseMap. - InverseMap(const DescriptorMap& _inverted) + explicit InverseMap(const DescriptorMap& _inverted) : inverted(_inverted) {} @@ -1437,7 +1538,7 @@ /// /// Constructor /// \param _graph The graph that the map belongs to. - SourceMap(const Graph& _graph) : graph(_graph) {} + explicit SourceMap(const Graph& _graph) : graph(_graph) {} /// \brief The subscript operator. /// @@ -1476,7 +1577,7 @@ /// /// Constructor /// \param _graph The graph that the map belongs to. - TargetMap(const Graph& _graph) : graph(_graph) {} + explicit TargetMap(const Graph& _graph) : graph(_graph) {} /// \brief The subscript operator. /// @@ -1515,7 +1616,7 @@ /// /// Constructor /// \param _graph The graph that the map belongs to. - ForwardMap(const Graph& _graph) : graph(_graph) {} + explicit ForwardMap(const Graph& _graph) : graph(_graph) {} /// \brief The subscript operator. /// @@ -1554,7 +1655,7 @@ /// /// Constructor /// \param _graph The graph that the map belongs to. - BackwardMap(const Graph& _graph) : graph(_graph) {} + explicit BackwardMap(const Graph& _graph) : graph(_graph) {} /// \brief The subscript operator. /// @@ -1592,7 +1693,8 @@ /// \brief Constructor /// /// Contructor of the map - PotentialDifferenceMap(const Graph& _graph, const NodeMap& _potential) + explicit PotentialDifferenceMap(const Graph& _graph, + const NodeMap& _potential) : graph(_graph), potential(_potential) {} /// \brief Const subscription operator @@ -1676,7 +1778,7 @@ /// \brief Constructor. /// /// Constructor for creating in-degree map. - InDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { + explicit InDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { Parent::attach(graph.getNotifier(typename _Graph::Edge())); for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) { @@ -1788,7 +1890,7 @@ /// \brief Constructor. /// /// Constructor for creating out-degree map. - OutDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { + explicit OutDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { Parent::attach(graph.getNotifier(typename _Graph::Edge())); for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) {