[Lemon-commits] Balazs Dezso: Port iterable maps from SVN 3509 (...

Lemon HG hg at lemon.cs.elte.hu
Mon Aug 31 08:27:15 CEST 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/7bda7860e0a8
changeset: 746:7bda7860e0a8
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Sat Jun 27 13:07:26 2009 +0200
description:
	Port iterable maps from SVN 3509 (#73)

diffstat:

 lemon/maps.h      |  901 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 test/maps_test.cc |  187 +++++++++++
 2 files changed, 1082 insertions(+), 6 deletions(-)

diffs (truncated from 1156 to 300 lines):

diff --git a/lemon/maps.h b/lemon/maps.h
--- a/lemon/maps.h
+++ b/lemon/maps.h
@@ -24,6 +24,7 @@
 #include <vector>
 
 #include <lemon/core.h>
+#include <lemon/smart_graph.h>
 
 ///\file
 ///\ingroup maps
@@ -1818,7 +1819,7 @@
   /// \brief Provides an immutable and unique id for each item in a graph.
   ///
   /// IdMap provides a unique and immutable id for each item of the
-  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
+  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
   ///  - \b unique: different items get different ids,
   ///  - \b immutable: the id of an item does not change (even if you
   ///    delete other nodes).
@@ -2004,7 +2005,7 @@
       if (it != _inv_map.end() && it->second == key) {
         _inv_map.erase(it);
       }
-      _inv_map.insert(make_pair(val, key));
+      _inv_map.insert(std::make_pair(val, key));
       Map::set(key, val);
     }
 
@@ -2254,7 +2255,7 @@
     }
 
     /// \brief Gives back the item belonging to a \e RangeId
-    /// 
+    ///
     /// Gives back the item belonging to a \e RangeId.
     Item operator()(int id) const {
       return _inv_map[id];
@@ -2311,6 +2312,894 @@
     }
   };
 
+  /// \brief Dynamic iterable bool map.
+  ///
+  /// This class provides a special graph map type which can store for
+  /// each graph item(node, arc, edge, etc.) a bool value. For both
+  /// the true and the false values it is possible to iterate on the
+  /// keys.
+  ///
+  /// \param GR The graph type.
+  /// \param ITEM One of the graph's item types, the key of the map.
+  template <typename GR, typename ITEM>
+  class IterableBoolMap
+    : protected ItemSetTraits<GR, ITEM>::template Map<int>::Type {
+  private:
+    typedef GR Graph;
+
+    typedef typename ItemSetTraits<Graph, ITEM>::ItemIt KeyIt;
+    typedef typename ItemSetTraits<GR, ITEM>::template Map<int>::Type Parent;
+
+    std::vector<ITEM> _array;
+    int _sep;
+
+  public:
+
+    /// Indicates that the map if reference map.
+    typedef True ReferenceMapTag;
+
+    /// The key type
+    typedef ITEM Key;
+    /// The value type
+    typedef bool Value;
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+  private:
+
+    int position(const Key& key) const {
+      return Parent::operator[](key);
+    }
+
+  public:
+
+    /// \brief Refernce to the value of the map.
+    ///
+    /// This class is similar to the bool type. It can be converted to
+    /// bool and it provides the same operators.
+    class Reference {
+      friend class IterableBoolMap;
+    private:
+      Reference(IterableBoolMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<bool>(value));
+         return *this;
+      }
+
+      operator bool() const {
+        return static_cast<const IterableBoolMap&>(_map)[_key];
+      }
+
+      Reference& operator=(bool value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator&=(bool value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(bool value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(bool value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+    private:
+      Key _key;
+      IterableBoolMap& _map;
+    };
+
+    /// \brief Constructor of the map with a default value.
+    ///
+    /// Constructor of the map with a default value.
+    explicit IterableBoolMap(const Graph& graph, bool def = false)
+      : Parent(graph) {
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = (def ? _array.size() : 0);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    bool operator[](const Key& key) const {
+      return position(key) < _sep;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, bool value) {
+      int pos = position(key);
+      if (value) {
+        if (pos < _sep) return;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+        ++_sep;
+      } else {
+        if (pos >= _sep) return;
+        --_sep;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+      }
+    }
+
+    /// \brief Set all items.
+    ///
+    /// Set all items in the map.
+    /// \note Constant time operation.
+    void setAll(bool value) {
+      _sep = (value ? _array.size() : 0);
+    }
+
+    /// \brief Returns the number of the keys mapped to true.
+    ///
+    /// Returns the number of the keys mapped to true.
+    int trueNum() const {
+      return _sep;
+    }
+
+    /// \brief Returns the number of the keys mapped to false.
+    ///
+    /// Returns the number of the keys mapped to false.
+    int falseNum() const {
+      return _array.size() - _sep;
+    }
+
+    /// \brief Iterator for the keys mapped to true.
+    ///
+    /// Iterator for the keys mapped to true. It works
+    /// like a graph item iterator in the map, it can be converted
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to
+    /// \c INVALID.
+    class TrueIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys which mapped to true.
+      /// \param map The IterableIntMap
+      explicit TrueIt(const IterableBoolMap& map)
+        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
+          _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the key to be invalid.
+      /// \sa Invalid for more details.
+      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      TrueIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to false.
+    ///
+    /// Iterator for the keys mapped to false. It works
+    /// like a graph item iterator in the map, it can be converted
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to
+    /// \c INVALID.
+    class FalseIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys which mapped to false.
+      /// \param map The IterableIntMap
+      explicit FalseIt(const IterableBoolMap& map)
+        : Parent(map._sep < int(map._array.size()) ?
+                 map._array.back() : INVALID), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the key to be invalid.
+      /// \sa Invalid for more details.
+      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      FalseIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to a given value.
+    ///
+    /// Iterator for the keys mapped to a given value. It works
+    /// like a graph item iterator in the map, it can be converted
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys which mapped to false.
+      /// \param map The IterableIntMap
+      /// \param value Which elements should be iterated.
+      ItemIt(const IterableBoolMap& map, bool value)
+        : Parent(value ? 
+                 (map._sep > 0 ?
+                  map._array[map._sep - 1] : INVALID) :
+                 (map._sep < int(map._array.size()) ?
+                  map._array.back() : INVALID)), _map(&map) {}



More information about the Lemon-commits mailing list