lemon/path.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 07 Feb 2008 21:28:39 +0000
changeset 99 dbaa96cc1013
parent 97 ee1324c91288
child 100 4f754b4cf82b
permissions -rw-r--r--
Merge
alpar@96
     1
/* -*- C++ -*-
alpar@96
     2
 *
alpar@96
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@96
     4
 *
alpar@96
     5
 * Copyright (C) 2003-2008
alpar@96
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@96
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@96
     8
 *
alpar@96
     9
 * Permission to use, modify and distribute this software is granted
alpar@96
    10
 * provided that this copyright notice appears in all copies. For
alpar@96
    11
 * precise terms see the accompanying LICENSE file.
alpar@96
    12
 *
alpar@96
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@96
    14
 * express or implied, and with no claim as to its suitability for any
alpar@96
    15
 * purpose.
alpar@96
    16
 *
alpar@96
    17
 */
alpar@96
    18
alpar@96
    19
///\ingroup paths
alpar@96
    20
///\file
alpar@96
    21
///\brief Classes for representing paths in digraphs.
alpar@96
    22
///
alpar@96
    23
alpar@96
    24
#ifndef LEMON_PATH_H
alpar@96
    25
#define LEMON_PATH_H
alpar@96
    26
alpar@96
    27
#include <vector>
alpar@96
    28
#include <algorithm>
alpar@96
    29
alpar@96
    30
#include <lemon/error.h>
alpar@96
    31
#include <lemon/bits/invalid.h>
alpar@96
    32
alpar@96
    33
namespace lemon {
alpar@96
    34
alpar@96
    35
  /// \addtogroup paths
alpar@96
    36
  /// @{
alpar@96
    37
alpar@96
    38
alpar@96
    39
  /// \brief A structure for representing directed paths in a digraph.
alpar@96
    40
  ///
alpar@96
    41
  /// A structure for representing directed path in a digraph.
alpar@96
    42
  /// \param Digraph The digraph type in which the path is.
alpar@96
    43
  ///
alpar@96
    44
  /// In a sense, the path can be treated as a list of arcs. The
alpar@97
    45
  /// lemon path type stores just this list. As a consequence, it
alpar@97
    46
  /// cannot enumerate the nodes of the path and the source node of
alpar@97
    47
  /// a zero length path is undefined.
alpar@96
    48
  ///
alpar@96
    49
  /// This implementation is a back and front insertable and erasable
alpar@96
    50
  /// path type. It can be indexed in O(1) time. The front and back
alpar@97
    51
  /// insertion and erase is done in O(1) (amortized) time. The
alpar@97
    52
  /// implementation uses two vectors for storing the front and back
alpar@97
    53
  /// insertions.
alpar@96
    54
  template <typename _Digraph>
alpar@96
    55
  class Path {
alpar@96
    56
  public:
alpar@96
    57
alpar@96
    58
    typedef _Digraph Digraph;
alpar@96
    59
    typedef typename Digraph::Arc Arc;
alpar@96
    60
alpar@96
    61
    /// \brief Default constructor
alpar@96
    62
    ///
alpar@96
    63
    /// Default constructor
alpar@96
    64
    Path() {}
alpar@96
    65
alpar@96
    66
    /// \brief Template copy constructor
alpar@96
    67
    ///
alpar@97
    68
    /// This constuctor initializes the path from any other path type.
alpar@97
    69
    /// It simply makes a copy of the given path.
alpar@96
    70
    template <typename CPath>
alpar@96
    71
    Path(const CPath& cpath) {
alpar@96
    72
      copyPath(*this, cpath);
alpar@96
    73
    }
alpar@96
    74
alpar@96
    75
    /// \brief Template copy assignment
alpar@96
    76
    ///
alpar@97
    77
    /// This operator makes a copy of a path of any other type.
alpar@96
    78
    template <typename CPath>
alpar@96
    79
    Path& operator=(const CPath& cpath) {
alpar@96
    80
      copyPath(*this, cpath);
alpar@96
    81
      return *this;
alpar@96
    82
    }
alpar@96
    83
alpar@96
    84
    /// \brief Lemon style iterator for path arcs
alpar@96
    85
    ///
alpar@96
    86
    /// This class is used to iterate on the arcs of the paths.
alpar@96
    87
    class ArcIt {
alpar@96
    88
      friend class Path;
alpar@96
    89
    public:
alpar@96
    90
      /// \brief Default constructor
alpar@96
    91
      ArcIt() {}
alpar@96
    92
      /// \brief Invalid constructor
alpar@96
    93
      ArcIt(Invalid) : path(0), idx(-1) {}
alpar@97
    94
      /// \brief Initializate the iterator to the first arc of path
alpar@96
    95
      ArcIt(const Path &_path) 
alpar@96
    96
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
alpar@96
    97
alpar@96
    98
    private:
alpar@96
    99
alpar@96
   100
      ArcIt(const Path &_path, int _idx) 
alpar@96
   101
        : path(&_path), idx(_idx) {}
alpar@96
   102
alpar@96
   103
    public:
alpar@96
   104
alpar@96
   105
      /// \brief Conversion to Arc
alpar@96
   106
      operator const Arc&() const {
alpar@96
   107
        return path->nth(idx);
alpar@96
   108
      }
alpar@96
   109
alpar@96
   110
      /// \brief Next arc
alpar@96
   111
      ArcIt& operator++() { 
alpar@96
   112
        ++idx;
alpar@96
   113
        if (idx >= path->length()) idx = -1; 
alpar@96
   114
        return *this; 
alpar@96
   115
      }
alpar@96
   116
alpar@96
   117
      /// \brief Comparison operator
alpar@96
   118
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
alpar@96
   119
      /// \brief Comparison operator
alpar@96
   120
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
alpar@96
   121
      /// \brief Comparison operator
alpar@96
   122
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
alpar@96
   123
alpar@96
   124
    private:
alpar@96
   125
      const Path *path;
alpar@96
   126
      int idx;
alpar@96
   127
    };
alpar@96
   128
alpar@96
   129
    /// \brief Length of the path.
alpar@96
   130
    int length() const { return head.size() + tail.size(); }
alpar@97
   131
    /// \brief Return whether the path is empty.
alpar@96
   132
    bool empty() const { return head.empty() && tail.empty(); }
alpar@96
   133
alpar@97
   134
    /// \brief Reset the path to an empty one.
alpar@96
   135
    void clear() { head.clear(); tail.clear(); }
alpar@96
   136
alpar@97
   137
    /// \brief The nth arc.
alpar@96
   138
    ///
alpar@96
   139
    /// \pre n is in the [0..length() - 1] range
alpar@96
   140
    const Arc& nth(int n) const {
alpar@96
   141
      return n < int(head.size()) ? *(head.rbegin() + n) :
alpar@96
   142
        *(tail.begin() + (n - head.size()));
alpar@96
   143
    }
alpar@96
   144
alpar@97
   145
    /// \brief Initialize arc iterator to point to the nth arc
alpar@96
   146
    ///
alpar@96
   147
    /// \pre n is in the [0..length() - 1] range
alpar@96
   148
    ArcIt nthIt(int n) const {
alpar@96
   149
      return ArcIt(*this, n);
alpar@96
   150
    }
alpar@96
   151
alpar@97
   152
    /// \brief The first arc of the path
alpar@96
   153
    const Arc& front() const {
alpar@96
   154
      return head.empty() ? tail.front() : head.back();
alpar@96
   155
    }
alpar@96
   156
alpar@96
   157
    /// \brief Add a new arc before the current path
alpar@96
   158
    void addFront(const Arc& arc) {
alpar@96
   159
      head.push_back(arc);
alpar@96
   160
    }
alpar@96
   161
alpar@96
   162
    /// \brief Erase the first arc of the path
alpar@96
   163
    void eraseFront() {
alpar@96
   164
      if (!head.empty()) {
alpar@96
   165
        head.pop_back();
alpar@96
   166
      } else {
alpar@96
   167
        head.clear();
alpar@96
   168
        int halfsize = tail.size() / 2;
alpar@96
   169
        head.resize(halfsize);
alpar@96
   170
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
alpar@96
   171
                  head.rbegin());
alpar@96
   172
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
alpar@96
   173
        tail.resize(tail.size() - halfsize - 1);
alpar@96
   174
      }
alpar@96
   175
    }
alpar@96
   176
alpar@97
   177
    /// \brief The last arc of the path
alpar@96
   178
    const Arc& back() const {
alpar@96
   179
      return tail.empty() ? head.front() : tail.back();
alpar@96
   180
    }
alpar@96
   181
alpar@96
   182
    /// \brief Add a new arc behind the current path
alpar@96
   183
    void addBack(const Arc& arc) {
alpar@96
   184
      tail.push_back(arc);
alpar@96
   185
    }
alpar@96
   186
alpar@96
   187
    /// \brief Erase the last arc of the path
alpar@96
   188
    void eraseBack() {
alpar@96
   189
      if (!tail.empty()) {
alpar@96
   190
        tail.pop_back();
alpar@96
   191
      } else {
alpar@96
   192
        int halfsize = head.size() / 2;
alpar@96
   193
        tail.resize(halfsize);
alpar@96
   194
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
alpar@96
   195
                  tail.rbegin());
alpar@96
   196
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
alpar@96
   197
        head.resize(head.size() - halfsize - 1);
alpar@96
   198
      }
alpar@96
   199
    }
