diff -r 67af33b34394 -r 06faf3f06d67 lemon/bits/base_extender.h --- a/lemon/bits/base_extender.h Tue Oct 03 11:24:41 2006 +0000 +++ b/lemon/bits/base_extender.h Tue Oct 03 11:46:39 2006 +0000 @@ -279,6 +279,209 @@ } }; + template + class BidirBpUGraphExtender : public Base { + public: + typedef Base Parent; + typedef BidirBpUGraphExtender Graph; + + typedef typename Parent::Node Node; + typedef typename Parent::UEdge UEdge; + + + using Parent::first; + using Parent::next; + + using Parent::id; + + class ANode : public Node { + friend class BidirBpUGraphExtender; + public: + ANode() {} + ANode(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::aNode(node) || node == INVALID, + typename Parent::NodeSetError()); + } + ANode& operator=(const Node& node) { + LEMON_ASSERT(Parent::aNode(node) || node == INVALID, + typename Parent::NodeSetError()); + Node::operator=(node); + return *this; + } + ANode(Invalid) : Node(INVALID) {} + }; + + void first(ANode& node) const { + Parent::firstANode(static_cast(node)); + } + void next(ANode& node) const { + Parent::nextANode(static_cast(node)); + } + + int id(const ANode& node) const { + return Parent::aNodeId(node); + } + + class BNode : public Node { + friend class BidirBpUGraphExtender; + public: + BNode() {} + BNode(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::bNode(node) || node == INVALID, + typename Parent::NodeSetError()); + } + BNode& operator=(const Node& node) { + LEMON_ASSERT(Parent::bNode(node) || node == INVALID, + typename Parent::NodeSetError()); + Node::operator=(node); + return *this; + } + BNode(Invalid) : Node(INVALID) {} + }; + + void first(BNode& node) const { + Parent::firstBNode(static_cast(node)); + } + void next(BNode& node) const { + Parent::nextBNode(static_cast(node)); + } + + int id(const BNode& node) const { + return Parent::aNodeId(node); + } + + Node source(const UEdge& edge) const { + return aNode(edge); + } + Node target(const UEdge& edge) const { + return bNode(edge); + } + + void firstInc(UEdge& edge, bool& direction, const Node& node) const { + if (Parent::aNode(node)) { + Parent::firstFromANode(edge, node); + direction = true; + } else { + Parent::firstFromBNode(edge, node); + direction = static_cast(edge) == INVALID; + } + } + void nextInc(UEdge& edge, bool& direction) const { + if (direction) { + Parent::nextFromANode(edge); + } else { + Parent::nextFromBNode(edge); + if (edge == INVALID) direction = true; + } + } + + class Edge : public UEdge { + friend class BidirBpUGraphExtender; + protected: + bool forward; + + Edge(const UEdge& edge, bool _forward) + : UEdge(edge), forward(_forward) {} + + public: + Edge() {} + Edge (Invalid) : UEdge(INVALID), forward(true) {} + bool operator==(const Edge& i) const { + return UEdge::operator==(i) && forward == i.forward; + } + bool operator!=(const Edge& i) const { + return UEdge::operator!=(i) || forward != i.forward; + } + bool operator<(const Edge& i) const { + return UEdge::operator<(i) || + (!(i.forward(edge)); + edge.forward = true; + } + + void next(Edge& edge) const { + if (!edge.forward) { + Parent::next(static_cast(edge)); + } + edge.forward = !edge.forward; + } + + void firstOut(Edge& edge, const Node& node) const { + if (Parent::aNode(node)) { + Parent::firstFromANode(edge, node); + edge.forward = true; + } else { + Parent::firstFromBNode(edge, node); + edge.forward = static_cast(edge) == INVALID; + } + } + void nextOut(Edge& edge) const { + if (edge.forward) { + Parent::nextFromANode(edge); + } else { + Parent::nextFromBNode(edge); + edge.forward = static_cast(edge) == INVALID; + } + } + + void firstIn(Edge& edge, const Node& node) const { + if (Parent::bNode(node)) { + Parent::firstFromBNode(edge, node); + edge.forward = true; + } else { + Parent::firstFromANode(edge, node); + edge.forward = static_cast(edge) == INVALID; + } + } + void nextIn(Edge& edge) const { + if (edge.forward) { + Parent::nextFromBNode(edge); + } else { + Parent::nextFromANode(edge); + edge.forward = static_cast(edge) == INVALID; + } + } + + Node source(const Edge& edge) const { + return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge); + } + Node target(const Edge& edge) const { + return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge); + } + + int id(const Edge& edge) const { + return (Parent::id(static_cast(edge)) << 1) + + (edge.forward ? 0 : 1); + } + Edge edgeFromId(int id) const { + return Edge(Parent::fromUEdgeId(id >> 1), (id & 1) == 0); + } + int maxEdgeId() const { + return (Parent::maxUEdgeId() << 1) + 1; + } + + bool direction(const Edge& edge) const { + return edge.forward; + } + + Edge direct(const UEdge& edge, bool direction) const { + return Edge(edge, direction); + } + + int edgeNum() const { + return 2 * Parent::uEdgeNum(); + } + + int uEdgeNum() const { + return Parent::uEdgeNum(); + } + + + }; } #endif