COIN-OR::LEMON - Graph Library

Ticket #631: ticket631.diff

File ticket631.diff, 87.9 KB (added by David Torres Sanchez, 11 months ago)

Mostly clang-format (sorry!), added AllocatorTraits::construct and destroy

  • lemon/bits/array_map.h

    diff -r ddda48feae8b lemon/bits/array_map.h
    a b  
    1919#ifndef LEMON_BITS_ARRAY_MAP_H
    2020#define LEMON_BITS_ARRAY_MAP_H
    2121
    22 #include <memory>
    23 
     22#include <lemon/bits/alteration_notifier.h>
    2423#include <lemon/bits/traits.h>
    25 #include <lemon/bits/alteration_notifier.h>
    2624#include <lemon/concept_check.h>
    2725#include <lemon/concepts/maps.h>
    2826
     27#include <memory>
     28
    2929// \ingroup graphbits
    3030// \file
    3131// \brief Graph map based on the array storage.
    3232
    3333namespace lemon {
    3434
    35   // \ingroup graphbits
    36   //
    37   // \brief Graph map based on the array storage.
    38   //
    39   // The ArrayMap template class is graph map structure that automatically
    40   // updates the map when a key is added to or erased from the graph.
    41   // This map uses the allocators to implement the container functionality.
    42   //
    43   // The template parameters are the Graph, the current Item type and
    44   // the Value type of the map.
    45   template <typename _Graph, typename _Item, typename _Value>
    46   class ArrayMap
     35// \ingroup graphbits
     36//
     37// \brief Graph map based on the array storage.
     38//
     39// The ArrayMap template class is graph map structure that automatically
     40// updates the map when a key is added to or erased from the graph.
     41// This map uses the allocators to implement the container functionality.
     42//
     43// The template parameters are the Graph, the current Item type and
     44// the Value type of the map.
     45template<typename _Graph, typename _Item, typename _Value>
     46class ArrayMap
    4747    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
    48   public:
    49     // The graph type.
    50     typedef _Graph GraphType;
    51     // The item type.
    52     typedef _Item Item;
    53     // The reference map tag.
    54     typedef True ReferenceMapTag;
     48 public:
     49  // The graph type.
     50  typedef _Graph GraphType;
     51  // The item type.
     52  typedef _Item Item;
     53  // The reference map tag.
     54  typedef True ReferenceMapTag;
     55
     56  // The key type of the map.
     57  typedef _Item Key;
     58  // The value type of the map.
     59  typedef _Value Value;
    5560
    56     // The key type of the map.
    57     typedef _Item Key;
    58     // The value type of the map.
    59     typedef _Value Value;
     61  // The const reference type of the map.
     62  typedef const _Value& ConstReference;
     63  // The reference type of the map.
     64  typedef _Value& Reference;
     65
     66  // The map type.
     67  typedef ArrayMap Map;
     68
     69  // The notifier type.
     70  typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
     71
     72 private:
     73  // The MapBase of the Map which imlements the core regisitry function.
     74  typedef typename Notifier::ObserverBase Parent;
     75
     76  typedef std::allocator<Value>                        Allocator;
     77  typedef std::allocator_traits<std::allocator<Value>> AllocatorTraits;
    6078
    61     // The const reference type of the map.
    62     typedef const _Value& ConstReference;
    63     // The reference type of the map.
    64     typedef _Value& Reference;
    65 
    66     // The map type.
    67     typedef ArrayMap Map;
    68 
    69     // The notifier type.
    70     typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
    71 
    72   private:
    73 
    74     // The MapBase of the Map which imlements the core regisitry function.
    75     typedef typename Notifier::ObserverBase Parent;
     79 public:
     80  // \brief Graph initialized map constructor.
     81  //
     82  // Graph initialized map constructor.
     83  explicit ArrayMap(const GraphType& graph) {
     84    Parent::attach(graph.notifier(Item()));
     85    allocate_memory();
     86    Notifier* nf = Parent::notifier();
     87    Item      it;
     88    for (nf->first(it); it != INVALID; nf->next(it)) {
     89      int id = nf->id(it);
     90      ;
     91      AllocatorTraits::construct(allocator, &(values[id]), Value());
     92    }
     93  }
    7694
    77     typedef std::allocator<Value> Allocator;
    78 
    79   public:
     95  // \brief Constructor to use default value to initialize the map.
     96  //
     97  // It constructs a map and initialize all of the the map.
     98  ArrayMap(const GraphType& graph, const Value& value) {
     99    Parent::attach(graph.notifier(Item()));
     100    allocate_memory();
     101    Notifier* nf = Parent::notifier();
     102    Item      it;
     103    for (nf->first(it); it != INVALID; nf->next(it)) {
     104      int id = nf->id(it);
     105      ;
     106      AllocatorTraits::construct(allocator, &(values[id]), value);
     107    }
     108  }
    80109
    81     // \brief Graph initialized map constructor.
    82     //
    83     // Graph initialized map constructor.
    84     explicit ArrayMap(const GraphType& graph) {
    85       Parent::attach(graph.notifier(Item()));
    86       allocate_memory();
    87       Notifier* nf = Parent::notifier();
    88       Item it;
    89       for (nf->first(it); it != INVALID; nf->next(it)) {
    90         int id = nf->id(it);;
    91         allocator.construct(&(values[id]), Value());
    92       }
     110 private:
     111  // \brief Constructor to copy a map of the same map type.
     112  //
     113  // Constructor to copy a map of the same map type.
     114  ArrayMap(const ArrayMap& copy) : Parent() {
     115    if (copy.attached()) {
     116      attach(*copy.notifier());
    93117    }
     118    capacity = copy.capacity;
     119    if (capacity == 0)
     120      return;
     121    values       = allocator.allocate(capacity);
     122    Notifier* nf = Parent::notifier();
     123    Item      it;
     124    for (nf->first(it); it != INVALID; nf->next(it)) {
     125      int id = nf->id(it);
     126      ;
     127      AllocatorTraits::construct(allocator, &(values[id]), copy.values[id]);
     128    }
     129  }
    94130
    95     // \brief Constructor to use default value to initialize the map.
    96     //
    97     // It constructs a map and initialize all of the the map.
    98     ArrayMap(const GraphType& graph, const Value& value) {
    99       Parent::attach(graph.notifier(Item()));
    100       allocate_memory();
    101       Notifier* nf = Parent::notifier();
    102       Item it;
    103       for (nf->first(it); it != INVALID; nf->next(it)) {
    104         int id = nf->id(it);;
    105         allocator.construct(&(values[id]), value);
    106       }
    107     }
     131  // \brief Assign operator.
     132  //
     133  // This operator assigns for each item in the map the
     134  // value mapped to the same item in the copied map.
     135  // The parameter map should be indiced with the same
     136  // itemset because this assign operator does not change
     137  // the container of the map.
     138  ArrayMap& operator=(const ArrayMap& cmap) {
     139    return operator=<ArrayMap>(cmap);
     140  }
    108141
    109   private:
    110     // \brief Constructor to copy a map of the same map type.
    111     //
    112     // Constructor to copy a map of the same map type.
    113     ArrayMap(const ArrayMap& copy) : Parent() {
    114       if (copy.attached()) {
    115         attach(*copy.notifier());
    116       }
    117       capacity = copy.capacity;
    118       if (capacity == 0) return;
    119       values = allocator.allocate(capacity);
    120       Notifier* nf = Parent::notifier();
    121       Item it;
    122       for (nf->first(it); it != INVALID; nf->next(it)) {
    123         int id = nf->id(it);;
    124         allocator.construct(&(values[id]), copy.values[id]);
    125       }
     142  // \brief Template assign operator.
     143  //
     144  // The given parameter should conform to the ReadMap
     145  // concecpt and could be indiced by the current item set of
     146  // the NodeMap. In this case the value for each item
     147  // is assigned by the value of the given ReadMap.
     148  template<typename CMap>
     149  ArrayMap& operator=(const CMap& cmap) {
     150    checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
     151    const typename Parent::Notifier* nf = Parent::notifier();
     152    Item                             it;
     153    for (nf->first(it); it != INVALID; nf->next(it)) {
     154      set(it, cmap[it]);
    126155    }
     156    return *this;
     157  }
     158
     159 public:
     160  // \brief The destructor of the map.
     161  //
     162  // The destructor of the map.
     163  virtual ~ArrayMap() {
     164    if (attached()) {
     165      clear();
     166      detach();
     167    }
     168  }
     169
     170 protected:
     171  using Parent::attach;
     172  using Parent::attached;
     173  using Parent::detach;
     174
     175 public:
     176  // \brief The subscript operator.
     177  //
     178  // The subscript operator. The map can be subscripted by the
     179  // actual keys of the graph.
     180  Value& operator[](const Key& key) {
     181    int id = Parent::notifier()->id(key);
     182    return values[id];
     183  }
    127184
    128     // \brief Assign operator.
    129     //
    130     // This operator assigns for each item in the map the
    131     // value mapped to the same item in the copied map.
    132     // The parameter map should be indiced with the same
    133     // itemset because this assign operator does not change
    134     // the container of the map.
    135     ArrayMap& operator=(const ArrayMap& cmap) {
    136       return operator=<ArrayMap>(cmap);
    137     }
     185  // \brief The const subscript operator.
     186  //
     187  // The const subscript operator. The map can be subscripted by the
     188  // actual keys of the graph.
     189  const Value& operator[](const Key& key) const {
     190    int id = Parent::notifier()->id(key);
     191    return values[id];
     192  }
    138193
     194  // \brief Setter function of the map.
     195  //
     196  // Setter function of the map. Equivalent with map[key] = val.
     197  // This is a compatibility feature with the not dereferable maps.
     198  void set(const Key& key, const Value& val) { (*this)[key] = val; }
    139199
    140     // \brief Template assign operator.
    141     //
    142     // The given parameter should conform to the ReadMap
    143     // concecpt and could be indiced by the current item set of
    144     // the NodeMap. In this case the value for each item
    145     // is assigned by the value of the given ReadMap.
    146     template <typename CMap>
    147     ArrayMap& operator=(const CMap& cmap) {
    148       checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
    149       const typename Parent::Notifier* nf = Parent::notifier();
    150       Item it;
     200 protected:
     201  // \brief Adds a new key to the map.
     202  //
     203  // It adds a new key to the map. It is called by the observer notifier
     204  // and it overrides the add() member function of the observer base.
     205  virtual void add(const Key& key) {
     206    Notifier* nf = Parent::notifier();
     207    int       id = nf->id(key);
     208    if (id >= capacity) {
     209      int new_capacity = (capacity == 0 ? 1 : capacity);
     210      while (new_capacity <= id) {
     211        new_capacity <<= 1;
     212      }
     213      Value* new_values = allocator.allocate(new_capacity);
     214      Item   it;
    151215      for (nf->first(it); it != INVALID; nf->next(it)) {
    152         set(it, cmap[it]);
     216        int jd = nf->id(it);
     217        ;
     218        if (id != jd) {
     219          AllocatorTraits::construct(allocator, &(new_values[jd]), values[jd]);
     220          AllocatorTraits::destroy(allocator, &(values[jd]));
     221        }
    153222      }
    154       return *this;
     223      if (capacity != 0)
     224        allocator.deallocate(values, capacity);
     225      values   = new_values;
     226      capacity = new_capacity;
    155227    }
     228    AllocatorTraits::construct(allocator, &(values[id]), Value());
     229  }
    156230
    157   public:
    158     // \brief The destructor of the map.
    159     //
    160     // The destructor of the map.
    161     virtual ~ArrayMap() {
    162       if (attached()) {
    163         clear();
    164         detach();
     231  // \brief Adds more new keys to the map.
     232  //
     233  // It adds more new keys to the map. It is called by the observer notifier
     234  // and it overrides the add() member function of the observer base.
     235  virtual void add(const std::vector<Key>& keys) {
     236    Notifier* nf     = Parent::notifier();
     237    int       max_id = -1;
     238    for (int i = 0; i < int(keys.size()); ++i) {
     239      int id = nf->id(keys[i]);
     240      if (id > max_id) {
     241        max_id = id;
    165242      }
    166243    }
    167 
    168   protected:
    169 
    170     using Parent::attach;
    171     using Parent::detach;
    172     using Parent::attached;
    173 
    174   public:
    175 
    176     // \brief The subscript operator.
    177     //
    178     // The subscript operator. The map can be subscripted by the
    179     // actual keys of the graph.
    180     Value& operator[](const Key& key) {
    181       int id = Parent::notifier()->id(key);
    182       return values[id];
    183     }
    184 
    185     // \brief The const subscript operator.
    186     //
    187     // The const subscript operator. The map can be subscripted by the
    188     // actual keys of the graph.
    189     const Value& operator[](const Key& key) const {
    190       int id = Parent::notifier()->id(key);
    191       return values[id];
    192     }
    193 
    194     // \brief Setter function of the map.
    195     //
    196     // Setter function of the map. Equivalent with map[key] = val.
    197     // This is a compatibility feature with the not dereferable maps.
    198     void set(const Key& key, const Value& val) {
    199       (*this)[key] = val;
    200     }
    201 
    202   protected:
    203 
    204     // \brief Adds a new key to the map.
    205     //
    206     // It adds a new key to the map. It is called by the observer notifier
    207     // and it overrides the add() member function of the observer base.
    208     virtual void add(const Key& key) {
    209       Notifier* nf = Parent::notifier();
    210       int id = nf->id(key);
    211       if (id >= capacity) {
    212         int new_capacity = (capacity == 0 ? 1 : capacity);
    213         while (new_capacity <= id) {
    214           new_capacity <<= 1;
    215         }
    216         Value* new_values = allocator.allocate(new_capacity);
    217         Item it;
    218         for (nf->first(it); it != INVALID; nf->next(it)) {
    219           int jd = nf->id(it);;
    220           if (id != jd) {
    221             allocator.construct(&(new_values[jd]), values[jd]);
    222             allocator.destroy(&(values[jd]));
     244    if (max_id >= capacity) {
     245      int new_capacity = (capacity == 0 ? 1 : capacity);
     246      while (new_capacity <= max_id) {
     247        new_capacity <<= 1;
     248      }
     249      Value* new_values = allocator.allocate(new_capacity);
     250      Item   it;
     251      for (nf->first(it); it != INVALID; nf->next(it)) {
     252        int  id    = nf->id(it);
     253        bool found = false;
     254        for (int i = 0; i < int(keys.size()); ++i) {
     255          int jd = nf->id(keys[i]);
     256          if (id == jd) {
     257            found = true;
     258            break;
    223259          }
    224260        }
    225         if (capacity != 0) allocator.deallocate(values, capacity);
    226         values = new_values;
    227         capacity = new_capacity;
    228       }
    229       allocator.construct(&(values[id]), Value());
    230     }
    231 
    232     // \brief Adds more new keys to the map.
    233     //
    234     // It adds more new keys to the map. It is called by the observer notifier
    235     // and it overrides the add() member function of the observer base.
    236     virtual void add(const std::vector<Key>& keys) {
    237       Notifier* nf = Parent::notifier();
    238       int max_id = -1;
    239       for (int i = 0; i < int(keys.size()); ++i) {
    240         int id = nf->id(keys[i]);
    241         if (id > max_id) {
    242           max_id = id;
    243         }
     261        if (found)
     262          continue;
     263        AllocatorTraits::construct(allocator, &(new_values[id]), values[id]);
     264        AllocatorTraits::destroy(allocator, &(values[id]));
    244265      }
    245       if (max_id >= capacity) {
    246         int new_capacity = (capacity == 0 ? 1 : capacity);
    247         while (new_capacity <= max_id) {
    248           new_capacity <<= 1;
    249         }
    250         Value* new_values = allocator.allocate(new_capacity);
    251         Item it;
    252         for (nf->first(it); it != INVALID; nf->next(it)) {
    253           int id = nf->id(it);
    254           bool found = false;
    255           for (int i = 0; i < int(keys.size()); ++i) {
    256             int jd = nf->id(keys[i]);
    257             if (id == jd) {
    258               found = true;
    259               break;
    260             }
    261           }
    262           if (found) continue;
    263           allocator.construct(&(new_values[id]), values[id]);
    264           allocator.destroy(&(values[id]));
    265         }
    266         if (capacity != 0) allocator.deallocate(values, capacity);
    267         values = new_values;
    268         capacity = new_capacity;
    269       }
    270       for (int i = 0; i < int(keys.size()); ++i) {
    271         int id = nf->id(keys[i]);
    272         allocator.construct(&(values[id]), Value());
    273       }
     266      if (capacity != 0)
     267        allocator.deallocate(values, capacity);
     268      values   = new_values;
     269      capacity = new_capacity;
     270    }
     271    for (int i = 0; i < int(keys.size()); ++i) {
     272      int id = nf->id(keys[i]);
     273      AllocatorTraits::construct(allocator, &(values[id]), Value());
    274274    }
     275  }
    275276
    276     // \brief Erase a key from the map.
    277     //
    278     // Erase a key from the map. It is called by the observer notifier
    279     // and it overrides the erase() member function of the observer base.
    280     virtual void erase(const Key& key) {
    281       int id = Parent::notifier()->id(key);
    282       allocator.destroy(&(values[id]));
     277  // \brief Erase a key from the map.
     278  //
     279  // Erase a key from the map. It is called by the observer notifier
     280  // and it overrides the erase() member function of the observer base.
     281  virtual void erase(const Key& key) {
     282    int id = Parent::notifier()->id(key);
     283    AllocatorTraits::destroy(allocator, &(values[id]));
     284  }
     285
     286  // \brief Erase more keys from the map.
     287  //
     288  // Erase more keys from the map. It is called by the observer notifier
     289  // and it overrides the erase() member function of the observer base.
     290  virtual void erase(const std::vector<Key>& keys) {
     291    for (int i = 0; i < int(keys.size()); ++i) {
     292      int id = Parent::notifier()->id(keys[i]);
     293      AllocatorTraits::destroy(allocator, &(values[id]));
    283294    }
     295  }
    284296
    285     // \brief Erase more keys from the map.
    286     //
    287     // Erase more keys from the map. It is called by the observer notifier
    288     // and it overrides the erase() member function of the observer base.
    289     virtual void erase(const std::vector<Key>& keys) {
    290       for (int i = 0; i < int(keys.size()); ++i) {
    291         int id = Parent::notifier()->id(keys[i]);
    292         allocator.destroy(&(values[id]));
    293       }
     297  // \brief Builds the map.
     298  //
     299  // It builds the map. It is called by the observer notifier
     300  // and it overrides the build() member function of the observer base.
     301  virtual void build() {
     302    Notifier* nf = Parent::notifier();
     303    allocate_memory();
     304    Item it;
     305    for (nf->first(it); it != INVALID; nf->next(it)) {
     306      int id = nf->id(it);
     307      ;
     308      AllocatorTraits::construct(allocator, &(values[id]), Value());
    294309    }
     310  }
    295311
    296     // \brief Builds the map.
    297     //
    298     // It builds the map. It is called by the observer notifier
    299     // and it overrides the build() member function of the observer base.
    300     virtual void build() {
    301       Notifier* nf = Parent::notifier();
    302       allocate_memory();
     312  // \brief Clear the map.
     313  //
     314  // It erase all items from the map. It is called by the observer notifier
     315  // and it overrides the clear() member function of the observer base.
     316  virtual void clear() {
     317    Notifier* nf = Parent::notifier();
     318    if (capacity != 0) {
    303319      Item it;
    304320      for (nf->first(it); it != INVALID; nf->next(it)) {
    305         int id = nf->id(it);;
    306         allocator.construct(&(values[id]), Value());
     321        int id = nf->id(it);
     322        AllocatorTraits::destroy(allocator, &(values[id]));
    307323      }
     324      allocator.deallocate(values, capacity);
     325      capacity = 0;
    308326    }
    309 
    310     // \brief Clear the map.
    311     //
    312     // It erase all items from the map. It is called by the observer notifier
    313     // and it overrides the clear() member function of the observer base.
    314     virtual void clear() {
    315       Notifier* nf = Parent::notifier();
    316       if (capacity != 0) {
    317         Item it;
    318         for (nf->first(it); it != INVALID; nf->next(it)) {
    319           int id = nf->id(it);
    320           allocator.destroy(&(values[id]));
    321         }
    322         allocator.deallocate(values, capacity);
    323         capacity = 0;
    324       }
    325     }
     327  }
    326328
    327   private:
     329 private:
     330  void allocate_memory() {
     331    int max_id = Parent::notifier()->maxId();
     332    if (max_id == -1) {
     333      capacity = 0;
     334      values   = 0;
     335      return;
     336    }
     337    capacity = 1;
     338    while (capacity <= max_id) {
     339      capacity <<= 1;
     340    }
     341    values = allocator.allocate(capacity);
     342  }
    328343
    329     void allocate_memory() {
    330       int max_id = Parent::notifier()->maxId();
    331       if (max_id == -1) {
    332         capacity = 0;
    333         values = 0;
    334         return;
    335       }
    336       capacity = 1;
    337       while (capacity <= max_id) {
    338         capacity <<= 1;
    339       }
    340       values = allocator.allocate(capacity);
    341     }
     344  int       capacity;
     345  Value*    values;
     346  Allocator allocator;
     347};
    342348
    343     int capacity;
    344     Value* values;
    345     Allocator allocator;
    346 
    347   };
    348 
    349 }
     349} // namespace lemon
    350350
    351351#endif
  • lemon/path.h

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