alpar@96
   200
alpar@96
   201
    typedef True BuildTag;
alpar@96
   202
alpar@96
   203
    template <typename CPath>
alpar@96
   204
    void build(const CPath& path) {
alpar@96
   205
      int len = path.length();
alpar@96
   206
      tail.reserve(len);
alpar@96
   207
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
alpar@96
   208
        tail.push_back(it);
alpar@96
   209
      }
alpar@96
   210
    }
alpar@96
   211
alpar@96
   212
    template <typename CPath>
alpar@96
   213
    void buildRev(const CPath& path) {
alpar@96
   214
      int len = path.length();
alpar@96
   215
      head.reserve(len);
alpar@96
   216
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
alpar@96
   217
        head.push_back(it);
alpar@96
   218
      }
alpar@96
   219
    }
alpar@96
   220
alpar@96
   221
  protected:
alpar@96
   222
    typedef std::vector<Arc> Container;
alpar@96
   223
    Container head, tail;
alpar@96
   224
alpar@96
   225
  };
alpar@96
   226
alpar@96
   227
  /// \brief A structure for representing directed paths in a digraph.
alpar@96
   228
  ///
alpar@96
   229
  /// A structure for representing directed path in a digraph.
alpar@96
   230
  /// \param Digraph The digraph type in which the path is.
alpar@96
   231
  ///
alpar@96
   232
  /// In a sense, the path can be treated as a list of arcs. The
alpar@96
   233
  /// lemon path type stores just this list. As a consequence it
alpar@96
   234
  /// cannot enumerate the nodes in the path and the zero length paths
alpar@96
   235
  /// cannot store the source.
alpar@96
   236
  ///
alpar@96
   237
  /// This implementation is a just back insertable and erasable path
alpar@96
   238
  /// type. It can be indexed in O(1) time. The back insertion and
alpar@96
   239
  /// erasure is amortized O(1) time. This implementation is faster
alpar@96
   240
  /// then the \c Path type because it use just one vector for the
alpar@96
   241
  /// arcs.
alpar@96
   242
  template <typename _Digraph>
