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