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