alpar@96
   243
  class SimplePath {
alpar@96
   244
  public:
alpar@96
   245
alpar@96
   246
    typedef _Digraph Digraph;
alpar@96
   247
    typedef typename Digraph::Arc Arc;
alpar@96
   248
alpar@96
   249
    /// \brief Default constructor
alpar@96
   250
    ///
alpar@96
   251
    /// Default constructor
alpar@96
   252
    SimplePath() {}
alpar@96
   253
alpar@96
   254
    /// \brief Template copy constructor
alpar@96
   255
    ///
alpar@96
   256
    /// This path can be initialized with any other path type. It just
alpar@96
   257
    /// makes a copy of the given path.
alpar@96
   258
    template <typename CPath>
alpar@96
   259
    SimplePath(const CPath& cpath) {
alpar@96
   260
      copyPath(*this, cpath);
alpar@96
   261
    }
alpar@96
   262
alpar@96
   263
    /// \brief Template copy assignment
alpar@96
   264
    ///
alpar@96
   265
    /// This path can be initialized with any other path type. It just
alpar@96
   266
    /// makes a copy of the given path.
alpar@96
   267
    template <typename CPath>
alpar@96
   268
    SimplePath& operator=(const CPath& cpath) {
alpar@96
   269
      copyPath(*this, cpath);
alpar@96
   270
      return *this;
alpar@96
   271
    }
alpar@96
   272
alpar@96
   273
    /// \brief Iterator class to iterate on the arcs of the paths
alpar@96
   274
    ///
alpar@96
   275
    /// This class is used to iterate on the arcs of the paths
alpar@96
   276
    ///
alpar@96
   277
    /// Of course it converts to Digraph::Arc
alpar@96
   278
    class ArcIt {
alpar@96
   279
      friend class SimplePath;
alpar@96
   280
    public:
alpar@96
   281
      /// Default constructor
alpar@96
   282
      ArcIt() {}
alpar@96
   283
      /// Invalid constructor
alpar@96
   284
      ArcIt(Invalid) : path(0), idx(-1) {}
alpar@96
   285
      /// \brief Initializate the constructor to the first arc of path
alpar@96
   286
      ArcIt(const SimplePath &_path) 
alpar@96
   287
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
alpar@96
   288
alpar@96
   289
    private:
alpar@96
   290
alpar@96
   291
      /// Constructor with starting point
alpar@96
   292
      ArcIt(const SimplePath &_path, int _idx) 
alpar@96
   293
        : idx(_idx), path(&_path) {}
alpar@96
   294
alpar@96
   295
    public:
alpar@96
   296
alpar@96
   297
      ///Conversion to Digraph::Arc
alpar@96
   298
      operator const Arc&() const {
alpar@96
   299
        return path->nth(idx);
alpar@96
   300
      }
alpar@96
   301
alpar@96
   302
      /// Next arc
alpar@96
   303
      ArcIt& operator++() { 
alpar@96
   304
        ++idx;
alpar@96
   305
        if (idx >= path->length()) idx = -1; 
alpar@96
   306
        return *this; 
alpar@96
   307
      }
alpar@96
   308
alpar@96
   309
      /// Comparison operator
alpar@96
   310
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
alpar@96
   311
      /// Comparison operator
alpar@96
   312
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
alpar@96
   313
      /// Comparison operator
alpar@96
   314
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
alpar@96
   315
alpar@96
   316
    private:
alpar@96
   317
      const SimplePath *path;
alpar@96
   318
      int idx;
alpar@96
   319
    };
alpar@96
   320
alpar@96
   321
    /// \brief Length of the path.
alpar@96
   322
    int length() const { return data.size(); }
alpar@97
   323
    /// \brief Return true if the path is empty.
alpar@96
   324
    bool empty() const { return data.empty(); }
alpar@96
   325
alpar@97
   326
    /// \brief Reset the path to an empty one.
alpar@96
   327
    void clear() { data.clear(); }
alpar@96
   328
alpar@97
   329
    /// \brief The nth arc.
alpar@96
   330
    ///
alpar@96
   331
    /// \pre n is in the [0..length() - 1] range
alpar@96
   332
    const Arc& nth(int n) const {
alpar@96
   333
      return data[n];
alpar@96
   334
    }
alpar@96
   335
alpar@96
   336
    /// \brief  Initializes arc iterator to point to the nth arc.
alpar@96
   337
    ArcIt nthIt(int n) const {
alpar@96
   338
      return ArcIt(*this, n);
alpar@96
   339
    }
alpar@96
   340
alpar@97
   341
    /// \brief The first arc of the path.
alpar@96
   342
    const Arc& front() const {
alpar@96
   343
      return data.front();
alpar@96
   344
    }
alpar@96
   345
alpar@97
   346
    /// \brief The last arc of the path.
alpar@96
   347
    const Arc& back() const {
alpar@96
   348
      return data.back();
alpar@96
   349
    }
alpar@96
   350
alpar@96
   351
    /// \brief Add a new arc behind the current path.
alpar@96
   352
    void addBack(const Arc& arc) {
alpar@96
   353
      data.push_back(arc);
alpar@96
   354
    }
alpar@96
   355
alpar@96
   356
    /// \brief Erase the last arc of the path
alpar@96
   357
    void eraseBack() {
alpar@96
   358
      data.pop_back();
alpar@96
   359
    }
alpar@96
   360
alpar@96
   361
    typedef True BuildTag;
alpar@96
   362
alpar@96
   363
    template <typename CPath>
alpar@96
   364
    void build(const CPath& path) {
alpar@96
   365
      int len = path.length();
alpar@96
   366
      data.resize(len);
alpar@96
   367
      int index = 0;
alpar@96
   368
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
alpar@96
   369
        data[index] = it;;
alpar@96
   370
        ++index;
alpar@96
   371
      }
alpar@96
   372
    }
alpar@96
   373
alpar@96
   374
    template <typename CPath>
alpar@96
   375
    void buildRev(const CPath& path) {
alpar@96
   376
      int len = path.length();
alpar@96
   377
      data.resize(len);
alpar@96
   378
      int index = len;
alpar@96
   379
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
alpar@96
   380
        --index;
alpar@96
   381
        data[index] = it;;
alpar@96
   382
      }
alpar@96
   383
    }
alpar@96
   384
alpar@96
   385
  protected:
alpar@96
   386
    typedef std::vector<Arc> Container;
alpar@96
   387
    Container data;
alpar@96
   388
alpar@96
   389
  };
alpar@96
   390
alpar@96
   391
  /// \brief A structure for representing directed paths in a digraph.
alpar@96
   392
  ///
alpar@96
   393
  /// A structure for representing directed path in a digraph.
alpar@96
   394
  /// \param Digraph The digraph type in which the path is.
alpar@96
   395
  ///
alpar@96
   396
  /// In a sense, the path can be treated as a list of arcs. The
alpar@96
   397
  /// lemon path type stores just this list. As a consequence it
alpar@96
   398
  /// cannot enumerate the nodes in the path and the zero length paths
alpar@96
   399
  /// cannot store the source.
alpar@96
   400
  ///
alpar@96
   401
  /// This implementation is a back and front insertable and erasable
alpar@96
   402
  /// path type. It can be indexed in O(k) time, where k is the rank
