# HG changeset patch # User Balazs Dezso # Date 1322726747 -3600 # Node ID c8fa41fcc4a70873b604e769c68110949cb6e75b # Parent b84e68af824820f7312cabd9da201c1600d69642 Type safe red and blue node set (#69) diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/bits/graph_extender.h --- a/lemon/bits/graph_extender.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/bits/graph_extender.h Thu Dec 01 09:05:47 2011 +0100 @@ -760,55 +760,17 @@ typedef True UndirectedTag; typedef typename Parent::Node Node; + typedef typename Parent::RedNode RedNode; + typedef typename Parent::BlueNode BlueNode; typedef typename Parent::Arc Arc; typedef typename Parent::Edge Edge; // BpGraph extension - class RedNode : public Node { - public: - RedNode() {} - RedNode(const RedNode& node) : Node(node) {} - RedNode(Invalid) : Node(INVALID){} - RedNode(const Node& node) : Node(node) {} - }; - class BlueNode : public Node { - public: - BlueNode() {} - BlueNode(const BlueNode& node) : Node(node) {} - BlueNode(Invalid) : Node(INVALID){} - BlueNode(const Node& node) : Node(node) {} - }; - using Parent::first; using Parent::next; - - void first(RedNode& node) const { - Parent::firstRed(node); - } - - void next(RedNode& node) const { - Parent::nextRed(node); - } - - void first(BlueNode& node) const { - Parent::firstBlue(node); - } - - void next(BlueNode& node) const { - Parent::nextBlue(node); - } - using Parent::id; - int id(const RedNode& node) const { - return Parent::redId(node); - } - - int id(const BlueNode& node) const { - return Parent::blueId(node); - } - int maxId(Node) const { return Parent::maxNodeId(); } @@ -862,6 +824,32 @@ return Parent::direct(edge, Parent::redNode(edge) == node); } + RedNode asRedNode(const Node& node) const { + if (node == INVALID || Parent::blue(node)) { + return INVALID; + } else { + return Parent::asRedNodeUnsafe(node); + } + } + + BlueNode asBlueNode(const Node& node) const { + if (node == INVALID || Parent::red(node)) { + return INVALID; + } else { + return Parent::asBlueNodeUnsafe(node); + } + } + + std::pair asRedBlueNode(const Node& node) const { + if (node == INVALID) { + return std::make_pair(RedNode(INVALID), BlueNode(INVALID)); + } else if (Parent::red(node)) { + return std::make_pair(Parent::asRedNodeUnsafe(node), BlueNode(INVALID)); + } else { + return std::make_pair(RedNode(INVALID), Parent::asBlueNodeUnsafe(node)); + } + } + // Alterable extension typedef AlterationNotifier NodeNotifier; @@ -925,49 +913,45 @@ }; - class RedIt : public Node { + class RedIt : public RedNode { const BpGraph* _graph; public: RedIt() {} - RedIt(Invalid i) : Node(i) { } + RedIt(Invalid i) : RedNode(i) { } explicit RedIt(const BpGraph& graph) : _graph(&graph) { - _graph->firstRed(static_cast(*this)); + _graph->first(static_cast(*this)); } - RedIt(const BpGraph& graph, const Node& node) - : Node(node), _graph(&graph) { - LEMON_DEBUG(_graph->red(node), "Node has to be red."); - } + RedIt(const BpGraph& graph, const RedNode& node) + : RedNode(node), _graph(&graph) {} RedIt& operator++() { - _graph->nextRed(*this); + _graph->next(static_cast(*this)); return *this; } }; - class BlueIt : public Node { + class BlueIt : public BlueNode { const BpGraph* _graph; public: BlueIt() {} - BlueIt(Invalid i) : Node(i) { } + BlueIt(Invalid i) : BlueNode(i) { } explicit BlueIt(const BpGraph& graph) : _graph(&graph) { - _graph->firstBlue(static_cast(*this)); + _graph->first(static_cast(*this)); } - BlueIt(const BpGraph& graph, const Node& node) - : Node(node), _graph(&graph) { - LEMON_DEBUG(_graph->blue(node), "Node has to be blue."); - } + BlueIt(const BpGraph& graph, const BlueNode& node) + : BlueNode(node), _graph(&graph) {} BlueIt& operator++() { - _graph->nextBlue(*this); + _graph->next(static_cast(*this)); return *this; } @@ -1258,21 +1242,21 @@ // Alteration extension - Node addRedNode() { - Node node = Parent::addRedNode(); + RedNode addRedNode() { + RedNode node = Parent::addRedNode(); notifier(RedNode()).add(node); notifier(Node()).add(node); return node; } - Node addBlueNode() { - Node node = Parent::addBlueNode(); + BlueNode addBlueNode() { + BlueNode node = Parent::addBlueNode(); notifier(BlueNode()).add(node); notifier(Node()).add(node); return node; } - Edge addEdge(const Node& from, const Node& to) { + Edge addEdge(const RedNode& from, const BlueNode& to) { Edge edge = Parent::addEdge(from, to); notifier(Edge()).add(edge); std::vector av; @@ -1317,9 +1301,9 @@ } if (Parent::red(node)) { - notifier(RedNode()).erase(node); + notifier(RedNode()).erase(this->asRedNodeUnsafe(node)); } else { - notifier(BlueNode()).erase(node); + notifier(BlueNode()).erase(this->asBlueNodeUnsafe(node)); } notifier(Node()).erase(node); diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/concepts/bpgraph.h --- a/lemon/concepts/bpgraph.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/concepts/bpgraph.h Thu Dec 01 09:05:47 2011 +0100 @@ -149,12 +149,6 @@ /// \sa Invalid for more details. RedNode(Invalid) { } - /// Constructor for conversion from a node. - - /// Constructor for conversion from a node. The conversion can - /// be invalid, since the Node can be member of the blue - /// set. - RedNode(const Node&) {} }; /// Class to represent blue nodes. @@ -182,12 +176,6 @@ /// \sa Invalid for more details. BlueNode(Invalid) { } - /// Constructor for conversion from a node. - - /// Constructor for conversion from a node. The conversion can - /// be invalid, since the Node can be member of the red - /// set. - BlueNode(const Node&) {} }; /// Iterator class for the red nodes. @@ -199,7 +187,7 @@ /// int count=0; /// for (BpGraph::RedNodeIt n(g); n!=INVALID; ++n) ++count; ///\endcode - class RedIt : public Node { + class RedIt : public RedNode { public: /// Default constructor @@ -210,7 +198,7 @@ /// Copy constructor. /// - RedIt(const RedIt& n) : Node(n) { } + RedIt(const RedIt& n) : RedNode(n) { } /// %Invalid constructor \& conversion. /// Initializes the iterator to be invalid. @@ -225,7 +213,7 @@ /// Sets the iterator to the given red node of the given /// digraph. - RedIt(const BpGraph&, const Node&) { } + RedIt(const BpGraph&, const RedNode&) { } /// Next node. /// Assign the iterator to the next red node. @@ -242,7 +230,7 @@ /// int count=0; /// for (BpGraph::BlueNodeIt n(g); n!=INVALID; ++n) ++count; ///\endcode - class BlueIt : public Node { + class BlueIt : public BlueNode { public: /// Default constructor @@ -253,7 +241,7 @@ /// Copy constructor. /// - BlueIt(const BlueIt& n) : Node(n) { } + BlueIt(const BlueIt& n) : BlueNode(n) { } /// %Invalid constructor \& conversion. /// Initializes the iterator to be invalid. @@ -268,7 +256,7 @@ /// Sets the iterator to the given blue node of the given /// digraph. - BlueIt(const BpGraph&, const Node&) { } + BlueIt(const BpGraph&, const BlueNode&) { } /// Next node. /// Assign the iterator to the next blue node. @@ -784,15 +772,54 @@ /// Gives back %true for blue nodes. bool blue(const Node&) const { return true; } + /// \brief Converts the node to red node object. + /// + /// This class is converts unsafely the node to red node + /// object. It should be called only if the node is from the red + /// partition or INVALID. + RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); } + + /// \brief Converts the node to blue node object. + /// + /// This class is converts unsafely the node to blue node + /// object. It should be called only if the node is from the red + /// partition or INVALID. + BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); } + + /// \brief Converts the node to red node object. + /// + /// This class is converts safely the node to red node + /// object. If the node is not from the red partition, then it + /// returns INVALID. + RedNode asRedNode(const Node&) const { return RedNode(); } + + /// \brief Converts the node to blue node object. + /// + /// This class is converts unsafely the node to blue node + /// object. If the node is not from the blue partition, then it + /// returns INVALID. + BlueNode asBlueNode(const Node&) const { return BlueNode(); } + + /// \brief Convert the node to either red or blue node. + /// + /// If the node is from the red partition then it is returned in + /// first and second is INVALID. If the node is from the blue + /// partition then it is returned in second and first is + /// INVALID. If the node INVALID then both first and second are + /// INVALID in the return value. + std::pair asRedBlueNode(const Node&) const { + return std::make_pair(RedNode(), BlueNode()); + } + /// \brief Gives back the red end node of the edge. /// /// Gives back the red end node of the edge. - Node redNode(const Edge&) const { return Node(); } + RedNode redNode(const Edge&) const { return RedNode(); } /// \brief Gives back the blue end node of the edge. /// /// Gives back the blue end node of the edge. - Node blueNode(const Edge&) const { return Node(); } + BlueNode blueNode(const Edge&) const { return BlueNode(); } /// \brief The first node of the edge. /// @@ -822,21 +849,11 @@ /// \brief The red ID of the node. /// /// Returns the red ID of the given node. - int redId(Node) const { return -1; } - - /// \brief The red ID of the node. - /// - /// Returns the red ID of the given node. int id(RedNode) const { return -1; } /// \brief The blue ID of the node. /// /// Returns the blue ID of the given node. - int blueId(Node) const { return -1; } - - /// \brief The blue ID of the node. - /// - /// Returns the blue ID of the given node. int id(BlueNode) const { return -1; } /// \brief The ID of the edge. @@ -928,11 +945,11 @@ void first(Node&) const {} void next(Node&) const {} - void firstRed(Node&) const {} - void nextRed(Node&) const {} + void firstRed(RedNode&) const {} + void nextRed(RedNode&) const {} - void firstBlue(Node&) const {} - void nextBlue(Node&) const {} + void firstBlue(BlueNode&) const {} + void nextBlue(BlueNode&) const {} void first(Edge&) const {} void next(Edge&) const {} diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/concepts/graph_components.h --- a/lemon/concepts/graph_components.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/concepts/graph_components.h Thu Dec 01 09:05:47 2011 +0100 @@ -317,10 +317,8 @@ /// \brief Class to represent red nodes. /// - /// This class represents the red nodes of the graph. It does - /// not supposed to be used directly, because the nodes can be - /// represented as Node instances. This class can be used as - /// template parameter for special map classes. + /// This class represents the red nodes of the graph. The red + /// nodes can be used also as normal nodes. class RedNode : public Node { typedef Node Parent; @@ -344,21 +342,12 @@ /// It initializes the item to be invalid. /// \sa Invalid for more details. RedNode(Invalid) {} - - /// \brief Constructor for conversion from a node. - /// - /// Constructor for conversion from a node. The conversion can - /// be invalid, since the Node can be member of the blue - /// set. - RedNode(const Node&) {} }; /// \brief Class to represent blue nodes. /// - /// This class represents the blue nodes of the graph. It does - /// not supposed to be used directly, because the nodes can be - /// represented as Node instances. This class can be used as - /// template parameter for special map classes. + /// This class represents the blue nodes of the graph. The blue + /// nodes can be used also as normal nodes. class BlueNode : public Node { typedef Node Parent; @@ -404,12 +393,51 @@ /// \brief Gives back the red end node of the edge. /// /// Gives back the red end node of the edge. - Node redNode(const Edge&) const { return Node(); } + RedNode redNode(const Edge&) const { return RedNode(); } /// \brief Gives back the blue end node of the edge. /// /// Gives back the blue end node of the edge. - Node blueNode(const Edge&) const { return Node(); } + BlueNode blueNode(const Edge&) const { return BlueNode(); } + + /// \brief Converts the node to red node object. + /// + /// This class is converts unsafely the node to red node + /// object. It should be called only if the node is from the red + /// partition or INVALID. + RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); } + + /// \brief Converts the node to blue node object. + /// + /// This class is converts unsafely the node to blue node + /// object. It should be called only if the node is from the red + /// partition or INVALID. + BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); } + + /// \brief Converts the node to red node object. + /// + /// This class is converts safely the node to red node + /// object. If the node is not from the red partition, then it + /// returns INVALID. + RedNode asRedNode(const Node&) const { return RedNode(); } + + /// \brief Converts the node to blue node object. + /// + /// This class is converts unsafely the node to blue node + /// object. If the node is not from the blue partition, then it + /// returns INVALID. + BlueNode asBlueNode(const Node&) const { return BlueNode(); } + + /// \brief Convert the node to either red or blue node. + /// + /// If the node is from the red partition then it is returned in + /// first and second is INVALID. If the node is from the blue + /// partition then it is returned in second and first is + /// INVALID. If the node INVALID then both first and second are + /// INVALID in the return value. + std::pair asRedBlueNode(const Node&) const { + return std::make_pair(RedNode(), BlueNode()); + } template struct Constraints { @@ -425,17 +453,22 @@ checkConcept, BlueNode>(); { Node n; - RedNode rn = n; - BlueNode bn = bn; + RedNode rn; + BlueNode bn; + Node rnan = rn; + Node bnan = bn; Edge e; bool b; - b = bpgraph.red(n); - b = bpgraph.blue(n); - ignore_unused_variable_warning(b); - n = bpgraph.redNode(e); - n = bpgraph.blueNode(e); - rn = n; - bn = n; + b = bpgraph.red(rnan); + b = bpgraph.blue(bnan); + rn = bpgraph.redNode(e); + bn = bpgraph.blueNode(e); + rn = bpgraph.asRedNodeUnsafe(rnan); + bn = bpgraph.asBlueNodeUnsafe(bnan); + rn = bpgraph.asRedNode(rnan); + bn = bpgraph.asBlueNode(bnan); + std::pair p = bpgraph.asRedBlueNode(rnan); + ignore_unused_variable_warning(b,p); } } @@ -599,21 +632,11 @@ /// \brief Return a unique integer id for the given node in the red set. /// /// Return a unique integer id for the given node in the red set. - int redId(const Node&) const { return -1; } - - /// \brief Return the same value as redId(). - /// - /// Return the same value as redId(). int id(const RedNode&) const { return -1; } /// \brief Return a unique integer id for the given node in the blue set. /// /// Return a unique integer id for the given node in the blue set. - int blueId(const Node&) const { return -1; } - - /// \brief Return the same value as blueId(). - /// - /// Return the same value as blueId(). int id(const BlueNode&) const { return -1; } /// \brief Return an integer greater or equal to the maximum @@ -638,10 +661,8 @@ typename _BpGraph::Node node; typename _BpGraph::RedNode red; typename _BpGraph::BlueNode blue; - int rid = bpgraph.redId(node); - int bid = bpgraph.blueId(node); - rid = bpgraph.id(red); - bid = bpgraph.id(blue); + int rid = bpgraph.id(red); + int bid = bpgraph.id(blue); rid = bpgraph.maxRedId(); bid = bpgraph.maxBlueId(); ignore_unused_variable_warning(rid); @@ -1137,11 +1158,15 @@ typedef BAS Base; typedef typename Base::Node Node; + typedef typename Base::RedNode RedNode; + typedef typename Base::BlueNode BlueNode; typedef typename Base::Arc Arc; typedef typename Base::Edge Edge; + + typedef IterableBpGraphComponent BpGraph; - - typedef IterableBpGraphComponent BpGraph; + using IterableGraphComponent::first; + using IterableGraphComponent::next; /// \name Base Iteration /// @@ -1152,22 +1177,22 @@ /// \brief Return the first red node. /// /// This function gives back the first red node in the iteration order. - void firstRed(Node&) const {} + void first(RedNode&) const {} /// \brief Return the next red node. /// /// This function gives back the next red node in the iteration order. - void nextRed(Node&) const {} + void next(RedNode&) const {} /// \brief Return the first blue node. /// /// This function gives back the first blue node in the iteration order. - void firstBlue(Node&) const {} + void first(BlueNode&) const {} /// \brief Return the next blue node. /// /// This function gives back the next blue node in the iteration order. - void nextBlue(Node&) const {} + void next(BlueNode&) const {} /// @} @@ -1181,12 +1206,12 @@ /// \brief This iterator goes through each red node. /// /// This iterator goes through each red node. - typedef GraphItemIt RedIt; + typedef GraphItemIt RedIt; /// \brief This iterator goes through each blue node. /// /// This iterator goes through each blue node. - typedef GraphItemIt BlueIt; + typedef GraphItemIt BlueIt; /// @} @@ -1195,15 +1220,16 @@ void constraints() { checkConcept, _BpGraph>(); - typename _BpGraph::Node node(INVALID); - bpgraph.firstRed(node); - bpgraph.nextRed(node); - bpgraph.firstBlue(node); - bpgraph.nextBlue(node); + typename _BpGraph::RedNode rn(INVALID); + bpgraph.first(rn); + bpgraph.next(rn); + typename _BpGraph::BlueNode bn(INVALID); + bpgraph.first(bn); + bpgraph.next(bn); - checkConcept, + checkConcept, typename _BpGraph::RedIt>(); - checkConcept, + checkConcept, typename _BpGraph::BlueIt>(); } @@ -1790,29 +1816,29 @@ { // int map test typedef typename _BpGraph::template RedMap IntRedMap; - checkConcept, + checkConcept, IntRedMap >(); } { // bool map test typedef typename _BpGraph::template RedMap BoolRedMap; - checkConcept, + checkConcept, BoolRedMap >(); } { // Dummy map test typedef typename _BpGraph::template RedMap DummyRedMap; - checkConcept, + checkConcept, DummyRedMap >(); } { // int map test typedef typename _BpGraph::template BlueMap IntBlueMap; - checkConcept, + checkConcept, IntBlueMap >(); } { // bool map test typedef typename _BpGraph::template BlueMap BoolBlueMap; - checkConcept, + checkConcept, BoolBlueMap >(); } { // Dummy map test typedef typename _BpGraph::template BlueMap DummyBlueMap; - checkConcept, + checkConcept, DummyBlueMap >(); } } @@ -1923,19 +1949,21 @@ typedef BAS Base; typedef typename Base::Node Node; + typedef typename Base::RedNode RedNode; + typedef typename Base::BlueNode BlueNode; typedef typename Base::Edge Edge; /// \brief Add a new red node to the digraph. /// /// This function adds a red new node to the digraph. - Node addRedNode() { + RedNode addRedNode() { return INVALID; } /// \brief Add a new blue node to the digraph. /// /// This function adds a blue new node to the digraph. - Node addBlueNode() { + BlueNode addBlueNode() { return INVALID; } @@ -1944,7 +1972,10 @@ /// This function adds a new edge connecting the given two nodes /// of the graph. The first node has to be a red node, and the /// second one a blue node. - Edge addEdge(const Node&, const Node&) { + Edge addEdge(const RedNode&, const BlueNode&) { + return INVALID; + } + Edge addEdge(const BlueNode&, const RedNode&) { return INVALID; } @@ -1952,11 +1983,13 @@ struct Constraints { void constraints() { checkConcept(); - typename _BpGraph::Node red_node, blue_node; + typename _BpGraph::RedNode red_node; + typename _BpGraph::BlueNode blue_node; red_node = bpgraph.addRedNode(); blue_node = bpgraph.addBlueNode(); typename _BpGraph::Edge edge; edge = bpgraph.addEdge(red_node, blue_node); + edge = bpgraph.addEdge(blue_node, red_node); } _BpGraph& bpgraph; diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/core.h --- a/lemon/core.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/core.h Thu Dec 01 09:05:47 2011 +0100 @@ -550,26 +550,30 @@ { template static void copy(const From& from, Graph &to, - NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + NodeRefMap& nodeRefMap, + EdgeRefMap& edgeRefMap) { to.build(from, nodeRefMap, edgeRefMap); } }; template struct BpGraphCopySelector { - template + template static void copy(const From& from, BpGraph &to, - NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + RedNodeRefMap& redNodeRefMap, + BlueNodeRefMap& blueNodeRefMap, + EdgeRefMap& edgeRefMap) { to.clear(); for (typename From::RedIt it(from); it != INVALID; ++it) { - nodeRefMap[it] = to.addRedNode(); + redNodeRefMap[it] = to.addRedNode(); } for (typename From::BlueIt it(from); it != INVALID; ++it) { - nodeRefMap[it] = to.addBlueNode(); + blueNodeRefMap[it] = to.addBlueNode(); } for (typename From::EdgeIt it(from); it != INVALID; ++it) { - edgeRefMap[it] = to.addEdge(nodeRefMap[from.redNode(it)], - nodeRefMap[from.blueNode(it)]); + edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)], + blueNodeRefMap[from.blueNode(it)]); } } }; @@ -579,10 +583,13 @@ BpGraph, typename enable_if::type> { - template + template static void copy(const From& from, BpGraph &to, - NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { - to.build(from, nodeRefMap, edgeRefMap); + RedNodeRefMap& redNodeRefMap, + BlueNodeRefMap& blueNodeRefMap, + EdgeRefMap& edgeRefMap) { + to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap); } }; @@ -1182,12 +1189,38 @@ typedef typename From::EdgeIt EdgeIt; typedef typename To::Node TNode; + typedef typename To::RedNode TRedNode; + typedef typename To::BlueNode TBlueNode; typedef typename To::Arc TArc; typedef typename To::Edge TEdge; - typedef typename From::template NodeMap NodeRefMap; + typedef typename From::template RedMap RedNodeRefMap; + typedef typename From::template BlueMap BlueNodeRefMap; typedef typename From::template EdgeMap EdgeRefMap; + struct NodeRefMap { + NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref, + const BlueNodeRefMap& blue_node_ref) + : _from(from), _red_node_ref(red_node_ref), + _blue_node_ref(blue_node_ref) {} + + typedef typename From::Node Key; + typedef typename To::Node Value; + + Value operator[](const Key& key) const { + std::pair red_blue_pair = _from.asRedBlueNode(key); + if (red_blue_pair.first != INVALID) { + return _red_node_ref[red_blue_pair.first]; + } else { + return _blue_node_ref[red_blue_pair.second]; + } + } + + const From& _from; + const RedNodeRefMap& _red_node_ref; + const BlueNodeRefMap& _blue_node_ref; + }; + struct ArcRefMap { ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref) : _from(from), _to(to), _edge_ref(edge_ref) {} @@ -1292,7 +1325,7 @@ template BpGraphCopy& redRef(RedRef& map) { _red_maps.push_back(new _core_bits::RefCopy(map)); + RedNodeRefMap, RedRef>(map)); return *this; } @@ -1306,7 +1339,7 @@ template BpGraphCopy& redCrossRef(RedCrossRef& map) { _red_maps.push_back(new _core_bits::CrossRefCopy(map)); + RedNodeRefMap, RedCrossRef>(map)); return *this; } @@ -1321,7 +1354,16 @@ template BpGraphCopy& redMap(const FromMap& map, ToMap& tmap) { _red_maps.push_back(new _core_bits::MapCopy(map, tmap)); + RedNodeRefMap, FromMap, ToMap>(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given red node. + /// + /// This function makes a copy of the given red node. + BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) { + _red_maps.push_back(new _core_bits::ItemCopy(node, tnode)); return *this; } @@ -1334,7 +1376,7 @@ template BpGraphCopy& blueRef(BlueRef& map) { _blue_maps.push_back(new _core_bits::RefCopy(map)); + BlueNodeRefMap, BlueRef>(map)); return *this; } @@ -1348,7 +1390,7 @@ template BpGraphCopy& blueCrossRef(BlueCrossRef& map) { _blue_maps.push_back(new _core_bits::CrossRefCopy(map)); + BlueNodeRefMap, BlueCrossRef>(map)); return *this; } @@ -1363,7 +1405,16 @@ template BpGraphCopy& blueMap(const FromMap& map, ToMap& tmap) { _blue_maps.push_back(new _core_bits::MapCopy(map, tmap)); + BlueNodeRefMap, FromMap, ToMap>(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given blue node. + /// + /// This function makes a copy of the given blue node. + BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) { + _blue_maps.push_back(new _core_bits::ItemCopy(node, tnode)); return *this; } @@ -1470,19 +1521,21 @@ /// This function executes the copying of the graph along with the /// copying of the assigned data. void run() { - NodeRefMap nodeRefMap(_from); + RedNodeRefMap redNodeRefMap(_from); + BlueNodeRefMap blueNodeRefMap(_from); + NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap); EdgeRefMap edgeRefMap(_from); ArcRefMap arcRefMap(_from, _to, edgeRefMap); _core_bits::BpGraphCopySelector:: - copy(_from, _to, nodeRefMap, edgeRefMap); + copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap); for (int i = 0; i < int(_node_maps.size()); ++i) { _node_maps[i]->copy(_from, nodeRefMap); } for (int i = 0; i < int(_red_maps.size()); ++i) { - _red_maps[i]->copy(_from, nodeRefMap); + _red_maps[i]->copy(_from, redNodeRefMap); } for (int i = 0; i < int(_blue_maps.size()); ++i) { - _blue_maps[i]->copy(_from, nodeRefMap); + _blue_maps[i]->copy(_from, blueNodeRefMap); } for (int i = 0; i < int(_edge_maps.size()); ++i) { _edge_maps[i]->copy(_from, edgeRefMap); @@ -1500,10 +1553,10 @@ std::vector<_core_bits::MapCopyBase* > _node_maps; - std::vector<_core_bits::MapCopyBase* > + std::vector<_core_bits::MapCopyBase* > _red_maps; - std::vector<_core_bits::MapCopyBase* > + std::vector<_core_bits::MapCopyBase* > _blue_maps; std::vector<_core_bits::MapCopyBase* > diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/full_graph.h --- a/lemon/full_graph.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/full_graph.h Thu Dec 01 09:05:47 2011 +0100 @@ -651,6 +651,30 @@ bool operator<(const Node& node) const {return _id < node._id;} }; + class RedNode : public Node { + friend class FullBpGraphBase; + protected: + + explicit RedNode(int pid) : Node(pid) {} + + public: + RedNode() {} + RedNode(const RedNode& node) : Node(node) {} + RedNode(Invalid) : Node(INVALID){} + }; + + class BlueNode : public Node { + friend class FullBpGraphBase; + protected: + + explicit BlueNode(int pid) : Node(pid) {} + + public: + BlueNode() {} + BlueNode(const BlueNode& node) : Node(node) {} + BlueNode(Invalid) : Node(INVALID){} + }; + class Edge { friend class FullBpGraphBase; protected: @@ -717,6 +741,9 @@ bool red(Node n) const { return n._id < _red_num; } bool blue(Node n) const { return n._id >= _red_num; } + static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } + static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } + Node source(Arc a) const { if (a._id & 1) { return Node((a._id >> 1) % _red_num); @@ -732,11 +759,11 @@ } } - Node redNode(Edge e) const { - return Node(e._id % _red_num); + RedNode redNode(Edge e) const { + return RedNode(e._id % _red_num); } - Node blueNode(Edge e) const { - return Node(e._id / _red_num + _red_num); + BlueNode blueNode(Edge e) const { + return BlueNode(e._id / _red_num + _red_num); } static bool direction(Arc a) { @@ -755,20 +782,20 @@ --node._id; } - void firstRed(Node& node) const { + void first(RedNode& node) const { node._id = _red_num - 1; } - static void nextRed(Node& node) { + static void next(RedNode& node) { --node._id; } - void firstBlue(Node& node) const { + void first(BlueNode& node) const { if (_red_num == _node_num) node._id = -1; else node._id = _node_num - 1; } - void nextBlue(Node& node) const { + void next(BlueNode& node) const { if (node._id == _red_num) node._id = -1; else --node._id; } @@ -842,15 +869,9 @@ } } - static int id(Node v) { return v._id; } - int redId(Node v) const { - LEMON_DEBUG(v._id < _red_num, "Node has to be red"); - return v._id; - } - int blueId(Node v) const { - LEMON_DEBUG(v._id >= _red_num, "Node has to be blue"); - return v._id - _red_num; - } + static int id(const Node& v) { return v._id; } + int id(const RedNode& v) const { return v._id; } + int id(const BlueNode& v) const { return v._id - _red_num; } static int id(Arc e) { return e._id; } static int id(Edge e) { return e._id; } @@ -868,19 +889,19 @@ return e._id >= 0 && e._id < _edge_num; } - Node redNode(int index) const { - return Node(index); + RedNode redNode(int index) const { + return RedNode(index); } - int redIndex(Node n) const { + int index(RedNode n) const { return n._id; } - Node blueNode(int index) const { - return Node(index + _red_num); + BlueNode blueNode(int index) const { + return BlueNode(index + _red_num); } - int blueIndex(Node n) const { + int index(BlueNode n) const { return n._id - _red_num; } @@ -1000,7 +1021,7 @@ /// structure is completely static, the red nodes can be indexed /// with integers from the range [0..redNum()-1]. /// \sa redIndex() - Node redNode(int index) const { return Parent::redNode(index); } + RedNode redNode(int index) const { return Parent::redNode(index); } /// \brief Returns the index of the given red node. /// @@ -1009,7 +1030,7 @@ /// integers from the range [0..redNum()-1]. /// /// \sa operator()() - int redIndex(Node node) const { return Parent::redIndex(node); } + int index(RedNode node) const { return Parent::index(node); } /// \brief Returns the blue node with the given index. /// @@ -1017,7 +1038,7 @@ /// structure is completely static, the blue nodes can be indexed /// with integers from the range [0..blueNum()-1]. /// \sa blueIndex() - Node blueNode(int index) const { return Parent::blueNode(index); } + BlueNode blueNode(int index) const { return Parent::blueNode(index); } /// \brief Returns the index of the given blue node. /// @@ -1026,7 +1047,7 @@ /// integers from the range [0..blueNum()-1]. /// /// \sa operator()() - int blueIndex(Node node) const { return Parent::blueIndex(node); } + int index(BlueNode node) const { return Parent::index(node); } /// \brief Returns the edge which connects the given nodes. /// diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/list_graph.h --- a/lemon/list_graph.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/list_graph.h Thu Dec 01 09:05:47 2011 +0100 @@ -1647,6 +1647,30 @@ bool operator<(const Node& node) const {return id < node.id;} }; + class RedNode : public Node { + friend class ListBpGraphBase; + protected: + + explicit RedNode(int pid) : Node(pid) {} + + public: + RedNode() {} + RedNode(const RedNode& node) : Node(node) {} + RedNode(Invalid) : Node(INVALID){} + }; + + class BlueNode : public Node { + friend class ListBpGraphBase; + protected: + + explicit BlueNode(int pid) : Node(pid) {} + + public: + BlueNode() {} + BlueNode(const BlueNode& node) : Node(node) {} + BlueNode(Invalid) : Node(INVALID){} + }; + class Edge { friend class ListBpGraphBase; protected: @@ -1692,6 +1716,9 @@ bool red(Node n) const { return nodes[n.id].red; } bool blue(Node n) const { return !nodes[n.id].red; } + static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); } + static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); } + int maxNodeId() const { return nodes.size()-1; } int maxRedId() const { return max_red; } int maxBlueId() const { return max_blue; } @@ -1701,8 +1728,12 @@ Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } Node target(Arc e) const { return Node(arcs[e.id].target); } - Node redNode(Edge e) const { return Node(arcs[2 * e.id].target); } - Node blueNode(Edge e) const { return Node(arcs[2 * e.id + 1].target); } + RedNode redNode(Edge e) const { + return RedNode(arcs[2 * e.id].target); + } + BlueNode blueNode(Edge e) const { + return BlueNode(arcs[2 * e.id + 1].target); + } static bool direction(Arc e) { return (e.id & 1) == 1; @@ -1720,19 +1751,19 @@ node.id = nodes[node.id].next; } - void firstRed(Node& node) const { + void first(RedNode& node) const { node.id = first_red; } - void nextRed(Node& node) const { + void next(RedNode& node) const { node.id = nodes[node.id].partition_next; } - void firstBlue(Node& node) const { + void first(BlueNode& node) const { node.id = first_blue; } - void nextBlue(Node& node) const { + void next(BlueNode& node) const { node.id = nodes[node.id].partition_next; } @@ -1835,14 +1866,8 @@ } static int id(Node v) { return v.id; } - int redId(Node v) const { - LEMON_DEBUG(nodes[v.id].red, "Node has to be red"); - return nodes[v.id].partition_index; - } - int blueId(Node v) const { - LEMON_DEBUG(!nodes[v.id].red, "Node has to be blue"); - return nodes[v.id].partition_index; - } + int id(RedNode v) const { return nodes[v.id].partition_index; } + int id(BlueNode v) const { return nodes[v.id].partition_index; } static int id(Arc e) { return e.id; } static int id(Edge e) { return e.id; } @@ -1865,7 +1890,7 @@ arcs[2 * e.id].prev_out != -2; } - Node addRedNode() { + RedNode addRedNode() { int n; if(first_free_red==-1) { @@ -1890,10 +1915,10 @@ nodes[n].first_out = -1; - return Node(n); + return RedNode(n); } - Node addBlueNode() { + BlueNode addBlueNode() { int n; if(first_free_blue==-1) { @@ -1918,7 +1943,7 @@ nodes[n].first_out = -1; - return Node(n); + return BlueNode(n); } Edge addEdge(Node u, Node v) { @@ -2029,8 +2054,7 @@ protected: - void changeRed(Edge e, Node n) { - LEMON_DEBUG(nodes[n].red, "Node has to be red"); + void changeRed(Edge e, RedNode n) { if(arcs[(2 * e.id) | 1].next_out != -1) { arcs[arcs[(2 * e.id) | 1].next_out].prev_out = arcs[(2 * e.id) | 1].prev_out; @@ -2052,9 +2076,8 @@ nodes[n.id].first_out = ((2 * e.id) | 1); } - void changeBlue(Edge e, Node n) { - LEMON_DEBUG(nodes[n].red, "Node has to be blue"); - if(arcs[2 * e.id].next_out != -1) { + void changeBlue(Edge e, BlueNode n) { + if(arcs[2 * e.id].next_out != -1) { arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; } if(arcs[2 * e.id].prev_out != -1) { @@ -2119,13 +2142,13 @@ /// /// This function adds a red new node to the graph. /// \return The new node. - Node addRedNode() { return Parent::addRedNode(); } + RedNode addRedNode() { return Parent::addRedNode(); } /// \brief Add a new blue node to the graph. /// /// This function adds a blue new node to the graph. /// \return The new node. - Node addBlueNode() { return Parent::addBlueNode(); } + BlueNode addBlueNode() { return Parent::addBlueNode(); } /// \brief Add a new edge to the graph. /// @@ -2133,7 +2156,10 @@ /// \c u and \c v with inherent orientation from node \c u to /// node \c v. /// \return The new edge. - Edge addEdge(Node u, Node v) { + Edge addEdge(RedNode u, BlueNode v) { + return Parent::addEdge(u, v); + } + Edge addEdge(BlueNode v, RedNode u) { return Parent::addEdge(u, v); } @@ -2188,8 +2214,8 @@ /// ///\warning This functionality cannot be used together with the ///Snapshot feature. - void changeRed(Edge e, Node n) { - Parent::changeRed(e,n); + void changeRed(Edge e, RedNode n) { + Parent::changeRed(e, n); } /// \brief Change the blue node of an edge. /// @@ -2202,8 +2228,8 @@ /// ///\warning This functionality cannot be used together with the ///Snapshot feature. - void changeBlue(Edge e, Node n) { - Parent::changeBlue(e,n); + void changeBlue(Edge e, BlueNode n) { + Parent::changeBlue(e, n); } ///Clear the graph. diff -r b84e68af8248 -r c8fa41fcc4a7 lemon/smart_graph.h --- a/lemon/smart_graph.h Thu Nov 25 22:45:29 2010 +0100 +++ b/lemon/smart_graph.h Thu Dec 01 09:05:47 2011 +0100 @@ -854,6 +854,30 @@ bool operator<(const Node& node) const {return _id < node._id;} }; + class RedNode : public Node { + friend class SmartBpGraphBase; + protected: + + explicit RedNode(int pid) : Node(pid) {} + + public: + RedNode() {} + RedNode(const RedNode& node) : Node(node) {} + RedNode(Invalid) : Node(INVALID){} + }; + + class BlueNode : public Node { + friend class SmartBpGraphBase; + protected: + + explicit BlueNode(int pid) : Node(pid) {} + + public: + BlueNode() {} + BlueNode(const BlueNode& node) : Node(node) {} + BlueNode(Invalid) : Node(INVALID){} + }; + class Edge { friend class SmartBpGraphBase; protected: @@ -913,11 +937,18 @@ bool red(Node n) const { return nodes[n._id].red; } bool blue(Node n) const { return !nodes[n._id].red; } + static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } + static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } + Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); } Node target(Arc a) const { return Node(arcs[a._id].target); } - Node redNode(Edge e) const { return Node(arcs[2 * e._id].target); } - Node blueNode(Edge e) const { return Node(arcs[2 * e._id + 1].target); } + RedNode redNode(Edge e) const { + return RedNode(arcs[2 * e._id].target); + } + BlueNode blueNode(Edge e) const { + return BlueNode(arcs[2 * e._id + 1].target); + } static bool direction(Arc a) { return (a._id & 1) == 1; @@ -935,19 +966,19 @@ --node._id; } - void firstRed(Node& node) const { + void first(RedNode& node) const { node._id = first_red; } - void nextRed(Node& node) const { + void next(RedNode& node) const { node._id = nodes[node._id].partition_next; } - void firstBlue(Node& node) const { + void first(BlueNode& node) const { node._id = first_blue; } - void nextBlue(Node& node) const { + void next(BlueNode& node) const { node._id = nodes[node._id].partition_next; } @@ -1005,14 +1036,8 @@ } static int id(Node v) { return v._id; } - int redId(Node v) const { - LEMON_DEBUG(nodes[v._id].red, "Node has to be red"); - return nodes[v._id].partition_index; - } - int blueId(Node v) const { - LEMON_DEBUG(!nodes[v._id].red, "Node has to be blue"); - return nodes[v._id].partition_index; - } + int id(RedNode v) const { return nodes[v._id].partition_index; } + int id(BlueNode v) const { return nodes[v._id].partition_index; } static int id(Arc e) { return e._id; } static int id(Edge e) { return e._id; } @@ -1030,7 +1055,7 @@ return e._id >= 0 && 2 * e._id < static_cast(arcs.size()); } - Node addRedNode() { + RedNode addRedNode() { int n = nodes.size(); nodes.push_back(NodeT()); nodes[n].first_out = -1; @@ -1039,10 +1064,10 @@ nodes[n].partition_next = first_red; first_red = n; - return Node(n); + return RedNode(n); } - Node addBlueNode() { + BlueNode addBlueNode() { int n = nodes.size(); nodes.push_back(NodeT()); nodes[n].first_out = -1; @@ -1051,10 +1076,10 @@ nodes[n].partition_next = first_blue; first_blue = n; - return Node(n); + return BlueNode(n); } - Edge addEdge(Node u, Node v) { + Edge addEdge(RedNode u, BlueNode v) { int n = arcs.size(); arcs.push_back(ArcT()); arcs.push_back(ArcT()); @@ -1124,13 +1149,13 @@ /// /// This function adds a red new node to the graph. /// \return The new node. - Node addRedNode() { return Parent::addRedNode(); } + RedNode addRedNode() { return Parent::addRedNode(); } /// \brief Add a new blue node to the graph. /// /// This function adds a blue new node to the graph. /// \return The new node. - Node addBlueNode() { return Parent::addBlueNode(); } + BlueNode addBlueNode() { return Parent::addBlueNode(); } /// \brief Add a new edge to the graph. /// @@ -1138,10 +1163,11 @@ /// \c u and \c v with inherent orientation from node \c u to /// node \c v. /// \return The new edge. - Edge addEdge(Node red, Node blue) { - LEMON_DEBUG(Parent::red(red) && Parent::blue(blue), - "Edge has to be formed by a red and a blue nodes"); - return Parent::addEdge(red, blue); + Edge addEdge(RedNode u, BlueNode v) { + return Parent::addEdge(u, v); + } + Edge addEdge(BlueNode v, RedNode u) { + return Parent::addEdge(u, v); } /// \brief Node validity check @@ -1237,7 +1263,7 @@ } else { max_red = -1; } - Parent::notifier(RedNode()).erase(node); + Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node)); } else { first_blue = nodes[n].partition_next; if (first_blue != -1) { @@ -1245,7 +1271,7 @@ } else { max_blue = -1; } - Parent::notifier(BlueNode()).erase(node); + Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node)); } Parent::notifier(Node()).erase(node); nodes.pop_back(); diff -r b84e68af8248 -r c8fa41fcc4a7 test/bpgraph_test.cc --- a/test/bpgraph_test.cc Thu Nov 25 22:45:29 2010 +0100 +++ b/test/bpgraph_test.cc Thu Dec 01 09:05:47 2011 +0100 @@ -41,7 +41,7 @@ G.reserveNode(3); G.reserveEdge(3); - Node + RedNode rn1 = G.addRedNode(); checkGraphNodeList(G, 1); checkGraphRedNodeList(G, 1); @@ -49,7 +49,7 @@ checkGraphEdgeList(G, 0); checkGraphArcList(G, 0); - Node + BlueNode bn1 = G.addBlueNode(), bn2 = G.addBlueNode(); checkGraphNodeList(G, 3); @@ -76,7 +76,7 @@ checkGraphConArcList(G, 2); Edge - e2 = G.addEdge(rn1, bn1), + e2 = G.addEdge(bn1, rn1), e3 = G.addEdge(rn1, bn2); checkGraphNodeList(G, 3); @@ -112,9 +112,10 @@ TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph); BpGraph G; - Node - n1 = G.addRedNode(), n2 = G.addBlueNode(), - n3 = G.addBlueNode(), n4 = G.addRedNode(); + RedNode + n1 = G.addRedNode(), n4 = G.addRedNode(); + BlueNode + n2 = G.addBlueNode(), n3 = G.addBlueNode(); Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3), e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3); @@ -159,9 +160,10 @@ TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph); BpGraph G; - Node - n1 = G.addRedNode(), n2 = G.addBlueNode(), - n3 = G.addBlueNode(), n4 = G.addRedNode(); + RedNode + n1 = G.addRedNode(), n4 = G.addRedNode(); + BlueNode + n2 = G.addBlueNode(), n3 = G.addBlueNode(); Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3), e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3); @@ -209,8 +211,9 @@ TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph); BpGraph G; - Node - n1 = G.addRedNode(), + RedNode + n1 = G.addRedNode(); + BlueNode n2 = G.addBlueNode(), n3 = G.addBlueNode(); Edge @@ -225,7 +228,7 @@ typename BpGraph::Snapshot snapshot(G); - Node n4 = G.addRedNode(); + RedNode n4 = G.addRedNode(); G.addEdge(n4, n2); G.addEdge(n4, n3); @@ -292,8 +295,9 @@ TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph); BpGraph g; - Node - n1 = g.addRedNode(), + RedNode + n1 = g.addRedNode(); + BlueNode n2 = g.addBlueNode(), n3 = g.addBlueNode(); @@ -396,12 +400,12 @@ for (int i = 0; i < G.redNum(); ++i) { check(G.red(G.redNode(i)), "Wrong node"); - check(G.redIndex(G.redNode(i)) == i, "Wrong index"); + check(G.index(G.redNode(i)) == i, "Wrong index"); } for (int i = 0; i < G.blueNum(); ++i) { check(G.blue(G.blueNode(i)), "Wrong node"); - check(G.blueIndex(G.blueNode(i)) == i, "Wrong index"); + check(G.index(G.blueNode(i)) == i, "Wrong index"); } for (NodeIt u(G); u != INVALID; ++u) { diff -r b84e68af8248 -r c8fa41fcc4a7 test/graph_copy_test.cc --- a/test/graph_copy_test.cc Thu Nov 25 22:45:29 2010 +0100 +++ b/test/graph_copy_test.cc Thu Dec 01 09:05:47 2011 +0100 @@ -221,24 +221,30 @@ SmartBpGraph::ArcMap fam(from); SmartBpGraph::EdgeMap fem(from); SmartBpGraph::Node fn = INVALID; + SmartBpGraph::RedNode frn = INVALID; + SmartBpGraph::BlueNode fbn = INVALID; SmartBpGraph::Arc fa = INVALID; SmartBpGraph::Edge fe = INVALID; - std::vector frnv; + std::vector frnv; for (int i = 0; i < nn; ++i) { - SmartBpGraph::Node node = from.addRedNode(); + SmartBpGraph::RedNode node = from.addRedNode(); frnv.push_back(node); fnm[node] = i * i; frnm[node] = i + i; - if (i == 0) fn = node; + if (i == 0) { + fn = node; + frn = node; + } } - std::vector fbnv; + std::vector fbnv; for (int i = 0; i < nn; ++i) { - SmartBpGraph::Node node = from.addBlueNode(); + SmartBpGraph::BlueNode node = from.addBlueNode(); fbnv.push_back(node); fnm[node] = i * i; fbnm[node] = i + i; + if (i == 0) fbn = node; } for (int i = 0; i < nn; ++i) { @@ -260,18 +266,20 @@ typename GR::template ArcMap tam(to); typename GR::template EdgeMap tem(to); typename GR::Node tn; + typename GR::RedNode trn; + typename GR::BlueNode tbn; typename GR::Arc ta; typename GR::Edge te; SmartBpGraph::NodeMap nr(from); - SmartBpGraph::RedMap rnr(from); - SmartBpGraph::BlueMap bnr(from); + SmartBpGraph::RedMap rnr(from); + SmartBpGraph::BlueMap bnr(from); SmartBpGraph::ArcMap ar(from); SmartBpGraph::EdgeMap er(from); typename GR::template NodeMap ncr(to); - typename GR::template RedMap rncr(to); - typename GR::template BlueMap bncr(to); + typename GR::template RedMap rncr(to); + typename GR::template BlueMap bncr(to); typename GR::template ArcMap acr(to); typename GR::template EdgeMap ecr(to); @@ -282,7 +290,8 @@ arcRef(ar).edgeRef(er). nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr). arcCrossRef(acr).edgeCrossRef(ecr). - node(fn, tn).arc(fa, ta).edge(fe, te).run(); + node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn). + arc(fa, ta).edge(fe, te).run(); check(countNodes(from) == countNodes(to), "Wrong copy."); check(countRedNodes(from) == countRedNodes(to), "Wrong copy."); @@ -293,17 +302,24 @@ for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) { check(ncr[nr[it]] == it, "Wrong copy."); check(fnm[it] == tnm[nr[it]], "Wrong copy."); - if (from.red(it)) { - check(rnr[it] == nr[it], "Wrong copy."); - check(rncr[rnr[it]] == it, "Wrong copy."); - check(frnm[it] == trnm[rnr[it]], "Wrong copy."); - check(to.red(rnr[it]), "Wrong copy."); - } else { - check(bnr[it] == nr[it], "Wrong copy."); - check(bncr[bnr[it]] == it, "Wrong copy."); - check(fbnm[it] == tbnm[bnr[it]], "Wrong copy."); - check(to.blue(bnr[it]), "Wrong copy."); - } + } + + for (SmartBpGraph::RedIt it(from); it != INVALID; ++it) { + check(ncr[nr[it]] == it, "Wrong copy."); + check(fnm[it] == tnm[nr[it]], "Wrong copy."); + check(rnr[it] == nr[it], "Wrong copy."); + check(rncr[rnr[it]] == it, "Wrong copy."); + check(frnm[it] == trnm[rnr[it]], "Wrong copy."); + check(to.red(rnr[it]), "Wrong copy."); + } + + for (SmartBpGraph::BlueIt it(from); it != INVALID; ++it) { + check(ncr[nr[it]] == it, "Wrong copy."); + check(fnm[it] == tnm[nr[it]], "Wrong copy."); + check(bnr[it] == nr[it], "Wrong copy."); + check(bncr[bnr[it]] == it, "Wrong copy."); + check(fbnm[it] == tbnm[bnr[it]], "Wrong copy."); + check(to.blue(bnr[it]), "Wrong copy."); } for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) { @@ -342,6 +358,8 @@ check(er[ecr[it]] == it, "Wrong copy."); } check(tn == nr[fn], "Wrong copy."); + check(trn == rnr[frn], "Wrong copy."); + check(tbn == bnr[fbn], "Wrong copy."); check(ta == ar[fa], "Wrong copy."); check(te == er[fe], "Wrong copy."); diff -r b84e68af8248 -r c8fa41fcc4a7 test/graph_test.h --- a/test/graph_test.h Thu Nov 25 22:45:29 2010 +0100 +++ b/test/graph_test.h Thu Dec 01 09:05:47 2011 +0100 @@ -46,6 +46,16 @@ typename Graph::RedIt n(G); for(int i=0;i rbn = + G.asRedBlueNode(nn); + check(rbn.first == n,"Wrong node conversion."); + check(rbn.second == INVALID,"Wrong node conversion."); ++n; } check(n==INVALID,"Wrong red Node list linking."); @@ -58,6 +68,16 @@ typename Graph::BlueIt n(G); for(int i=0;i rbn = + G.asRedBlueNode(nn); + check(rbn.first == INVALID,"Wrong node conversion."); + check(rbn.second == n,"Wrong node conversion."); ++n; } check(n==INVALID,"Wrong blue Node list linking."); @@ -207,9 +227,8 @@ std::set values; for (typename Graph::RedIt n(G); n != INVALID; ++n) { check(G.red(n), "Wrong partition"); - check(G.redId(n) == G.id(RedNode(n)), "Wrong id"); - check(values.find(G.redId(n)) == values.end(), "Wrong id"); - check(G.redId(n) <= G.maxRedId(), "Wrong maximum id"); + check(values.find(G.id(n)) == values.end(), "Wrong id"); + check(G.id(n) <= G.maxRedId(), "Wrong maximum id"); values.insert(G.id(n)); } check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id"); @@ -221,9 +240,8 @@ std::set values; for (typename Graph::BlueIt n(G); n != INVALID; ++n) { check(G.blue(n), "Wrong partition"); - check(G.blueId(n) == G.id(BlueNode(n)), "Wrong id"); - check(values.find(G.blueId(n)) == values.end(), "Wrong id"); - check(G.blueId(n) <= G.maxBlueId(), "Wrong maximum id"); + check(values.find(G.id(n)) == values.end(), "Wrong id"); + check(G.id(n) <= G.maxBlueId(), "Wrong maximum id"); values.insert(G.id(n)); } check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");