[Lemon-commits] [lemon_svn] deba: r2281 - hugo/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:51:29 CET 2006
Author: deba
Date: Wed Nov 2 16:25:13 2005
New Revision: 2281
Modified:
hugo/trunk/lemon/iterable_maps.h
Log:
IterableIntMap
todo: documentation need
Modified: hugo/trunk/lemon/iterable_maps.h
==============================================================================
--- hugo/trunk/lemon/iterable_maps.h (original)
+++ hugo/trunk/lemon/iterable_maps.h Wed Nov 2 16:25:13 2005
@@ -14,6 +14,8 @@
*
*/
+#include <lemon/traits.h>
+#include <lemon/invalid.h>
#include <vector>
#include <limits>
@@ -246,5 +248,197 @@
};
};
+
+ namespace _iterable_maps_bits {
+ template <typename Item>
+ struct IterableIntMapNode {
+ IterableIntMapNode() : value(-1) {}
+ Item prev, next;
+ int value;
+ };
+ }
+
+ ///\ingroup maps
+ ///
+ /// \brief Dynamic iterable integer map.
+ ///
+ /// \todo Document please
+ template <typename _Graph, typename _Item>
+ class IterableIntMap : protected ItemSetTraits<_Graph, _Item>
+ ::template Map<_iterable_maps_bits::IterableIntMapNode<_Item> >::Parent {
+ public:
+ typedef typename ItemSetTraits<_Graph, _Item>
+ ::template Map<_iterable_maps_bits::IterableIntMapNode<_Item> >
+ ::Parent Parent;
+
+ typedef _Item Key;
+ typedef int Value;
+ typedef _Graph Graph;
+
+ IterableIntMap(const Graph& graph) : Parent(graph) {}
+
+ private:
+
+ void unlace(const Key& key) {
+ typename Parent::Value& node = Parent::operator[](key);
+ if (node.value < 0) return;
+ if (node.prev != INVALID) {
+ Parent::operator[](node.prev).next = node.next;
+ } else {
+ first[node.value] = node.next;
+ }
+ if (node.next != INVALID) {
+ Parent::operator[](node.next).prev = node.prev;
+ }
+ while (!first.empty() && first.back() == INVALID) {
+ first.pop_back();
+ }
+ }
+
+ void lace(const Key& key) {
+ typename Parent::Value& node = Parent::operator[](key);
+ if (node.value < 0) return;
+ if (node.value >= (int)first.size()) {
+ first.resize(node.value + 1, INVALID);
+ }
+ node.prev = INVALID;
+ node.next = first[node.value];
+ if (node.next != INVALID) {
+ Parent::operator[](node.next).prev = key;
+ }
+ first[node.value] = key;
+ }
+
+ public:
+
+ typedef True ReferenceMapTag;
+
+ class Reference {
+ friend class IterableIntMap;
+ private:
+ Reference(IterableIntMap& map, const Key& key)
+ : _key(key), _map(map) {}
+ public:
+
+ Reference& operator=(const Reference& value) {
+ _map.set(_key, (const int&)value);
+ return *this;
+ }
+
+ operator const int&() const {
+ return static_cast<const IterableIntMap&>(_map)[_key];
+ }
+
+ Reference& operator=(int value) {
+ _map.set(_key, value);
+ return *this;
+ }
+ Reference& operator+=(int value) {
+ _map.set(_key, _map[_key] + value);
+ return *this;
+ }
+ Reference& operator-=(int value) {
+ _map.set(_key, _map[_key] - value);
+ return *this;
+ }
+ Reference& operator*=(int value) {
+ _map.set(_key, _map[_key] * value);
+ return *this;
+ }
+ Reference& operator/=(int value) {
+ _map.set(_key, _map[_key] / value);
+ return *this;
+ }
+ Reference& operator%=(int value) {
+ _map.set(_key, _map[_key] % value);
+ return *this;
+ }
+ Reference& operator&=(int value) {
+ _map.set(_key, _map[_key] & value);
+ return *this;
+ }
+ Reference& operator|=(int value) {
+ _map.set(_key, _map[_key] | value);
+ return *this;
+ }
+ Reference& operator^=(int value) {
+ _map.set(_key, _map[_key] ^ value);
+ return *this;
+ }
+ Reference& operator<<=(int value) {
+ _map.set(_key, _map[_key] << value);
+ return *this;
+ }
+ Reference& operator>>=(int value) {
+ _map.set(_key, _map[_key] >> value);
+ return *this;
+ }
+
+ private:
+ Key _key;
+ IterableIntMap& _map;
+ };
+
+ typedef const Value& ConstReference;
+
+ int size() const {
+ return (int)first.size();
+ }
+
+ void set(const Key& key, const Value& value) {
+ unlace(key);
+ Parent::operator[](key).value = value;
+ lace(key);
+ }
+
+ const Value& operator[](const Key& key) const {
+ return Parent::operator[](key).value;
+ }
+
+ Reference operator[](const Key& key) {
+ return Reference(*this, key);
+ }
+
+ class ItemIt : public _Item {
+ public:
+ typedef _Item Parent;
+
+ ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+ ItemIt(const IterableIntMap& map, int value) : _map(&map) {
+ if (value < 0 || value >= (int)_map->first.size()) {
+ Parent::operator=(INVALID);
+ } else {
+ Parent::operator=(_map->first[value]);
+ }
+ }
+
+ ItemIt& operator++() {
+ Parent::operator=(_map->IterableIntMap::Parent::
+ operator[](static_cast<Parent&>(*this)).next);
+ return *this;
+ }
+
+
+ private:
+ const IterableIntMap* _map;
+ };
+
+ protected:
+
+ virtual void erase(const Key& key) {
+ unlace(key);
+ Parent::erase(key);
+ }
+
+ virtual void clear() {
+ first.clear();
+ Parent::clear();
+ }
+
+ private:
+ std::vector<_Item> first;
+ };
+
/// @}
}
More information about the Lemon-commits
mailing list