alpar@96
   403
  /// of the arc in the path. The length can be computed in O(n)
alpar@96
   404
  /// time. The front and back insertion and erasure is O(1) time
alpar@96
   405
  /// and it can be splited and spliced in O(1) time.
alpar@96
   406
  template <typename _Digraph>
alpar@96
   407
  class ListPath {
alpar@96
   408
  public:
alpar@96
   409
alpar@96
   410
    typedef _Digraph Digraph;
alpar@96
   411
    typedef typename Digraph::Arc Arc;
alpar@96
   412
alpar@96
   413
  protected:
alpar@96
   414
alpar@96
   415
    // the std::list<> is incompatible 
alpar@96
   416
    // hard to create invalid iterator
alpar@96
   417
    struct Node {
alpar@96
   418
      Arc arc;
alpar@96
   419
      Node *next, *prev;
alpar@96
   420
    };
alpar@96
   421
alpar@96
   422
    Node *first, *last;
alpar@96
   423
alpar@96
   424
    std::allocator<Node> alloc;
alpar@96
   425
alpar@96
   426
  public:
alpar@96
   427
 
alpar@96
   428
    /// \brief Default constructor
alpar@96
   429
    ///
alpar@96
   430
    /// Default constructor
alpar@96
   431
    ListPath() : first(0), last(0) {}
alpar@96
   432
alpar@96
   433
    /// \brief Template copy constructor
alpar@96
   434
    ///
alpar@96
   435
    /// This path can be initialized with any other path type. It just
alpar@96
   436
    /// makes a copy of the given path.
alpar@96
   437
    template <typename CPath>
alpar@96
   438
    ListPath(const CPath& cpath) : first(0), last(0) {
alpar@96
   439
      copyPath(*this, cpath);
alpar@96
   440
    }
alpar@96
   441
alpar@96
   442
    /// \brief Destructor of the path
alpar@96
   443
    ///
alpar@96
   444
    /// Destructor of the path
alpar@96
   445
    ~ListPath() {
alpar@96
   446
      clear();
alpar@96
   447
    }
alpar@96
   448
alpar@96
   449
    /// \brief Template copy assignment
alpar@96
   450
    ///
alpar@96
   451
    /// This path can be initialized with any other path type. It just
alpar@96
   452
    /// makes a copy of the given path.
alpar@96
   453
    template <typename CPath>
alpar@96
   454
    ListPath& operator=(const CPath& cpath) {
alpar@96
   455
      copyPath(*this, cpath);
alpar@96
   456
      return *this;
alpar@96
   457
    }
alpar@96
   458
alpar@96
   459
    /// \brief Iterator class to iterate on the arcs of the paths
alpar@96
   460
    ///
alpar@96
   461
    /// This class is used to iterate on the arcs of the paths
alpar@96
   462
    ///
alpar@96
   463
    /// Of course it converts to Digraph::Arc
alpar@96
   464
    class ArcIt {
alpar@96
   465
      friend class ListPath;
alpar@96
   466
    public:
alpar@96
   467
      /// Default constructor
alpar@96
   468
      ArcIt() {}
alpar@96
   469
      /// Invalid constructor
alpar@96
   470
      ArcIt(Invalid) : path(0), node(0) {}
alpar@96
   471
      /// \brief Initializate the constructor to the first arc of path
alpar@96
   472
      ArcIt(const ListPath &_path) 
alpar@96
   473
        : path(&_path), node(_path.first) {}
alpar@96
   474
alpar@96
   475
    protected:
alpar@96
   476
alpar@96
   477
      ArcIt(const ListPath &_path, Node *_node) 
alpar@96
   478
        : path(&_path), node(_node) {}
alpar@96
   479
alpar@96
   480
alpar@96
   481
    public:
alpar@96
   482
alpar@96
   483
      ///Conversion to Digraph::Arc
alpar@96
   484
      operator const Arc&() const {
alpar@96
   485
        return node->arc;
alpar@96
   486
      }
alpar@96
   487
alpar@96
   488
      /// Next arc
alpar@96
   489
      ArcIt& operator++() { 
alpar@96
   490
        node = node->next;
alpar@96
   491
        return *this; 
alpar@96
   492
      }
alpar@96
   493
alpar@96
   494
      /// Comparison operator
alpar@96
   495
      bool operator==(const ArcIt& e) const { return node==e.node; }
alpar@96
   496
      /// Comparison operator
alpar@96
   497
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
alpar@96
   498
      /// Comparison operator
alpar@96
   499
      bool operator<(const ArcIt& e) const { return node<e.node; }
alpar@96
   500
alpar@96
   501
    private:
alpar@96
   502
      const ListPath *path;
alpar@96
   503
      Node *node;
alpar@96
   504
    };
alpar@96
   505
alpar@97
   506
    /// \brief The nth arc.
alpar@96
   507
    ///
alpar@97
   508
    /// This function looks for the nth arc in O(n) time.
alpar@96
   509
    /// \pre n is in the [0..length() - 1] range
alpar@96
   510
    const Arc& nth(int n) const {
alpar@96
   511
      Node *node = first;
alpar@96
   512
      for (int i = 0; i < n; ++i) {
alpar@96
   513
        node = node->next;
alpar@96
   514
      }
alpar@96
   515
      return node->arc;
alpar@96
   516
    }
alpar@96
   517
alpar@96
   518
    /// \brief Initializes arc iterator to point to the nth arc.
alpar@96
   519
    ArcIt nthIt(int n) const {
alpar@96
   520
      Node *node = first;
alpar@96
   521
      for (int i = 0; i < n; ++i) {
alpar@96
   522
        node = node->next;
alpar@96
   523
      }
alpar@96
   524
      return ArcIt(*this, node);
alpar@96
   525
    }
alpar@96
   526
alpar@96
   527
    /// \brief Length of the path.
alpar@96
   528
    int length() const {
alpar@96
   529
      int len = 0;
alpar@96
   530
      Node *node = first;
alpar@96
   531
      while (node != 0) {
alpar@96
   532
        node = node->next;
alpar@96
   533
        ++len;
alpar@96
   534
      }
alpar@96
   535
      return len;
alpar@96
   536
    }
alpar@96
   537
alpar@97
   538
    /// \brief Return true if the path is empty.
alpar@96
   539
    bool empty() const { return first == 0; }
alpar@96
   540
alpar@97
   541
    /// \brief Reset the path to an empty one.
alpar@96
   542
    void clear() {
alpar@96
   543
      while (first != 0) {
alpar@96
   544
        last = first->next;
alpar@96
   545
        alloc.destroy(first);
alpar@96
   546
        alloc.deallocate(first, 1);
alpar@96
   547
        first = last;
alpar@96
   548
      }
alpar@96
   549
    }
alpar@96
   550
alpar@97
   551
    /// \brief The first arc of the path
alpar@96
   552
    const Arc& front() const {
alpar@96
   553
      return first->arc;
alpar@96
   554
    }
alpar@96
   555
alpar@96
   556
    /// \brief Add a new arc before the current path
alpar@96
   557
    void addFront(const Arc& arc) {
alpar@96
   558
      Node *node = alloc.allocate(1);
alpar@96
   559
      alloc.construct(node, Node());
alpar@96
   560
      node->prev = 0;
alpar@96
   561
      node->next = first;
alpar@96
   562
      node->arc = arc;
alpar@96
   563
      if (first) {
alpar@96
   564
        first->prev = node;
alpar@96
   565
        first = node;
alpar@96
   566
      } else {
alpar@96
   567
        first = last = node;
alpar@96
   568
      }
alpar@96
   569
    }
alpar@96
   570
alpar@96
   571
    /// \brief Erase the first arc of the path
alpar@96
   572
    void eraseFront() {
alpar@96
   573
      Node *node = first;
alpar@96
   574
      first = first->next;
alpar@96
   575
      if (first) {
alpar@96
   576
        first->prev = 0;
alpar@96
   577
      } else {
alpar@96
   578
        last = 0;
alpar@96
   579
      }
alpar@96
   580
      alloc.destroy(node);
alpar@96
   581
      alloc.deallocate(node, 1);
alpar@96
   582
    }
alpar@96
   583
alpar@97
   584
    /// \brief The last arc of the path.
alpar@96
   585
    const Arc& back() const {
alpar@96
   586
      return last->arc;
alpar@96
   587
    }
alpar@96
   588
alpar@96
   589
    /// \brief Add a new arc behind the current path.
alpar@96
   590
    void addBack(const Arc& arc) {
alpar@96
   591
      Node *node = alloc.allocate(1);
alpar@96
   592
      alloc.construct(node, Node());
alpar@96
   593
      node->next = 0;
alpar@96
   594
      node->prev = last;
alpar@96
   595
      node->arc = arc;
alpar@96
   596
      if (last) {
alpar@96
   597
        last->next = node;
alpar@96
   598
        last = node;
alpar@96
   599
      } else {
alpar@96
   600
        last = first = node;
alpar@96
   601
      }
alpar@96
   602
    }
alpar@96
   603
alpar@96
   604
    /// \brief Erase the last arc of the path
alpar@96
   605
    void eraseBack() {
alpar@96
   606
      Node *node = last;
alpar@96
   607
      last = last->prev;
alpar@96
   608
      if (last) {
alpar@96
   609
        last->next = 0;
alpar@96
   610
      } else {
alpar@96
   611
        first = 0;
alpar@96
   612
      }
alpar@96
   613
      alloc.destroy(node);
alpar@96
   614
      alloc.deallocate(node, 1);
alpar@96
   615
    }
alpar@96
   616
alpar@97
   617
    /// \brief Splice a path to the back of the current path.
alpar@96
   618
    ///
alpar@97
   619
    /// It splices \c tpath to the back of the current path and \c
alpar@96
   620
    /// tpath becomes empty. The time complexity of this function is
alpar@96
   621
    /// O(1).
alpar@96
   622
    void spliceBack(ListPath& tpath) {
alpar@96
   623
      if (first) {
alpar@96
   624
        if (tpath.first) {
alpar@96
   625
          last->next = tpath.first;
alpar@96
   626
          tpath.first->prev = last;
alpar@96
   627
          last = tpath.last;
alpar@96
   628
        }
alpar@96
   629
      } else {
alpar@96
   630
        first = tpath.first;
alpar@96
   631
        last = tpath.last;
alpar@96
   632
      }
alpar@96
   633
      tpath.first = tpath.last = 0;
alpar@96
   634
    }
alpar@96
   635
alpar@97
   636
    /// \brief Splice a path to the front of the current path.
alpar@96
   637
    ///
alpar@97
   638
    /// It splices \c tpath before the current path and \c tpath
alpar@96
   639
    /// becomes empty. The time complexity of this function
alpar@96
   640
    /// is O(1).
alpar@96
   641
    void spliceFront(ListPath& tpath) {
alpar@96
   642
      if (first) {
alpar@96
   643
        if (tpath.first) {
alpar@96
   644
          first->prev = tpath.last;
alpar@96
   645
          tpath.last->next = first;
alpar@96
   646
          first = tpath.first;
alpar@96
   647
        }
alpar@96
   648
      } else {
alpar@96
   649
        first = tpath.first;
alpar@96
   650
        last = tpath.last;
alpar@96
   651
      }
alpar@96
   652
      tpath.first = tpath.last = 0;
alpar@96
   653
    }
alpar@96
   654
alpar@97
   655
    /// \brief Splice a path into the current path.
alpar@96
   656
    ///
alpar@96
   657
    /// It splices the \c tpath into the current path before the
alpar@96
   658
    /// position of \c it iterator and \c tpath becomes empty. The
alpar@97
   659
    /// time complexity of this function is O(1). If the \c it is
alpar@97
   660
    /// \c INVALID then it will splice behind the current path.
alpar@96
   661
    void splice(ArcIt it, ListPath& tpath) {
alpar@96
   662
      if (it.node) {
alpar@96
   663
        if (tpath.first) {
alpar@96
   664
          tpath.first->prev = it.node->prev;
alpar@96
   665
          if (it.node->prev) {
alpar@96
   666
            it.node->prev->next = tpath.first;
alpar@96
   667
          } else {
alpar@96
   668
            first = tpath.first;
alpar@96
   669
          }
alpar@96
   670
          it.node->prev = tpath.last;
alpar@96
   671
          tpath.last->next = it.node;
alpar@96
   672
        }
alpar@96
   673
      } else {
alpar@96
   674
        if (first) {
alpar@96
   675
          if (tpath.first) {
alpar@96
   676
            last->next = tpath.first;
alpar@96
   677
            tpath.first->prev = last;
alpar@96
   678
            last = tpath.last;
alpar@96
   679
          }
alpar@96
   680
        } else {
alpar@96
   681
          first = tpath.first;
alpar@96
   682
          last = tpath.last;
alpar@96
   683
        }
alpar@96
   684
      }
alpar@96
   685
      tpath.first = tpath.last = 0;
alpar@96
   686
    }
alpar@96
   687
alpar@97
   688
    /// \brief Split the current path.
alpar@96
   689
    ///
alpar@97
   690
    /// It splits the current path into two parts. The part before
alpar@97
   691
    /// the iterator \c it will remain in the current path and the part
alpar@97
   692
    /// starting with
alpar@97
   693
    /// \c it will put into \c tpath. If \c tpath have arcs
alpar@97
   694
    /// before the operation they are removed first.  The time
alpar@97
   695
    /// complexity of this function is O(1) plus the the time of emtying
alpar@97
   696
    /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
alpar@96
   697
    void split(ArcIt it, ListPath& tpath) {
alpar@96
   698
      tpath.clear();
alpar@96
   699
      if (it.node) {
alpar@96
   700
        tpath.first = it.node;
alpar@96
   701
        tpath.last = last;
alpar@96
   702
        if (it.node->prev) {
alpar@96
   703
          last = it.node->prev;
alpar@96
   704
          last->next = 0;
alpar@96
   705
        } else {
alpar@96
   706
          first = last = 0;
alpar@96
   707
        }
alpar@96
   708
        it.node->prev = 0;
alpar@96
   709
      }
alpar@96
   710
    }
alpar@96
   711
alpar@96
   712
alpar@96
   713
    typedef True BuildTag;
alpar@96
   714
alpar@96
   715
    template <typename CPath>
alpar@96
   716
    void build(const CPath& path) {
alpar@96
   717
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
alpar@96
   718
        addBack(it);
alpar@96
   719
      }
alpar@96
   720
    }
