src/lemon/undir_graph_extender.h
changeset 1022 567f392d1d2e
parent 986 e997802b855c
child 1030 c8a41699e613
equal deleted inserted replaced
3:b74ac4fc8358 4:2526add56e1c
    68     /// \bug Is this a good name for this? Or "reverse" is better?
    68     /// \bug Is this a good name for this? Or "reverse" is better?
    69     Edge opposite(const Edge &e) const {
    69     Edge opposite(const Edge &e) const {
    70       return Edge(e,!e.forward);
    70       return Edge(e,!e.forward);
    71     }
    71     }
    72 
    72 
    73     /// Source of the given Edge.
    73   protected:
    74     Node source(const Edge &e) const {
    74 
       
    75     template <typename E>
       
    76     Node _dirSource(const E &e) const {
    75       return e.forward ? Parent::source(e) : Parent::target(e);
    77       return e.forward ? Parent::source(e) : Parent::target(e);
    76     }
    78     }
    77 
    79 
       
    80     template <typename E>
       
    81     Node _dirTarget(const E &e) const {
       
    82       return e.forward ? Parent::target(e) : Parent::source(e);
       
    83     }
       
    84 
       
    85   public:
    78     /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
    86     /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
    79     /// or something???
    87     /// or something???
    80     using Parent::source;
    88     using Parent::source;
    81 
    89 
    82     /// Target of the given Edge.
    90     /// Source of the given Edge.
    83     Node target(const Edge &e) const {
    91     Node source(const Edge &e) const {
    84       return e.forward ? Parent::target(e) : Parent::source(e);
    92       return _dirSource(e);
    85     }
    93     }
    86 
    94 
    87     /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
    95     /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
    88     /// or something???
    96     /// or something???
    89     using Parent::target;
    97     using Parent::target;
       
    98 
       
    99     /// Target of the given Edge.
       
   100     Node target(const Edge &e) const {
       
   101       return _dirTarget(e);
       
   102     }
    90 
   103 
    91     /// Returns whether the given directed edge is same orientation as the
   104     /// Returns whether the given directed edge is same orientation as the
    92     /// corresponding undirected edge.
   105     /// corresponding undirected edge.
    93     ///
   106     ///
    94     /// \todo reference to the corresponding point of the undirected graph
   107     /// \todo reference to the corresponding point of the undirected graph
   120 	Parent::next(e);
   133 	Parent::next(e);
   121 	e.forward = true;
   134 	e.forward = true;
   122       }
   135       }
   123     }
   136     }
   124 
   137 
   125     void firstOut(Edge &e, const Node &n) const {
   138     
       
   139   protected:
       
   140 
       
   141     template <typename E>
       
   142     void _dirFirstOut(E &e, const Node &n) const {
   126       Parent::firstOut(e,n);
   143       Parent::firstOut(e,n);
   127       if( UndirEdge(e) != INVALID ) {
   144       if( UndirEdge(e) != INVALID ) {
   128 	e.forward = true;
   145 	e.forward = true;
   129       }
   146       }
   130       else {
   147       else {
   131 	Parent::firstIn(e,n);
   148 	Parent::firstIn(e,n);
   132 	e.forward = false;
   149 	e.forward = false;
   133       }
   150       }
   134     }
   151     }
   135     void firstIn(Edge &e, const Node &n) const {
   152     template <typename E>
       
   153     void _dirFirstIn(E &e, const Node &n) const {
   136       Parent::firstIn(e,n);
   154       Parent::firstIn(e,n);
   137       if( UndirEdge(e) != INVALID ) {
   155       if( UndirEdge(e) != INVALID ) {
   138 	e.forward = true;
   156 	e.forward = true;
   139       }
   157       }
   140       else {
   158       else {
   141 	Parent::firstOut(e,n);
   159 	Parent::firstOut(e,n);
   142 	e.forward = false;
   160 	e.forward = false;
   143       }
   161       }
   144     }
   162     }
   145 
   163 
   146     void nextOut(Edge &e) const {
   164     template <typename E>
       
   165     void _dirNextOut(E &e) const {
   147       if( e.forward ) {
   166       if( e.forward ) {
   148 	Parent::nextOut(e);
   167 	Parent::nextOut(e);
   149 	if( UndirEdge(e) == INVALID ) {
   168 	if( UndirEdge(e) == INVALID ) {
   150 	  Parent::firstIn(e, Parent::source(e));
   169 	  Parent::firstIn(e, Parent::source(e));
   151 	  e.forward = false;
   170 	  e.forward = false;
   153       }
   172       }
   154       else {
   173       else {
   155 	Parent::nextIn(e);
   174 	Parent::nextIn(e);
   156       }
   175       }
   157     }
   176     }
   158     void nextIn(Edge &e) const {
   177     template <typename E>
       
   178     void _dirNextIn(E &e) const {
   159       if( e.forward ) {
   179       if( e.forward ) {
   160 	Parent::nextIn(e);
   180 	Parent::nextIn(e);
   161 	if( UndirEdge(e) == INVALID ) {
   181 	if( UndirEdge(e) == INVALID ) {
   162 	  Parent::firstOut(e, Parent::target(e));
   182 	  Parent::firstOut(e, Parent::target(e));
   163 	  e.forward = false;
   183 	  e.forward = false;
   166       else {
   186       else {
   167 	Parent::nextOut(e);
   187 	Parent::nextOut(e);
   168       }
   188       }
   169     }
   189     }
   170 
   190 
       
   191   public:
       
   192 
       
   193     void firstOut(Edge &e, const Node &n) const {
       
   194       _dirFirstOut(e, n);
       
   195     }
       
   196     void firstIn(Edge &e, const Node &n) const {
       
   197       _dirFirstIn(e, n);
       
   198     }
       
   199 
       
   200     void nextOut(Edge &e) const {
       
   201       _dirNextOut(e);
       
   202     }
       
   203     void nextIn(Edge &e) const {
       
   204       _dirNextIn(e);
       
   205     }
       
   206 
   171     // Miscellaneous stuff:
   207     // Miscellaneous stuff:
   172 
   208 
   173     /// \todo these methods (id, maxEdgeId) should be moved into separate
   209     /// \todo these methods (id, maxEdgeId) should be moved into separate
   174     /// Extender
   210     /// Extender
   175 
   211 
   176     using Parent::id;
   212     // using Parent::id;
       
   213     // Using "using" is not a good idea, cause it could be that there is
       
   214     // no "id" in Parent...
       
   215 
       
   216     int id(const Node &n) const {
       
   217       return Parent::id(n);
       
   218     }
       
   219 
       
   220     int id(const UndirEdge &e) const {
       
   221       return Parent::id(e);
       
   222     }
   177 
   223 
   178     int id(const Edge &e) const {
   224     int id(const Edge &e) const {
   179       return 2 * Parent::id(e) + int(e.forward);
   225       return 2 * Parent::id(e) + int(e.forward);
   180     }
   226     }
   181 
   227 
   182     int maxId(Edge = INVALID) const {
   228 
       
   229     int maxId(Node n) const {
       
   230       return Parent::maxId(Node());
       
   231     }
       
   232 
       
   233     int maxId(Edge) const {
   183       return 2 * Parent::maxId(typename Parent::Edge()) + 1;
   234       return 2 * Parent::maxId(typename Parent::Edge()) + 1;
   184     }
   235     }
   185     int maxId(UndirEdge = INVALID) const {
   236     int maxId(UndirEdge) const {
   186       return Parent::maxId(typename Parent::Edge());
   237       return Parent::maxId(typename Parent::Edge());
   187     }
   238     }
   188 
   239 
   189   };
   240   };
   190 
   241