deba@416: /* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@414:  *
deba@416:  * This file is a part of LEMON, a generic C++ optimization library.
deba@414:  *
alpar@440:  * Copyright (C) 2003-2009
deba@414:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@414:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@414:  *
deba@414:  * Permission to use, modify and distribute this software is granted
deba@414:  * provided that this copyright notice appears in all copies. For
deba@414:  * precise terms see the accompanying LICENSE file.
deba@414:  *
deba@414:  * This software is provided "AS IS" with no warranty of any kind,
deba@414:  * express or implied, and with no claim as to its suitability for any
deba@414:  * purpose.
deba@414:  *
deba@414:  */
deba@414: 
deba@414: #ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
deba@414: #define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
deba@414: 
deba@414: #include <lemon/core.h>
deba@414: #include <lemon/error.h>
deba@414: 
deba@414: namespace lemon {
deba@414: 
deba@414:   template <typename _Digraph>
deba@414:   class DigraphAdaptorExtender : public _Digraph {
kpeter@617:     typedef _Digraph Parent;
kpeter@617: 
deba@414:   public:
deba@414: 
deba@414:     typedef _Digraph Digraph;
deba@414:     typedef DigraphAdaptorExtender Adaptor;
deba@414: 
deba@414:     // Base extensions
deba@414: 
deba@414:     typedef typename Parent::Node Node;
deba@414:     typedef typename Parent::Arc Arc;
deba@414: 
deba@414:     int maxId(Node) const {
deba@414:       return Parent::maxNodeId();
deba@414:     }
deba@414: 
deba@414:     int maxId(Arc) const {
deba@414:       return Parent::maxArcId();
deba@414:     }
deba@414: 
deba@414:     Node fromId(int id, Node) const {
deba@414:       return Parent::nodeFromId(id);
deba@414:     }
deba@414: 
deba@414:     Arc fromId(int id, Arc) const {
deba@414:       return Parent::arcFromId(id);
deba@414:     }
deba@414: 
deba@414:     Node oppositeNode(const Node &n, const Arc &e) const {
deba@414:       if (n == Parent::source(e))
deba@416:         return Parent::target(e);
deba@414:       else if(n==Parent::target(e))
deba@416:         return Parent::source(e);
deba@414:       else
deba@416:         return INVALID;
deba@414:     }
deba@414: 
deba@416:     class NodeIt : public Node {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       NodeIt() {}
deba@414: 
deba@414:       NodeIt(Invalid i) : Node(i) { }
deba@414: 
deba@414:       explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416:         _adaptor->first(static_cast<Node&>(*this));
deba@414:       }
deba@414: 
deba@416:       NodeIt(const Adaptor& adaptor, const Node& node)
deba@416:         : Node(node), _adaptor(&adaptor) {}
deba@414: 
deba@416:       NodeIt& operator++() {
deba@416:         _adaptor->next(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class ArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       ArcIt() { }
deba@414: 
deba@414:       ArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@414:       explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416:         _adaptor->first(static_cast<Arc&>(*this));
deba@414:       }
deba@414: 
deba@416:       ArcIt(const Adaptor& adaptor, const Arc& e) :
deba@416:         Arc(e), _adaptor(&adaptor) { }
deba@414: 
deba@416:       ArcIt& operator++() {
deba@416:         _adaptor->next(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class OutArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       OutArcIt() { }
deba@414: 
deba@414:       OutArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@416:       OutArcIt(const Adaptor& adaptor, const Node& node)
deba@416:         : _adaptor(&adaptor) {
deba@416:         _adaptor->firstOut(*this, node);
deba@414:       }
deba@414: 
deba@416:       OutArcIt(const Adaptor& adaptor, const Arc& arc)
deba@416:         : Arc(arc), _adaptor(&adaptor) {}
deba@414: 
deba@416:       OutArcIt& operator++() {
deba@416:         _adaptor->nextOut(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class InArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       InArcIt() { }
deba@414: 
deba@414:       InArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@416:       InArcIt(const Adaptor& adaptor, const Node& node)
deba@416:         : _adaptor(&adaptor) {
deba@416:         _adaptor->firstIn(*this, node);
deba@414:       }
deba@414: 
deba@416:       InArcIt(const Adaptor& adaptor, const Arc& arc) :
deba@416:         Arc(arc), _adaptor(&adaptor) {}
deba@414: 
deba@416:       InArcIt& operator++() {
deba@416:         _adaptor->nextIn(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414:     Node baseNode(const OutArcIt &e) const {
deba@414:       return Parent::source(e);
deba@414:     }
deba@414:     Node runningNode(const OutArcIt &e) const {
deba@414:       return Parent::target(e);
deba@414:     }
deba@414: 
deba@414:     Node baseNode(const InArcIt &e) const {
deba@414:       return Parent::target(e);
deba@414:     }
deba@414:     Node runningNode(const InArcIt &e) const {
deba@414:       return Parent::source(e);
deba@414:     }
deba@414: 
deba@414:   };
deba@414: 
deba@416:   template <typename _Graph>
deba@414:   class GraphAdaptorExtender : public _Graph {
kpeter@617:     typedef _Graph Parent;
kpeter@617: 
deba@414:   public:
deba@416: 
deba@414:     typedef _Graph Graph;
deba@414:     typedef GraphAdaptorExtender Adaptor;
deba@414: 
deba@414:     typedef typename Parent::Node Node;
deba@414:     typedef typename Parent::Arc Arc;
deba@414:     typedef typename Parent::Edge Edge;
deba@414: 
deba@416:     // Graph extension
deba@414: 
deba@414:     int maxId(Node) const {
deba@414:       return Parent::maxNodeId();
deba@414:     }
deba@414: 
deba@414:     int maxId(Arc) const {
deba@414:       return Parent::maxArcId();
deba@414:     }
deba@414: 
deba@414:     int maxId(Edge) const {
deba@414:       return Parent::maxEdgeId();
deba@414:     }
deba@414: 
deba@414:     Node fromId(int id, Node) const {
deba@414:       return Parent::nodeFromId(id);
deba@414:     }
deba@414: 
deba@414:     Arc fromId(int id, Arc) const {
deba@414:       return Parent::arcFromId(id);
deba@414:     }
deba@414: 
deba@414:     Edge fromId(int id, Edge) const {
deba@414:       return Parent::edgeFromId(id);
deba@414:     }
deba@414: 
deba@414:     Node oppositeNode(const Node &n, const Edge &e) const {
deba@414:       if( n == Parent::u(e))
deba@416:         return Parent::v(e);
deba@414:       else if( n == Parent::v(e))
deba@416:         return Parent::u(e);
deba@414:       else
deba@416:         return INVALID;
deba@414:     }
deba@414: 
deba@414:     Arc oppositeArc(const Arc &a) const {
deba@414:       return Parent::direct(a, !Parent::direction(a));
deba@414:     }
deba@414: 
deba@414:     using Parent::direct;
deba@414:     Arc direct(const Edge &e, const Node &s) const {
deba@414:       return Parent::direct(e, Parent::u(e) == s);
deba@414:     }
deba@414: 
deba@414: 
deba@416:     class NodeIt : public Node {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       NodeIt() {}
deba@414: 
deba@414:       NodeIt(Invalid i) : Node(i) { }
deba@414: 
deba@414:       explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416:         _adaptor->first(static_cast<Node&>(*this));
deba@414:       }
deba@414: 
deba@416:       NodeIt(const Adaptor& adaptor, const Node& node)
deba@416:         : Node(node), _adaptor(&adaptor) {}
deba@414: 
deba@416:       NodeIt& operator++() {
deba@416:         _adaptor->next(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class ArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       ArcIt() { }
deba@414: 
deba@414:       ArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@414:       explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416:         _adaptor->first(static_cast<Arc&>(*this));
deba@414:       }
deba@414: 
deba@416:       ArcIt(const Adaptor& adaptor, const Arc& e) :
deba@416:         Arc(e), _adaptor(&adaptor) { }
deba@414: 
deba@416:       ArcIt& operator++() {
deba@416:         _adaptor->next(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class OutArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       OutArcIt() { }
deba@414: 
deba@414:       OutArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@416:       OutArcIt(const Adaptor& adaptor, const Node& node)
deba@416:         : _adaptor(&adaptor) {
deba@416:         _adaptor->firstOut(*this, node);
deba@414:       }
deba@414: 
deba@416:       OutArcIt(const Adaptor& adaptor, const Arc& arc)
deba@416:         : Arc(arc), _adaptor(&adaptor) {}
deba@414: 
deba@416:       OutArcIt& operator++() {
deba@416:         _adaptor->nextOut(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@414: 
deba@416:     class InArcIt : public Arc {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       InArcIt() { }
deba@414: 
deba@414:       InArcIt(Invalid i) : Arc(i) { }
deba@414: 
deba@416:       InArcIt(const Adaptor& adaptor, const Node& node)
deba@416:         : _adaptor(&adaptor) {
deba@416:         _adaptor->firstIn(*this, node);
deba@414:       }
deba@414: 
deba@416:       InArcIt(const Adaptor& adaptor, const Arc& arc) :
deba@416:         Arc(arc), _adaptor(&adaptor) {}
deba@414: 
deba@416:       InArcIt& operator++() {
deba@416:         _adaptor->nextIn(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@416:     class EdgeIt : public Parent::Edge {
deba@414:       const Adaptor* _adaptor;
deba@414:     public:
deba@414: 
deba@414:       EdgeIt() { }
deba@414: 
deba@414:       EdgeIt(Invalid i) : Edge(i) { }
deba@414: 
deba@414:       explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416:         _adaptor->first(static_cast<Edge&>(*this));
deba@414:       }
deba@414: 
deba@416:       EdgeIt(const Adaptor& adaptor, const Edge& e) :
deba@416:         Edge(e), _adaptor(&adaptor) { }
deba@414: 
deba@416:       EdgeIt& operator++() {
deba@416:         _adaptor->next(*this);
deba@416:         return *this;
deba@414:       }
deba@414: 
deba@414:     };
deba@414: 
deba@416:     class IncEdgeIt : public Edge {
deba@414:       friend class GraphAdaptorExtender;
deba@414:       const Adaptor* _adaptor;
deba@414:       bool direction;
deba@414:     public:
deba@414: 
deba@414:       IncEdgeIt() { }
deba@414: 
deba@414:       IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
deba@414: 
deba@414:       IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
deba@416:         _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
deba@414:       }
deba@414: 
deba@414:       IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
deba@416:         : _adaptor(&adaptor), Edge(e) {
deba@416:         direction = (_adaptor->u(e) == n);
deba@414:       }
deba@414: 
deba@414:       IncEdgeIt& operator++() {
deba@416:         _adaptor->nextInc(*this, direction);
deba@416:         return *this;
deba@414:       }
deba@414:     };
deba@414: 
deba@414:     Node baseNode(const OutArcIt &a) const {
deba@414:       return Parent::source(a);
deba@414:     }
deba@414:     Node runningNode(const OutArcIt &a) const {
deba@414:       return Parent::target(a);
deba@414:     }
deba@414: 
deba@414:     Node baseNode(const InArcIt &a) const {
deba@414:       return Parent::target(a);
deba@414:     }
deba@414:     Node runningNode(const InArcIt &a) const {
deba@414:       return Parent::source(a);
deba@414:     }
deba@414: 
deba@414:     Node baseNode(const IncEdgeIt &e) const {
deba@414:       return e.direction ? Parent::u(e) : Parent::v(e);
deba@414:     }
deba@414:     Node runningNode(const IncEdgeIt &e) const {
deba@414:       return e.direction ? Parent::v(e) : Parent::u(e);
deba@414:     }
deba@414: 
deba@414:   };
deba@414: 
deba@414: }
deba@414: 
deba@414: 
deba@414: #endif