alpar@96
   721
alpar@96
   722
    template <typename CPath>
alpar@96
   723
    void buildRev(const CPath& path) {
alpar@96
   724
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
alpar@96
   725
        addFront(it);
alpar@96
   726
      }
alpar@96
   727
    }
alpar@96
   728
alpar@96
   729
  };
alpar@96
   730
alpar@96
   731
  /// \brief A structure for representing directed paths in a digraph.
alpar@96
   732
  ///
alpar@96
   733
  /// A structure for representing directed path in a digraph.
alpar@96
   734
  /// \param Digraph The digraph type in which the path is.
alpar@96
   735
  ///
alpar@96
   736
  /// In a sense, the path can be treated as a list of arcs. The
alpar@96
   737
  /// lemon path type stores just this list. As a consequence it
alpar@97
   738
  /// cannot enumerate the nodes in the path and the source node of
alpar@97
   739
  /// a zero length path is undefined.
alpar@96
   740
  ///
alpar@97
   741
  /// This implementation is completly static, i.e. it can be copy constucted
alpar@97
   742
  /// or copy assigned from another path, but otherwise it cannot be
alpar@97
   743
  /// modified.
alpar@97
   744
  ///
alpar@97
   745
  /// Being the the most memory efficient path type in LEMON,
alpar@97
   746
  /// it is intented to be
alpar@97
   747
  /// used when you want to store a large number of paths.
alpar@96
   748
  template <typename _Digraph>
alpar@96
   749
  class StaticPath {
alpar@96
   750
  public:
alpar@96
   751
alpar@96
   752
    typedef _Digraph Digraph;
alpar@96
   753
    typedef typename Digraph::Arc Arc;
alpar@96
   754
alpar@96
   755
    /// \brief Default constructor
alpar@96
   756
    ///
alpar@96
   757
    /// Default constructor
alpar@96
   758
    StaticPath() : len(0), arcs(0) {}
alpar@96
   759
    
alpar@96
   760
    /// \brief Template copy constructor
alpar@96
   761
    ///
alpar@97
   762
    /// This path can be initialized from any other path type.
alpar@96
   763
    template <typename CPath>
alpar@96
   764
    StaticPath(const CPath& cpath) : arcs(0) {
alpar@96
   765
      copyPath(*this, cpath);
alpar@96
   766
    }
alpar@96
   767
alpar@96
   768
    /// \brief Destructor of the path
alpar@96
   769
    ///
alpar@96
   770
    /// Destructor of the path
alpar@96
   771
    ~StaticPath() {
alpar@96
   772
      if (arcs) delete[] arcs;
alpar@96
   773
    }
alpar@96
   774
alpar@96
   775
    /// \brief Template copy assignment
alpar@96
   776
    ///
alpar@97
   777
    /// This path can be made equal to any other path type. It simply
alpar@96
   778
    /// makes a copy of the given path.
alpar@96
   779
    template <typename CPath>
alpar@96
   780
    StaticPath& operator=(const CPath& cpath) {
alpar@96
   781
      copyPath(*this, cpath);
alpar@96
   782
      return *this;
alpar@96
   783
    }
alpar@96
   784
alpar@96
   785
    /// \brief Iterator class to iterate on the arcs of the paths
alpar@96
   786
    ///
alpar@96
   787
    /// This class is used to iterate on the arcs of the paths
alpar@96
   788
    ///
alpar@96
   789
    /// Of course it converts to Digraph::Arc
alpar@96
   790
    class ArcIt {
alpar@96
   791
      friend class StaticPath;
alpar@96
   792
    public:
alpar@96
   793
      /// Default constructor
alpar@96
   794
      ArcIt() {}
alpar@96
   795
      /// Invalid constructor
alpar@96
   796
      ArcIt(Invalid) : path(0), idx(-1) {}
alpar@96
   797
      /// Initializate the constructor to the first arc of path
alpar@96
   798
      ArcIt(const StaticPath &_path) 
alpar@96
   799
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
alpar@96
   800
alpar@96
   801
    private:
alpar@96
   802
alpar@96
   803
      /// Constructor with starting point
alpar@96
   804
      ArcIt(const StaticPath &_path, int _idx) 
alpar@96
   805
        : idx(_idx), path(&_path) {}
alpar@96
   806
alpar@96
   807
    public:
alpar@96
   808
alpar@96
   809
      ///Conversion to Digraph::Arc
alpar@96
   810
      operator const Arc&() const {
alpar@96
   811
        return path->nth(idx);
alpar@96
   812
      }
alpar@96
   813
alpar@96
   814
      /// Next arc
alpar@96
   815
      ArcIt& operator++() { 
alpar@96
   816
        ++idx;
alpar@96
   817
        if (idx >= path->length()) idx = -1; 
alpar@96
   818
        return *this; 
alpar@96
   819
      }
alpar@96
   820
alpar@96
   821
      /// Comparison operator
alpar@96
   822
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
alpar@96
   823
      /// Comparison operator
alpar@96
   824
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
alpar@96
   825
      /// Comparison operator
alpar@96
   826
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
alpar@96
   827
alpar@96
   828
    private:
alpar@96
   829
      const StaticPath *path;
alpar@96
   830
      int idx;
alpar@96
   831
    };
alpar@96
   832
alpar@97
   833
    /// \brief The nth arc.
alpar@96
   834
    ///
alpar@96
   835
    /// \pre n is in the [0..length() - 1] range
alpar@96
   836
    const Arc& nth(int n) const {
alpar@96
   837
      return arcs[n];
alpar@96
   838
    }
alpar@96
   839
alpar@97
   840
    /// \brief The arc iterator pointing to the nth arc.
alpar@96
   841
    ArcIt nthIt(int n) const {
alpar@96
   842
      return ArcIt(*this, n);
alpar@96
   843
    }
alpar@96
   844
alpar@97
   845
    /// \brief The length of the path.
alpar@96
   846
    int length() const { return len; }
alpar@96
   847
alpar@97
   848
    /// \brief Return true when the path is empty.
alpar@96
   849
    int empty() const { return len == 0; }
alpar@96
   850
alpar@97
   851
    /// \break Erase all arcs in the digraph.
alpar@96
   852
    void clear() {
alpar@96
   853
      len = 0;
alpar@96
   854
      if (arcs) delete[] arcs;
alpar@96
   855
      arcs = 0;
alpar@96
   856
    }
alpar@96
   857
alpar@97
   858
    /// \brief The first arc of the path.
alpar@96
   859
    const Arc& front() const {
alpar@96
   860
      return arcs[0];
alpar@96
   861
    }
alpar@96
   862
alpar@97
   863
    /// \brief The last arc of the path.
alpar@96
   864
    const Arc& back() const {
alpar@96
   865
      return arcs[len - 1];
alpar@96
   866
    }
alpar@96
   867
alpar@96
   868
alpar@96
   869
    typedef True BuildTag;
alpar@96
   870
alpar@96
   871
    template <typename CPath>
alpar@96
   872
    void build(const CPath& path) {
alpar@96
   873
      len = path.length();
alpar@96
   874
      arcs = new Arc[len];
alpar@96
   875
      int index = 0;
alpar@96
   876
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
alpar@96
   877
        arcs[index] = it;
alpar@96
   878
        ++index;
alpar@96
   879
      }
alpar@96
   880
    }
alpar@96
   881
alpar@96
   882
    template <typename CPath>
alpar@96
   883
    void buildRev(const CPath& path) {
alpar@96
   884
      len = path.length();
alpar@96
   885
      arcs = new Arc[len];
alpar@96
   886
      int index = len;
alpar@96
   887
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
alpar@96
   888
        --index;
alpar@96
   889
        arcs[index] = it;
alpar@96
   890
      }
alpar@96
   891
    }
alpar@96
   892
alpar@96
   893
  private:
alpar@96
   894
    int len;
alpar@96
   895
    Arc* arcs;
alpar@96
   896
  };
alpar@96
   897
alpar@98
   898
  ///////////////////////////////////////////////////////////////////////
alpar@98
   899
  // Additional utilities
alpar@98
   900
  ///////////////////////////////////////////////////////////////////////
alpar@98
   901
alpar@98
   902
  namespace _path_bits {
alpar@98
   903
alpar@98
   904
    template <typename Path, typename Enable = void>
alpar@98
   905
    struct RevTagIndicator {
alpar@98
   906
      static const bool value = false;
alpar@98
   907
    };
alpar@98
   908
alpar@98
   909
    template <typename Digraph>
alpar@98
   910
    struct RevTagIndicator<
alpar@98
   911
      Digraph, 
alpar@98
   912
      typename enable_if<typename Digraph::RevTag, void>::type
alpar@98
   913
    > {
alpar@98
   914
      static const bool value = true;
alpar@98
   915
    };
alpar@98
   916
alpar@98
   917
    template <typename Target, typename Source,
alpar@98
   918
              typename BuildEnable = void, typename RevEnable = void>
alpar@98
   919
    struct PathCopySelector {
alpar@98
   920
      static void copy(Target& target, const Source& source) {
alpar@98
   921
        target.clear();
alpar@98
   922
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
alpar@98
   923
          target.addBack(it);
alpar@98
   924
        }
alpar@98
   925
      }
alpar@98
   926
    };
alpar@98
   927
alpar@98
   928
    template <typename Target, typename Source, typename BuildEnable>
alpar@98
   929
    struct PathCopySelector<
alpar@98
   930
      Target, Source, BuildEnable, 
alpar@98
   931
      typename enable_if<typename Source::RevPathTag, void>::type> {
alpar@98
   932
      static void copy(Target& target, const Source& source) {
alpar@98
   933
        target.clear();
alpar@98
   934
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
alpar@98
   935
          target.addFront(it);
alpar@98
   936
        }
alpar@98
   937
      }
alpar@98
   938
    };
alpar@98
   939
alpar@98
   940
    template <typename Target, typename Source, typename RevEnable>
alpar@98
   941
    struct PathCopySelector<
alpar@98
   942
      Target, Source, 
alpar@98
   943
      typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
alpar@98
   944
      static void copy(Target& target, const Source& source) {
alpar@98
   945
        target.clear();
alpar@98
   946
        target.build(source);
alpar@98
   947
      }
alpar@98
   948
    };
alpar@98
   949
alpar@98
   950
    template <typename Target, typename Source>
alpar@98
   951
    struct PathCopySelector<
alpar@98
   952
      Target, Source, 
alpar@98
   953
      typename enable_if<typename Target::BuildTag, void>::type,
alpar@98
   954
      typename enable_if<typename Source::RevPathTag, void>::type> {
alpar@98
   955
      static void copy(Target& target, const Source& source) {
alpar@98
   956
        target.clear();
alpar@98
   957
        target.buildRev(source);
alpar@98
   958
      }
alpar@98
   959
    };
alpar@98
   960
alpar@98
   961
  }
alpar@98
   962
alpar@98
   963
alpar@98
   964
  /// \brief Make a copy of a path.
alpar@98
   965
  ///
alpar@98
   966
  ///  This function makes a copy of a path.
alpar@98
   967
  template <typename Target, typename Source>
alpar@98
   968
  void copyPath(Target& target, const Source& source) {
alpar@98
   969
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
alpar@98
   970
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
alpar@98
   971
  }
alpar@98
   972
alpar@98
   973
  /// \brief Check the consistency of a path.
alpar@98
   974
  ///
alpar@98
   975
  /// This function checks that the target of each arc is the same
alpar@98
   976
  /// as the source of the next one. 
alpar@98
   977
  /// 
alpar@98
   978
  template <typename Digraph, typename Path>
alpar@98
   979
  bool checkPath(const Digraph& digraph, const Path& path) {
alpar@98
   980
    typename Path::ArcIt it(path);
alpar@98
   981
    if (it == INVALID) return true;
alpar@98
   982
    typename Digraph::Node node = digraph.target(it);
alpar@98
   983
    ++it;
alpar@98
   984
    while (it != INVALID) {
alpar@98
   985
      if (digraph.source(it) != node) return false;
alpar@98
   986
      node = digraph.target(it);
alpar@98
   987
      ++it;
alpar@98
   988
    }
alpar@98
   989
    return true;
alpar@98
   990
  }
alpar@98
   991
alpar@98
   992
  /// \brief The source of a path
alpar@98
   993
  ///
alpar@98
   994
  /// This function returns the source of the given path.
alpar@98
   995
  template <typename Digraph, typename Path>
alpar@98
   996
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
alpar@98
   997
    return digraph.source(path.front());
alpar@98
   998
  }
alpar@98
   999
alpar@98
  1000
  /// \brief The target of a path
alpar@98
  1001
  ///
alpar@98
  1002
  /// This function returns the target of the given path.
alpar@98
  1003
  template <typename Digraph, typename Path>
alpar@98
  1004
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
alpar@98
  1005
    return digraph.target(path.back());
alpar@98
  1006
  }
alpar@98
  1007
alpar@98
  1008
  /// \brief Class which helps to iterate through the nodes of a path
alpar@98
  1009
  ///
alpar@98
  1010
  /// In a sense, the path can be treated as a list of arcs. The
alpar@98
  1011
  /// lemon path type stores only this list. As a consequence, it
alpar@98
  1012
  /// cannot enumerate the nodes in the path and the zero length paths
alpar@98
  1013
  /// cannot have a source node.
alpar@98
  1014
  ///
alpar@98
  1015
  /// This class implements the node iterator of a path structure. To
alpar@98
  1016
  /// provide this feature, the underlying digraph should be passed to
alpar@98
  1017
  /// the constructor of the iterator.
alpar@98
  1018
  template <typename Path>
alpar@98
  1019
  class PathNodeIt {
alpar@98
  1020
  private:
alpar@98
  1021
    const typename Path::Digraph *_digraph;
alpar@98
  1022
    typename Path::ArcIt _it;
alpar@98
  1023
    typename Path::Digraph::Node _nd;
alpar@98
  1024
alpar@98
  1025
  public:
alpar@98
  1026
alpar@98
  1027
    typedef typename Path::Digraph Digraph;
alpar@98
  1028
    typedef typename Digraph::Node Node;
alpar@98
  1029
    
alpar@98
  1030
    /// Default constructor
alpar@98
  1031
    PathNodeIt() {}
alpar@98
  1032
    /// Invalid constructor
alpar@98
  1033
    PathNodeIt(Invalid) 
alpar@98
  1034
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
alpar@98
  1035
    /// Constructor
alpar@98
  1036
    PathNodeIt(const Digraph& digraph, const Path& path) 
alpar@98
  1037
      : _digraph(&digraph), _it(path) {
alpar@98
  1038
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
alpar@98
  1039
    }
alpar@98
  1040
    /// Constructor
alpar@98
  1041
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src) 
alpar@98
  1042
      : _digraph(&digraph), _it(path), _nd(src) {}
alpar@98
  1043
alpar@98
  1044
    ///Conversion to Digraph::Node
alpar@98
  1045
    operator Node() const {
alpar@98
  1046
      return _nd;
alpar@98
  1047
    }
alpar@98
  1048
alpar@98
  1049
    /// Next node
alpar@98
  1050
    PathNodeIt& operator++() {
alpar@98
  1051
      if (_it == INVALID) _nd = INVALID;
alpar@98
  1052
      else {
alpar@98
  1053
	_nd = _digraph->target(_it);
alpar@98
  1054
	++_it;
alpar@98
  1055
      }
alpar@98
  1056
      return *this;
alpar@98
  1057
    }
alpar@98
  1058
alpar@98
  1059
    /// Comparison operator
alpar@98
  1060
    bool operator==(const PathNodeIt& n) const { 
alpar@98
  1061
      return _it == n._it && _nd == n._nd; 
alpar@98
  1062
    }
alpar@98
  1063
    /// Comparison operator
alpar@98
  1064
    bool operator!=(const PathNodeIt& n) const { 
alpar@98
  1065
      return _it != n._it || _nd != n._nd; 
alpar@98
  1066
    }
alpar@98
  1067
    /// Comparison operator
alpar@98
  1068
    bool operator<(const PathNodeIt& n) const { 
alpar@98
  1069
      return (_it < n._it && _nd != INVALID);
alpar@98
  1070
    }
alpar@98
  1071
    
alpar@98
  1072
  };
alpar@98
  1073
  
alpar@96
  1074
  ///@}
alpar@96
  1075
alpar@96
  1076
} // namespace lemon
alpar@96
  1077
alpar@96
  1078
#endif // LEMON_PATH_H