# HG changeset patch # User deba # Date 1141640917 0 # Node ID 2ff283124dfc0f0800b209ab2e9f620fe4e9b809 # Parent 2ba916d7aae314c4bbb9a11884024426f407557a Clarifing alteration observing system It is directly connected now to a container diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/Makefile.am --- a/lemon/Makefile.am Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/Makefile.am Mon Mar 06 10:28:37 2006 +0000 @@ -84,8 +84,8 @@ tolerance.h \ bits/alteration_notifier.h \ bits/array_map.h \ + bits/base_extender.h \ bits/default_map.h \ - bits/static_map.h \ bits/vector_map.h \ bits/map_extender.h \ bits/graph_extender.h \ diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/alteration_notifier.h --- a/lemon/bits/alteration_notifier.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/alteration_notifier.h Mon Mar 06 10:28:37 2006 +0000 @@ -16,48 +16,91 @@ * */ -#ifndef LEMON_ALTERATION_NOTIFIER_H -#define LEMON_ALTERATION_NOTIFIER_H +#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H +#define LEMON_BITS_ALTERATION_NOTIFIER_H #include -#include + +#include ///\ingroup graphbits ///\file -///\brief Observer registry for graph alteration observers. +///\brief Observer notifier for graph alteration observers. namespace lemon { - /// \addtogroup graphbits - /// @{ - - /// \brief Registry class to register objects observes alterations in - /// the graph. + /// \ingroup graphbits /// - /// This class is a registry for the objects which observe the - /// alterations in a container. The alteration observers can be attached - /// to and detached from the registry. The observers have to inherit - /// from the \ref AlterationNotifier::ObserverBase and override - /// the virtual functions in that. + /// \brief Notifier class to notify observes about alterations in + /// a container. /// - /// The most important application of the alteration observing is the - /// dynamic map implementation. + /// The simple graph's can be refered as two containers, one node container + /// and one edge container. But they are not standard containers they + /// does not store values directly they are just key continars for more + /// value containers which are the node and edge maps. /// - /// \param _Item The item type what the observers are observing, usually - /// edge or node. + /// The graph's node and edge sets can be changed as we add or erase + /// nodes and edges in the graph. Lemon would like to handle easily + /// that the node and edge maps should contain values for all nodes or + /// edges. If we want to check on every indicing if the map contains + /// the current indicing key that cause a drawback in the performance + /// in the library. We use an other solution we notify all maps about + /// an alteration in the graph, which cause only drawback on the + /// alteration of the graph. + /// + /// This class provides an interface to the container. The \e first() and \e + /// next() member functions make possible to iterate on the keys of the + /// container. The \e id() function returns an integer id for each key. + /// The \e maxId() function gives back an upper bound of the ids. + /// + /// For the proper functonality of this class, we should notify it + /// about each alteration in the container. The alterations have four type + /// as \e add(), \e erase(), \e build() and \e clear(). The \e add() and + /// \e erase() signals that only one or few items added or erased to or + /// from the graph. If all items are erased from the graph or from an empty + /// graph a new graph is builded then it can be signaled with the + /// clear() and build() members. Important rule that if we erase items + /// from graph we should first signal the alteration and after that erase + /// them from the container, on the other way on item addition we should + /// first extend the container and just after that signal the alteration. + /// + /// The alteration can be observed with a class inherited from the + /// \e ObserverBase nested class. The signals can be handled with + /// overriding the virtual functions defined in the base class. + /// The observer base can be attached to the notifier with the + /// \e attach() member and can be detached with detach() function. + /// + /// Alteration observers try to be exception safe. This can be achived + /// when the observers does not throw exception on \e erase() and + /// \e clear(). Less strict condition is that the \e erase() should + /// not throw exception after an \e add() with the same parameter and + /// the \e clear() should not throw exception after a \e build(). + /// + /// There are some place when the alteration observing is not completly + /// reliable. If we want to carry out the node degree in the graph + /// as in the \ref InDegMap and we use the reverseEdge that cause + /// unreliable functionality. Because the alteration observing signals + /// only erasing and adding but not the reversing it will stores bad + /// degrees. The sub graph adaptors cannot signal the alterations because + /// just a setting in the filter map can modify the graph and this cannot + /// be watched in any way. + /// + /// \param _Container The container which is observed. + /// \param _Item The item type which is obserbved. /// /// \author Balazs Dezso - template + template class AlterationNotifier { public: typedef True Notifier; + typedef _Container Container; typedef _Item Item; - /// ObserverBase is the base class for the observers. - + /// \brief ObserverBase is the base class for the observers. + /// /// ObserverBase is the abstract base class for the observers. /// It will be notified about an item was inserted into or /// erased from the graph. @@ -75,7 +118,7 @@ class ObserverBase { protected: - typedef AlterationNotifier Registry; + typedef AlterationNotifier Notifier; friend class AlterationNotifier; @@ -83,23 +126,39 @@ /// /// Default constructor for ObserverBase. /// - ObserverBase() : registry(0) {} + ObserverBase() : notifier(0) {} + /// \brief Constructor which attach the observer into notifier. + /// + /// Constructor which attach the observer into notifier. + ObserverBase(AlterationNotifier& _notifier) { + attach(_notifier); + } + + /// \brief Constructor which attach the obserever to the same notifier. + /// + /// Constructor which attach the obserever to the same notifier as + /// the other observer is attached to. ObserverBase(const ObserverBase& copy) { if (copy.attached()) { - copy.getRegistry()->attach(*this); + attach(*copy.getNotifier()); } } - virtual ~ObserverBase() {} + /// \brief Destructor + virtual ~ObserverBase() { + if (attached()) { + detach(); + } + } /// \brief Attaches the observer into an AlterationNotifier. /// /// This member attaches the observer into an AlterationNotifier. /// - void attach(AlterationNotifier& r) { - registry = &r; - registry->attach(*this); + void attach(AlterationNotifier& _notifier) { + notifier = &_notifier; + notifier->attach(*this); } /// \brief Detaches the observer into an AlterationNotifier. @@ -107,21 +166,20 @@ /// This member detaches the observer from an AlterationNotifier. /// void detach() { - if (registry) { - registry->detach(*this); - } + notifier->detach(*this); } - /// Gives back a pointer to the registry what the map attached into. - - /// This function gives back a pointer to the registry what the map + /// \brief Gives back a pointer to the notifier which the map /// attached into. /// - Registry* getRegistry() const { return const_cast(registry); } + /// This function gives back a pointer to the notifier which the map + /// attached into. + /// + Notifier* getNotifier() const { return const_cast(notifier); } - /// Gives back true when the observer is attached into a registry. - bool attached() const { return registry != 0; } + /// Gives back true when the observer is attached into a notifier. + bool attached() const { return notifier != 0; } private: @@ -129,8 +187,8 @@ protected: - Registry* registry; - int registry_index; + Notifier* notifier; + int notifier_index; /// \brief The member function to notificate the observer about an /// item is added to the container. @@ -149,9 +207,17 @@ /// subclasses. virtual void add(const std::vector& items) { - for (int i = 0; i < (int)items.size(); ++i) { - add(items[i]); - } + int i; + try { + for (i = 0; i < (int)items.size(); ++i) { + add(items[i]); + } + } catch (...) { + for (int j = 0; j < i; ++j) { + add(items[j]); + } + throw; + } } /// \brief The member function to notificate the observer about an @@ -170,9 +236,9 @@ /// is erased from the container. It have to be overrided in the /// subclasses. virtual void erase(const std::vector& items) { - for (int i = 0; i < (int)items.size(); ++i) { - erase(items[i]); - } + for (int i = 0; i < (int)items.size(); ++i) { + erase(items[i]); + } } /// \brief The member function to notificate the observer about the @@ -182,166 +248,222 @@ /// container is built from an empty container. It have to be /// overrided in the subclasses. - virtual void build() = 0; + virtual void build() { + Item it; + try { + for (notifier->first(it); it != INVALID; notifier->next(it)) { + add(it); + } + } catch (...) { + Item jt; + for (notifier->first(jt); jt != it; notifier->next(jt)) { + erase(jt); + } + throw; + } + } /// \brief The member function to notificate the observer about all /// items are erased from the container. /// /// The clear() member function notificates the observer about all /// items are erased from the container. It have to be overrided in - /// the subclasses. - - virtual void clear() = 0; + /// the subclasses. + virtual void clear() { + Item it; + for (notifier->first(it); it != INVALID; notifier->next(it)) { + erase(it); + } + } }; protected: - - typedef std::vector Container; + const Container* container; - Container container; + typedef std::vector Observers; + Observers observers; public: - /// Default constructor. - + /// \brief Default constructor. /// /// The default constructor of the AlterationNotifier. - /// It creates an empty registry. - AlterationNotifier() {} + /// It creates an empty notifier. + AlterationNotifier() + : container(0) {} - /// Copy Constructor of the AlterationNotifier. - + /// \brief Constructor. + /// + /// Constructor with the observed container parameter. + AlterationNotifier(const Container& _container) + : container(&_container) {} + + /// \brief Copy Constructor of the AlterationNotifier. + /// /// Copy constructor of the AlterationNotifier. - /// It creates only an empty registry because the copiable - /// registry's observers have to be registered still into that registry. - AlterationNotifier(const AlterationNotifier&) {} + /// It creates only an empty notifier because the copiable + /// notifier's observers have to be registered still into that notifier. + AlterationNotifier(const AlterationNotifier& _notifier) + : container(_notifier.container) {} - /// Assign operator. - - /// Assign operator for the AlterationNotifier. - /// It makes the notifier only empty because the copiable - /// notifier's observers have to be registered still into that registry. - AlterationNotifier& operator=(const AlterationNotifier&) { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->registry = 0; + /// \brief Destructor. + /// + /// Destructor of the AlterationNotifier. + /// + ~AlterationNotifier() { + typename Observers::iterator it; + for (it = observers.begin(); it != observers.end(); ++it) { + (*it)->notifier = 0; } } - /// Destructor. - - /// Destructor of the AlterationNotifier. + /// \brief Sets the container. /// - ~AlterationNotifier() { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->registry = 0; - } + /// Sets the container. + void setContainer(const Container& _container) { + container = &_container; } - - + + protected: + + AlterationNotifier& operator=(const AlterationNotifier&); + + public: + + + + /// \brief First item in the container. + /// + /// Returns the first item in the container. It is + /// for start the iteration on the container. + void first(Item& item) const { + container->first(item); + } + + /// \brief Next item in the container. + /// + /// Returns the next item in the container. It is + /// for iterate on the container. + void next(Item& item) const { + container->next(item); + } + + /// \brief Returns the id of the item. + /// + /// Returns the id of the item provided by the container. + int id(const Item& item) const { + return container->id(item); + } + + /// \brief Returns the maximum id of the container. + /// + /// Returns the maximum id of the container. + int maxId() const { + return container->maxId(Item()); + } + protected: void attach(ObserverBase& observer) { - container.push_back(&observer); - observer.registry = this; - observer.registry_index = container.size()-1; + observers.push_back(&observer); + observer.notifier = this; + observer.notifier_index = observers.size() - 1; } - void detach(ObserverBase& base) { - container.back()->registry_index = base.registry_index; - container[base.registry_index] = container.back(); - container.pop_back(); - base.registry = 0; + void detach(ObserverBase& observer) { + observers.back()->notifier_index = observer.notifier_index; + observers[observer.notifier_index] = observers.back(); + observers.pop_back(); + observer.notifier = 0; } public: - /// \brief Notifies all the registered observers about an Item added to + /// \brief Notifies all the registed observers about an item added to /// the container. /// - /// It notifies all the registered observers about an Item added to + /// It notifies all the registed observers about an item added to /// the container. /// void add(const Item& item) { - typename Container::iterator it; + typename Observers::iterator it; try { - for (it = container.begin(); it != container.end(); ++it) { + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->add(item); } } catch (...) { - typename Container::iterator jt; - for (jt = container.begin(); jt != it; ++it) { + typename Observers::iterator jt; + for (jt = observers.begin(); jt != it; ++jt) { (*it)->erase(item); } throw; } } - /// \brief Notifies all the registered observers about more Item added to + /// \brief Notifies all the registed observers about more item added to /// the container. /// - /// It notifies all the registered observers about more Item added to + /// It notifies all the registed observers about more item added to /// the container. /// void add(const std::vector& items) { - typename Container::iterator it; + typename Observers::iterator it; try { - for (it = container.begin(); it != container.end(); ++it) { + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->add(items); } } catch (...) { - typename Container::iterator jt; - for (jt = container.begin(); jt != it; ++it) { + typename Observers::iterator jt; + for (jt = observers.begin(); jt != it; ++jt) { (*it)->erase(items); } throw; } } - /// \brief Notifies all the registered observers about an Item erased from + /// \brief Notifies all the registed observers about an item erased from /// the container. /// - /// It notifies all the registered observers about an Item erased from + /// It notifies all the registed observers about an item erased from /// the container. /// void erase(const Item& key) { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { + typename Observers::iterator it; + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->erase(key); } } - /// \brief Notifies all the registered observers about more Item erased + /// \brief Notifies all the registed observers about more item erased /// from the container. /// - /// It notifies all the registered observers about more Item erased from + /// It notifies all the registed observers about more item erased from /// the container. /// void erase(const std::vector& items) { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { + typename Observers::iterator it; + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->erase(items); } } - /// \brief Notifies all the registered observers about the container is + /// \brief Notifies all the registed observers about the container is /// built. /// - /// Notifies all the registered observers about the container is built + /// Notifies all the registed observers about the container is built /// from an empty container. void build() { - typename Container::iterator it; + typename Observers::iterator it; try { - for (it = container.begin(); it != container.end(); ++it) { + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->build(); } } catch (...) { - typename Container::iterator jt; - for (jt = container.begin(); jt != it; ++it) { + typename Observers::iterator jt; + for (jt = observers.begin(); jt != it; ++jt) { (*it)->clear(); } throw; @@ -349,23 +471,19 @@ } - /// \brief Notifies all the registered observers about all Items are + /// \brief Notifies all the registed observers about all items are /// erased. /// - /// Notifies all the registered observers about all Items are erased + /// Notifies all the registed observers about all items are erased /// from the container. void clear() { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { + typename Observers::iterator it; + for (it = observers.begin(); it != observers.end(); ++it) { (*it)->clear(); } } }; - -/// @} - - } #endif diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/array_map.h --- a/lemon/bits/array_map.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/array_map.h Mon Mar 06 10:28:37 2006 +0000 @@ -20,15 +20,13 @@ #define LEMON_BITS_ARRAY_MAP_H #include -#include + +#include #include -#include -#include /// \ingroup graphbits /// \file -/// \brief Graph maps that construct and destruct -/// their elements dynamically. +/// \brief Graph map based on the array storage. namespace lemon { @@ -37,22 +35,20 @@ /// \brief Graph map based on the array storage. /// /// The ArrayMap template class is graph map structure what - /// automatically indates the map when a key is added to or erased from + /// automatically updates the map when a key is added to or erased from /// the map. This map uses the allocators to implement /// the container functionality. /// - /// The template parameter is the AlterationNotifier that the maps - /// will belong to and the Value. - - template - class ArrayMap : public AlterationNotifier<_Item>::ObserverBase { - - typedef _Item Item; + /// The template parameter is the Graph the current Item type and + /// the Value type of the map. + template + class ArrayMap + : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { public: /// The graph type of the maps. typedef _Graph Graph; + /// The item type of the map. + typedef _Item Item; /// The reference map tag. typedef True ReferenceMapTag; @@ -60,37 +56,33 @@ typedef _Item Key; /// The value type of the map. typedef _Value Value; + /// The const reference type of the map. typedef const _Value& ConstReference; /// The reference type of the map. typedef _Value& Reference; - typedef const Value ConstValue; - typedef Value* Pointer; - typedef const Value* ConstPointer; - - typedef AlterationNotifier<_Item> Registry; + /// The notifier type. + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier; /// The MapBase of the Map which imlements the core regisitry function. - typedef typename Registry::ObserverBase Parent; + typedef typename Notifier::ObserverBase Parent; - - private: typedef std::allocator Allocator; - public: /// \brief Graph initialized map constructor. /// /// Graph initialized map constructor. - ArrayMap(const Graph& _g) : graph(&_g) { + ArrayMap(const Graph& graph) { + Parent::attach(graph.getNotifier(Item())); + allocate_memory(); + Notifier* notifier = Parent::getNotifier(); Item it; - attach(_g.getNotifier(Item())); - allocate_memory(); - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it);; allocator.construct(&(values[id]), Value()); } } @@ -98,29 +90,31 @@ /// \brief Constructor to use default value to initialize the map. /// /// It constructs a map and initialize all of the the map. - ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) { + ArrayMap(const Graph& graph, const Value& value) { + Parent::attach(graph.getNotifier(Item())); + allocate_memory(); + Notifier* notifier = Parent::getNotifier(); Item it; - attach(_g.getNotifier(_Item())); - allocate_memory(); - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), _v); + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it);; + allocator.construct(&(values[id]), value); } } /// \brief Constructor to copy a map of the same map type. /// /// Constructor to copy a map of the same map type. - ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) { + ArrayMap(const ArrayMap& copy) : Parent() { if (copy.attached()) { - attach(*copy.getRegistry()); + attach(*copy.getNotifier()); } capacity = copy.capacity; if (capacity == 0) return; values = allocator.allocate(capacity); + Notifier* notifier = Parent::getNotifier(); Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it);; allocator.construct(&(values[id]), copy.values[id]); } } @@ -145,11 +139,6 @@ using Parent::detach; using Parent::attached; - const Graph* getGraph() { - return graph; - } - - public: /// \brief The subscript operator. @@ -157,7 +146,7 @@ /// The subscript operator. The map can be subscripted by the /// actual keys of the graph. Value& operator[](const Key& key) { - int id = graph->id(key); + int id = Parent::getNotifier()->id(key); return values[id]; } @@ -166,7 +155,7 @@ /// The const subscript operator. The map can be subscripted by the /// actual keys of the graph. const Value& operator[](const Key& key) const { - int id = graph->id(key); + int id = Parent::getNotifier()->id(key); return values[id]; } @@ -180,10 +169,13 @@ protected: - /// Add a new key to the map. It called by the map registry. - + /// \brief Adds a new key to the map. + /// + /// It adds a new key to the map. It called by the observer notifier + /// and it overrides the add() member function of the observer base. virtual void add(const Key& key) { - int id = graph->id(key); + Notifier* notifier = Parent::getNotifier(); + int id = notifier->id(key); if (id >= capacity) { int new_capacity = (capacity == 0 ? 1 : capacity); while (new_capacity <= id) { @@ -191,8 +183,8 @@ } Value* new_values = allocator.allocate(new_capacity); Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int jd = graph->id(it);; + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int jd = notifier->id(it);; if (id != jd) { allocator.construct(&(new_values[jd]), values[jd]); allocator.destroy(&(values[jd])); @@ -205,10 +197,15 @@ allocator.construct(&(values[id]), Value()); } + /// \brief Adds more new keys to the map. + /// + /// It adds more new keys to the map. It called by the observer notifier + /// and it overrides the add() member function of the observer base. virtual void add(const std::vector& keys) { + Notifier* notifier = Parent::getNotifier(); int max_id = -1; for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); + int id = notifier->id(keys[i]); if (id > max_id) { max_id = id; } @@ -220,11 +217,11 @@ } Value* new_values = allocator.allocate(new_capacity); Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it); + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it); bool found = false; for (int i = 0; i < (int)keys.size(); ++i) { - int jd = graph->id(keys[i]); + int jd = notifier->id(keys[i]); if (id == jd) { found = true; break; @@ -239,39 +236,55 @@ capacity = new_capacity; } for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); + int id = notifier->id(keys[i]); allocator.construct(&(values[id]), Value()); } } - /// Erase a key from the map. It called by the map registry. - + /// \brief Erase a key from the map. + /// + /// Erase a key from the map. It called by the observer notifier + /// and it overrides the erase() member function of the observer base. virtual void erase(const Key& key) { - int id = graph->id(key); + int id = Parent::getNotifier()->id(key); allocator.destroy(&(values[id])); } + /// \brief Erase more keys from the map. + /// + /// Erase more keys from the map. It called by the observer notifier + /// and it overrides the erase() member function of the observer base. virtual void erase(const std::vector& keys) { for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); + int id = Parent::getNotifier()->id(keys[i]); allocator.destroy(&(values[id])); } } + /// \brief Buildes the map. + /// + /// It buildes the map. It called by the observer notifier + /// and it overrides the build() member function of the observer base. virtual void build() { + Notifier* notifier = Parent::getNotifier(); allocate_memory(); Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it);; allocator.construct(&(values[id]), Value()); } } + /// \brief Clear the map. + /// + /// It erase all items from the map. It called by the observer notifier + /// and it overrides the clear() member function of the observer base. virtual void clear() { + Notifier* notifier = Parent::getNotifier(); if (capacity != 0) { Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it); + for (notifier->first(it); it != INVALID; notifier->next(it)) { + int id = notifier->id(it); allocator.destroy(&(values[id])); } allocator.deallocate(values, capacity); @@ -282,7 +295,7 @@ private: void allocate_memory() { - int max_id = graph->maxId(_Item()); + int max_id = Parent::getNotifier()->maxId(); if (max_id == -1) { capacity = 0; values = 0; @@ -295,7 +308,6 @@ values = allocator.allocate(capacity); } - const Graph* graph; int capacity; Value* values; Allocator allocator; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/base_extender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/bits/base_extender.h Mon Mar 06 10:28:37 2006 +0000 @@ -0,0 +1,473 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_BASE_EXTENDER_H +#define LEMON_BITS_BASE_EXTENDER_H + +#include +#include + +#include +#include + +#include +#include + +///\ingroup graphbits +///\file +///\brief Extenders for the graph types +namespace lemon { + + /// \ingroup graphbits + /// + /// \brief BaseExtender for the UGraphs + template + class UGraphBaseExtender : public Base { + + public: + + typedef Base Parent; + typedef typename Parent::Edge UEdge; + typedef typename Parent::Node Node; + + typedef True UndirectedTag; + + class Edge : public UEdge { + friend class UGraphBaseExtender; + + protected: + bool forward; + + Edge(const UEdge &ue, bool _forward) : + UEdge(ue), forward(_forward) {} + + public: + Edge() {} + + /// Invalid edge constructor + Edge(Invalid i) : UEdge(i), forward(true) {} + + bool operator==(const Edge &that) const { + return forward==that.forward && UEdge(*this)==UEdge(that); + } + bool operator!=(const Edge &that) const { + return forward!=that.forward || UEdge(*this)!=UEdge(that); + } + bool operator<(const Edge &that) const { + return forward> 1), bool(id & 1)); + } + + UEdge uEdgeFromId(int id) const { + return Parent::edgeFromId(id >> 1); + } + + int id(const Node &n) const { + return Parent::id(n); + } + + int id(const UEdge &e) const { + return Parent::id(e); + } + + int id(const Edge &e) const { + return 2 * Parent::id(e) + int(e.forward); + } + + int maxNodeId() const { + return Parent::maxNodeId(); + } + + int maxEdgeId() const { + return 2 * Parent::maxEdgeId() + 1; + } + + int maxUEdgeId() const { + return Parent::maxEdgeId(); + } + + + int edgeNum() const { + return 2 * Parent::edgeNum(); + } + + int uEdgeNum() const { + return Parent::edgeNum(); + } + + Edge findEdge(Node source, Node target, Edge prev) const { + if (prev == INVALID) { + UEdge edge = Parent::findEdge(source, target); + if (edge != INVALID) return direct(edge, true); + edge = Parent::findEdge(target, source); + if (edge != INVALID) return direct(edge, false); + } else if (direction(prev)) { + UEdge edge = Parent::findEdge(source, target, prev); + if (edge != INVALID) return direct(edge, true); + edge = Parent::findEdge(target, source); + if (edge != INVALID) return direct(edge, false); + } else { + UEdge edge = Parent::findEdge(target, source, prev); + if (edge != INVALID) return direct(edge, false); + } + return INVALID; + } + + UEdge findUEdge(Node source, Node target, UEdge prev) const { + if (prev == INVALID) { + UEdge edge = Parent::findEdge(source, target); + if (edge != INVALID) return edge; + edge = Parent::findEdge(target, source); + if (edge != INVALID) return edge; + } else if (Parent::source(prev) == source) { + UEdge edge = Parent::findEdge(source, target, prev); + if (edge != INVALID) return edge; + edge = Parent::findEdge(target, source); + if (edge != INVALID) return edge; + } else { + UEdge edge = Parent::findEdge(target, source, prev); + if (edge != INVALID) return edge; + } + return INVALID; + } + }; + + + /// \ingroup graphbits + /// + /// \brief BaseExtender for the BpUGraphs + template + class BpUGraphBaseExtender : public Base { + public: + typedef Base Parent; + typedef BpUGraphBaseExtender Graph; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge UEdge; + + + using Parent::first; + using Parent::next; + + using Parent::id; + + class ANode : public Node { + friend class BpUGraphBaseExtender; + public: + ANode() {} + ANode(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::aNode(node) || node == INVALID, + typename Parent::NodeSetError()); + } + ANode(Invalid) : Node(INVALID) {} + }; + + void first(ANode& node) const { + Parent::firstANode(static_cast(node)); + } + void next(ANode& node) const { + Parent::nextANode(static_cast(node)); + } + + int id(const ANode& node) const { + return Parent::aNodeId(node); + } + + class BNode : public Node { + friend class BpUGraphBaseExtender; + public: + BNode() {} + BNode(const Node& node) : Node(node) { + LEMON_ASSERT(Parent::bNode(node) || node == INVALID, + typename Parent::NodeSetError()); + } + BNode(Invalid) : Node(INVALID) {} + }; + + void first(BNode& node) const { + Parent::firstBNode(static_cast(node)); + } + void next(BNode& node) const { + Parent::nextBNode(static_cast(node)); + } + + int id(const BNode& node) const { + return Parent::aNodeId(node); + } + + Node source(const UEdge& edge) const { + return aNode(edge); + } + Node target(const UEdge& edge) const { + return bNode(edge); + } + + void firstInc(UEdge& edge, bool& direction, const Node& node) const { + if (Parent::aNode(node)) { + Parent::firstOut(edge, node); + direction = true; + } else { + Parent::firstIn(edge, node); + direction = static_cast(edge) == INVALID; + } + } + void nextInc(UEdge& edge, bool& direction) const { + if (direction) { + Parent::nextOut(edge); + } else { + Parent::nextIn(edge); + if (edge == INVALID) direction = true; + } + } + + int maxUEdgeId() const { + return Parent::maxEdgeId(); + } + + UEdge uEdgeFromId(int id) const { + return Parent::edgeFromId(id); + } + + class Edge : public UEdge { + friend class BpUGraphBaseExtender; + protected: + bool forward; + + Edge(const UEdge& edge, bool _forward) + : UEdge(edge), forward(_forward) {} + + public: + Edge() {} + Edge (Invalid) : UEdge(INVALID), forward(true) {} + bool operator==(const Edge& i) const { + return UEdge::operator==(i) && forward == i.forward; + } + bool operator!=(const Edge& i) const { + return UEdge::operator!=(i) || forward != i.forward; + } + bool operator<(const Edge& i) const { + return UEdge::operator<(i) || + (!(i.forward(edge)); + edge.forward = true; + } + + void next(Edge& edge) const { + if (!edge.forward) { + Parent::next(static_cast(edge)); + } + edge.forward = !edge.forward; + } + + void firstOut(Edge& edge, const Node& node) const { + if (Parent::aNode(node)) { + Parent::firstOut(edge, node); + edge.forward = true; + } else { + Parent::firstIn(edge, node); + edge.forward = static_cast(edge) == INVALID; + } + } + void nextOut(Edge& edge) const { + if (edge.forward) { + Parent::nextOut(edge); + } else { + Parent::nextIn(edge); + edge.forward = static_cast(edge) == INVALID; + } + } + + void firstIn(Edge& edge, const Node& node) const { + if (Parent::bNode(node)) { + Parent::firstIn(edge, node); + edge.forward = true; + } else { + Parent::firstOut(edge, node); + edge.forward = static_cast(edge) == INVALID; + } + } + void nextIn(Edge& edge) const { + if (edge.forward) { + Parent::nextIn(edge); + } else { + Parent::nextOut(edge); + edge.forward = static_cast(edge) == INVALID; + } + } + + Node source(const Edge& edge) const { + return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge); + } + Node target(const Edge& edge) const { + return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge); + } + + int id(const Edge& edge) const { + return (Parent::id(edge) << 1) + (edge.forward ? 0 : 1); + } + Edge edgeFromId(int id) const { + return Edge(Parent::fromId(id >> 1, UEdge()), (id & 1) == 0); + } + int maxEdgeId() const { + return (Parent::maxId(UEdge()) << 1) + 1; + } + + bool direction(const Edge& edge) const { + return edge.forward; + } + + Edge direct(const UEdge& edge, bool direction) const { + return Edge(edge, direction); + } + }; + +} + +#endif diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/default_map.h --- a/lemon/bits/default_map.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/default_map.h Mon Mar 06 10:28:37 2006 +0000 @@ -16,18 +16,16 @@ * */ -#ifndef LEMON_DEFAULT_MAP_H -#define LEMON_DEFAULT_MAP_H +#ifndef LEMON_BITS_DEFAULT_MAP_H +#define LEMON_BITS_DEFAULT_MAP_H #include #include -#include ///\ingroup graphbits ///\file -///\brief Graph maps that construct and destruct -///their elements dynamically. +///\brief Graph maps that construct and destruct their elements dynamically. namespace lemon { @@ -151,10 +149,7 @@ }; /// \e - template < - typename _Graph, - typename _Item, - typename _Value> + template class DefaultMap : public DefaultMapSelector<_Graph, _Item, _Value>::Map { public: @@ -164,8 +159,9 @@ typedef typename Parent::Graph Graph; typedef typename Parent::Value Value; - DefaultMap(const Graph& _g) : Parent(_g) {} - DefaultMap(const Graph& _g, const Value& _v) : Parent(_g, _v) {} + DefaultMap(const Graph& graph) : Parent(graph) {} + DefaultMap(const Graph& graph, const Value& value) + : Parent(graph, value) {} }; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/edge_set_extender.h --- a/lemon/bits/edge_set_extender.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/edge_set_extender.h Mon Mar 06 10:28:37 2006 +0000 @@ -73,7 +73,7 @@ // Alteration notifier extensions /// The edge observer registry. - typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier EdgeNotifier; protected: @@ -219,10 +219,10 @@ template class EdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef EdgeSetExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} @@ -264,6 +264,9 @@ Parent::erase(edge); } + EdgeSetExtender() { + edge_notifier.setContainer(*this); + } ~EdgeSetExtender() { edge_notifier.clear(); @@ -330,8 +333,8 @@ return Parent::direct(ue, Parent::source(ue) == s); } - typedef AlterationNotifier EdgeNotifier; - typedef AlterationNotifier UEdgeNotifier; + typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier UEdgeNotifier; protected: @@ -537,10 +540,10 @@ template class EdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef UEdgeSetExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} @@ -566,10 +569,10 @@ template class UEdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef UEdgeSetExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} @@ -617,9 +620,14 @@ } + UEdgeSetExtender() { + edge_notifier.setContainer(*this); + uedge_notifier.setContainer(*this); + } + ~UEdgeSetExtender() { - getNotifier(Edge()).clear(); - getNotifier(UEdge()).clear(); + uedge_notifier.clear(); + edge_notifier.clear(); } }; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/graph_extender.h --- a/lemon/bits/graph_extender.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/graph_extender.h Mon Mar 06 10:28:37 2006 +0000 @@ -22,8 +22,12 @@ #include #include +#include #include +#include +#include + ///\ingroup graphbits ///\file ///\brief Extenders for the graph types @@ -71,8 +75,8 @@ // Alterable extension - typedef AlterationNotifier NodeNotifier; - typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier EdgeNotifier; protected: @@ -214,15 +218,15 @@ template class NodeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef GraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - NodeMap(const Graph& _g) - : Parent(_g) {} - NodeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + NodeMap(const Graph& graph) + : Parent(graph) {} + NodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); @@ -238,9 +242,9 @@ template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); + const typename Parent::Notifier* notifier = Parent::getNotifier(); Node it; - for (graph->first(it); it != INVALID; graph->next(it)) { + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -250,15 +254,15 @@ template class EdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef GraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - EdgeMap(const Graph& _g) - : Parent(_g) {} - EdgeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + EdgeMap(const Graph& graph) + : Parent(graph) {} + EdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); @@ -267,9 +271,9 @@ template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); + const typename Parent::Notifier* notifier = Parent::getNotifier(); Edge it; - for (graph->first(it); it != INVALID; graph->next(it)) { + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -319,258 +323,20 @@ Parent::erase(edge); } + GraphExtender() { + node_notifier.setContainer(*this); + edge_notifier.setContainer(*this); + } + ~GraphExtender() { - getNotifier(Edge()).clear(); - getNotifier(Node()).clear(); + edge_notifier.clear(); + node_notifier.clear(); } }; /// \ingroup graphbits /// - /// \brief BaseExtender for the UGraphs - template - class UGraphBaseExtender : public Base { - - public: - - typedef Base Parent; - typedef typename Parent::Edge UEdge; - typedef typename Parent::Node Node; - - typedef True UndirectedTag; - - class Edge : public UEdge { - friend class UGraphBaseExtender; - - protected: - bool forward; - - Edge(const UEdge &ue, bool _forward) : - UEdge(ue), forward(_forward) {} - - public: - Edge() {} - - /// Invalid edge constructor - Edge(Invalid i) : UEdge(i), forward(true) {} - - bool operator==(const Edge &that) const { - return forward==that.forward && UEdge(*this)==UEdge(that); - } - bool operator!=(const Edge &that) const { - return forward!=that.forward || UEdge(*this)!=UEdge(that); - } - bool operator<(const Edge &that) const { - return forward> 1), bool(id & 1)); - } - - UEdge uEdgeFromId(int id) const { - return Parent::edgeFromId(id >> 1); - } - - int id(const Node &n) const { - return Parent::id(n); - } - - int id(const UEdge &e) const { - return Parent::id(e); - } - - int id(const Edge &e) const { - return 2 * Parent::id(e) + int(e.forward); - } - - int maxNodeId() const { - return Parent::maxNodeId(); - } - - int maxEdgeId() const { - return 2 * Parent::maxEdgeId() + 1; - } - - int maxUEdgeId() const { - return Parent::maxEdgeId(); - } - - - int edgeNum() const { - return 2 * Parent::edgeNum(); - } - - int uEdgeNum() const { - return Parent::edgeNum(); - } - - Edge findEdge(Node source, Node target, Edge prev) const { - if (prev == INVALID) { - UEdge edge = Parent::findEdge(source, target); - if (edge != INVALID) return direct(edge, true); - edge = Parent::findEdge(target, source); - if (edge != INVALID) return direct(edge, false); - } else if (direction(prev)) { - UEdge edge = Parent::findEdge(source, target, prev); - if (edge != INVALID) return direct(edge, true); - edge = Parent::findEdge(target, source); - if (edge != INVALID) return direct(edge, false); - } else { - UEdge edge = Parent::findEdge(target, source, prev); - if (edge != INVALID) return direct(edge, false); - } - return INVALID; - } - - UEdge findUEdge(Node source, Node target, UEdge prev) const { - if (prev == INVALID) { - UEdge edge = Parent::findEdge(source, target); - if (edge != INVALID) return edge; - edge = Parent::findEdge(target, source); - if (edge != INVALID) return edge; - } else if (Parent::source(prev) == source) { - UEdge edge = Parent::findEdge(source, target, prev); - if (edge != INVALID) return edge; - edge = Parent::findEdge(target, source); - if (edge != INVALID) return edge; - } else { - UEdge edge = Parent::findEdge(target, source, prev); - if (edge != INVALID) return edge; - } - return INVALID; - } - }; - - - /// \ingroup graphbits - /// /// \brief Extender for the UGraphs template class UGraphExtender : public Base { @@ -629,9 +395,9 @@ // Alterable extension - typedef AlterationNotifier NodeNotifier; - typedef AlterationNotifier EdgeNotifier; - typedef AlterationNotifier UEdgeNotifier; + typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier UEdgeNotifier; protected: @@ -842,15 +608,15 @@ template class NodeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef UGraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - NodeMap(const Graph& _g) - : Parent(_g) {} - NodeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + NodeMap(const Graph& graph) + : Parent(graph) {} + NodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); @@ -866,9 +632,9 @@ template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); + const typename Parent::Notifier* notifier = Parent::getNotifier(); Node it; - for (graph->first(it); it != INVALID; graph->next(it)) { + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -878,15 +644,15 @@ template class EdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef UGraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - EdgeMap(const Graph& _g) - : Parent(_g) {} - EdgeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + EdgeMap(const Graph& graph) + : Parent(graph) {} + EdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); @@ -895,9 +661,9 @@ template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); + const typename Parent::Notifier* notifier = Parent::getNotifier(); Edge it; - for (graph->first(it); it != INVALID; graph->next(it)) { + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -907,15 +673,15 @@ template class UEdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef UGraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - UEdgeMap(const Graph& _g) - : Parent(_g) {} - UEdgeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + UEdgeMap(const Graph& graph) + : Parent(graph) {} + UEdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); @@ -924,9 +690,9 @@ template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); - UEdge it; - for (graph->first(it); it != INVALID; graph->next(it)) { + const typename Parent::Notifier* notifier = Parent::getNotifier(); + Edge it; + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -981,207 +747,20 @@ Parent::erase(uedge); } + UGraphExtender() { + node_notifier.setContainer(*this); + edge_notifier.setContainer(*this); + uedge_notifier.setContainer(*this); + } + ~UGraphExtender() { - getNotifier(Edge()).clear(); - getNotifier(UEdge()).clear(); - getNotifier(Node()).clear(); - } + uedge_notifier.clear(); + edge_notifier.clear(); + node_notifier.clear(); + } }; - - /// \ingroup graphbits - /// - /// \brief BaseExtender for the BpUGraphs - template - class BpUGraphBaseExtender : public Base { - public: - typedef Base Parent; - typedef BpUGraphBaseExtender Graph; - - typedef typename Parent::Node Node; - typedef typename Parent::Edge UEdge; - - - using Parent::first; - using Parent::next; - - using Parent::id; - - class ANode : public Node { - friend class BpUGraphBaseExtender; - public: - ANode() {} - ANode(const Node& node) : Node(node) { - LEMON_ASSERT(Parent::aNode(node) || node == INVALID, - typename Parent::NodeSetError()); - } - ANode(Invalid) : Node(INVALID) {} - }; - - void first(ANode& node) const { - Parent::firstANode(static_cast(node)); - } - void next(ANode& node) const { - Parent::nextANode(static_cast(node)); - } - - int id(const ANode& node) const { - return Parent::aNodeId(node); - } - - class BNode : public Node { - friend class BpUGraphBaseExtender; - public: - BNode() {} - BNode(const Node& node) : Node(node) { - LEMON_ASSERT(Parent::bNode(node) || node == INVALID, - typename Parent::NodeSetError()); - } - BNode(Invalid) : Node(INVALID) {} - }; - - void first(BNode& node) const { - Parent::firstBNode(static_cast(node)); - } - void next(BNode& node) const { - Parent::nextBNode(static_cast(node)); - } - - int id(const BNode& node) const { - return Parent::aNodeId(node); - } - - Node source(const UEdge& edge) const { - return aNode(edge); - } - Node target(const UEdge& edge) const { - return bNode(edge); - } - - void firstInc(UEdge& edge, bool& direction, const Node& node) const { - if (Parent::aNode(node)) { - Parent::firstOut(edge, node); - direction = true; - } else { - Parent::firstIn(edge, node); - direction = static_cast(edge) == INVALID; - } - } - void nextInc(UEdge& edge, bool& direction) const { - if (direction) { - Parent::nextOut(edge); - } else { - Parent::nextIn(edge); - if (edge == INVALID) direction = true; - } - } - - int maxUEdgeId() const { - return Parent::maxEdgeId(); - } - - UEdge uEdgeFromId(int id) const { - return Parent::edgeFromId(id); - } - - class Edge : public UEdge { - friend class BpUGraphBaseExtender; - protected: - bool forward; - - Edge(const UEdge& edge, bool _forward) - : UEdge(edge), forward(_forward) {} - - public: - Edge() {} - Edge (Invalid) : UEdge(INVALID), forward(true) {} - bool operator==(const Edge& i) const { - return UEdge::operator==(i) && forward == i.forward; - } - bool operator!=(const Edge& i) const { - return UEdge::operator!=(i) || forward != i.forward; - } - bool operator<(const Edge& i) const { - return UEdge::operator<(i) || - (!(i.forward(edge)); - edge.forward = true; - } - - void next(Edge& edge) const { - if (!edge.forward) { - Parent::next(static_cast(edge)); - } - edge.forward = !edge.forward; - } - - void firstOut(Edge& edge, const Node& node) const { - if (Parent::aNode(node)) { - Parent::firstOut(edge, node); - edge.forward = true; - } else { - Parent::firstIn(edge, node); - edge.forward = static_cast(edge) == INVALID; - } - } - void nextOut(Edge& edge) const { - if (edge.forward) { - Parent::nextOut(edge); - } else { - Parent::nextIn(edge); - edge.forward = static_cast(edge) == INVALID; - } - } - - void firstIn(Edge& edge, const Node& node) const { - if (Parent::bNode(node)) { - Parent::firstIn(edge, node); - edge.forward = true; - } else { - Parent::firstOut(edge, node); - edge.forward = static_cast(edge) == INVALID; - } - } - void nextIn(Edge& edge) const { - if (edge.forward) { - Parent::nextIn(edge); - } else { - Parent::nextOut(edge); - edge.forward = static_cast(edge) == INVALID; - } - } - - Node source(const Edge& edge) const { - return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge); - } - Node target(const Edge& edge) const { - return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge); - } - - int id(const Edge& edge) const { - return (Parent::id(edge) << 1) + (edge.forward ? 0 : 1); - } - Edge edgeFromId(int id) const { - return Edge(Parent::fromId(id >> 1, UEdge()), (id & 1) == 0); - } - int maxEdgeId() const { - return (Parent::maxId(UEdge()) << 1) + 1; - } - - bool direction(const Edge& edge) const { - return edge.forward; - } - - Edge direct(const UEdge& edge, bool direction) const { - return Edge(edge, direction); - } - }; - /// \ingroup graphbits /// /// \brief Extender for the BpUGraphs @@ -1245,40 +824,40 @@ return Parent::uEdgeFromId(id); } - typedef AlterationNotifier NodeNotifier; - typedef AlterationNotifier BNodeNotifier; - typedef AlterationNotifier ANodeNotifier; - typedef AlterationNotifier EdgeNotifier; - typedef AlterationNotifier UEdgeNotifier; + typedef AlterationNotifier ANodeNotifier; + typedef AlterationNotifier BNodeNotifier; + typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier UEdgeNotifier; protected: - mutable NodeNotifier nodeNotifier; - mutable BNodeNotifier bNodeNotifier; - mutable ANodeNotifier aNodeNotifier; - mutable EdgeNotifier edgeNotifier; - mutable UEdgeNotifier uEdgeNotifier; + mutable ANodeNotifier anode_notifier; + mutable BNodeNotifier bnode_notifier; + mutable NodeNotifier node_notifier; + mutable EdgeNotifier edge_notifier; + mutable UEdgeNotifier uedge_notifier; public: NodeNotifier& getNotifier(Node) const { - return nodeNotifier; + return node_notifier; + } + + ANodeNotifier& getNotifier(ANode) const { + return anode_notifier; } BNodeNotifier& getNotifier(BNode) const { - return bNodeNotifier; - } - - ANodeNotifier& getNotifier(ANode) const { - return aNodeNotifier; + return bnode_notifier; } EdgeNotifier& getNotifier(Edge) const { - return edgeNotifier; + return edge_notifier; } UEdgeNotifier& getNotifier(UEdge) const { - return uEdgeNotifier; + return uedge_notifier; } class NodeIt : public Node { @@ -1511,16 +1090,15 @@ template class ANodeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef BpUGraphExtender Graph; - typedef IterableMapExtender > - Parent; + typedef MapExtender > Parent; - ANodeMap(const Graph& _g) - : Parent(_g) {} - ANodeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + ANodeMap(const Graph& graph) + : Parent(graph) {} + ANodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} ANodeMap& operator=(const ANodeMap& cmap) { return operator=(cmap); @@ -1548,16 +1126,15 @@ template class BNodeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef BpUGraphExtender Graph; - typedef IterableMapExtender > - Parent; + typedef MapExtender > Parent; - BNodeMap(const Graph& _g) - : Parent(_g) {} - BNodeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + BNodeMap(const Graph& graph) + : Parent(graph) {} + BNodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} BNodeMap& operator=(const BNodeMap& cmap) { return operator=(cmap); @@ -1594,23 +1171,16 @@ typedef _Value Value; /// The reference type of the map; - typedef typename BNodeMap<_Value>::Reference Reference; - /// The pointer type of the map; - typedef typename BNodeMap<_Value>::Pointer Pointer; - - /// The const value type of the map. - typedef const Value ConstValue; + typedef typename ANodeMap<_Value>::Reference Reference; /// The const reference type of the map; - typedef typename BNodeMap<_Value>::ConstReference ConstReference; - /// The pointer type of the map; - typedef typename BNodeMap<_Value>::ConstPointer ConstPointer; + typedef typename ANodeMap<_Value>::ConstReference ConstReference; typedef True ReferenceMapTag; - NodeMapBase(const Graph& _g) - : aNodeMap(_g), bNodeMap(_g) {} - NodeMapBase(const Graph& _g, const _Value& _v) - : aNodeMap(_g, _v), bNodeMap(_g, _v) {} + NodeMapBase(const Graph& graph) + : aNodeMap(graph), bNodeMap(graph) {} + NodeMapBase(const Graph& graph, const _Value& value) + : aNodeMap(graph, value), bNodeMap(graph, value) {} ConstReference operator[](const Key& node) const { if (Parent::aNode(node)) { @@ -1649,15 +1219,15 @@ template class NodeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef BpUGraphExtender Graph; - typedef IterableMapExtender< NodeMapBase<_Value> > Parent; + typedef MapExtender< NodeMapBase<_Value> > Parent; - NodeMap(const Graph& _g) - : Parent(_g) {} - NodeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + NodeMap(const Graph& graph) + : Parent(graph) {} + NodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); @@ -1673,9 +1243,9 @@ template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); - Node it; - for (graph->first(it); it != INVALID; graph->next(it)) { + const typename Parent::Notifier* notifier = Parent::getNotifier(); + Edge it; + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -1687,15 +1257,15 @@ template class EdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef BpUGraphExtender Graph; - typedef IterableMapExtender > Parent; + typedef MapExtender > Parent; - EdgeMap(const Graph& _g) - : Parent(_g) {} - EdgeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + EdgeMap(const Graph& graph) + : Parent(graph) {} + EdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); @@ -1704,9 +1274,9 @@ template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); + const typename Parent::Notifier* notifier = Parent::getNotifier(); Edge it; - for (graph->first(it); it != INVALID; graph->next(it)) { + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -1715,16 +1285,15 @@ template class UEdgeMap - : public IterableMapExtender > { + : public MapExtender > { public: typedef BpUGraphExtender Graph; - typedef IterableMapExtender > - Parent; + typedef MapExtender > Parent; - UEdgeMap(const Graph& _g) - : Parent(_g) {} - UEdgeMap(const Graph& _g, const _Value& _v) - : Parent(_g, _v) {} + UEdgeMap(const Graph& graph) + : Parent(graph) {} + UEdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); @@ -1733,9 +1302,9 @@ template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); - const typename Parent::Graph* graph = Parent::getGraph(); - UEdge it; - for (graph->first(it); it != INVALID; graph->next(it)) { + const typename Parent::Notifier* notifier = Parent::getNotifier(); + Edge it; + for (notifier->first(it); it != INVALID; notifier->next(it)) { Parent::set(it, cmap[it]); } return *this; @@ -1801,12 +1370,20 @@ } + BpUGraphExtender() { + anode_notifier.setContainer(*this); + bnode_notifier.setContainer(*this); + node_notifier.setContainer(*this); + edge_notifier.setContainer(*this); + uedge_notifier.setContainer(*this); + } + ~BpUGraphExtender() { - getNotifier(Edge()).clear(); - getNotifier(UEdge()).clear(); - getNotifier(Node()).clear(); - getNotifier(BNode()).clear(); - getNotifier(ANode()).clear(); + uedge_notifier.clear(); + edge_notifier.clear(); + node_notifier.clear(); + anode_notifier.clear(); + bnode_notifier.clear(); } diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/map_extender.h --- a/lemon/bits/map_extender.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/map_extender.h Mon Mar 06 10:28:37 2006 +0000 @@ -29,12 +29,14 @@ namespace lemon { /// \ingroup graphbits + /// + /// \brief Extender for maps template - class IterableMapExtender : public _Map { + class MapExtender : public _Map { public: typedef _Map Parent; - typedef IterableMapExtender Map; + typedef MapExtender Map; typedef typename Parent::Graph Graph; @@ -49,26 +51,36 @@ friend class MapIt; friend class ConstMapIt; - protected: - - using Parent::getGraph; - public: - IterableMapExtender(const Graph& graph) : Parent(graph) {} + MapExtender(const Graph& graph) + : Parent(graph) {} - IterableMapExtender(const Graph& graph, const Value& value) + MapExtender(const Graph& graph, const Value& value) : Parent(graph, value) {} - class MapIt : public ItemSetTraits::ItemIt { + class MapIt : public Item { public: - typedef typename ItemSetTraits::ItemIt Parent; - + typedef Item Parent; typedef typename Map::Value Value; - MapIt(Map& _map) : Parent(*_map.getGraph()), map(_map) {} + MapIt() {} + + MapIt(Invalid i) : Parent(i) { } + + explicit MapIt(Map& _map) : map(_map) { + map.getNotifier()->first(*this); + } + + MapIt(const Map& _map, const Item& item) + : Parent(item), map(_map) {} + + MapIt& operator++() { + map.getNotifier()->next(*this); + return *this; + } typename MapTraits::ConstReturnValue operator*() const { return map[*this]; @@ -87,28 +99,60 @@ }; - class ConstMapIt : public ItemSetTraits::ItemIt { + class ConstMapIt : public Item { public: - typedef typename ItemSetTraits::ItemIt Parent; + typedef Item Parent; typedef typename Map::Value Value; + + ConstMapIt() {} - ConstMapIt(const Map& _map) : Parent(*_map.getGraph()), map(_map) {} + ConstMapIt(Invalid i) : Parent(i) { } + + explicit ConstMapIt(Map& _map) : map(_map) { + map.getNotifier()->first(*this); + } + + ConstMapIt(const Map& _map, const Item& item) + : Parent(item), map(_map) {} + + ConstMapIt& operator++() { + map.getNotifier()->next(*this); + return *this; + } typename MapTraits::ConstReturnValue operator*() const { return map[*this]; } + protected: const Map& map; }; - class ItemIt : public ItemSetTraits::ItemIt { + class ItemIt : Item { public: - typedef typename ItemSetTraits::ItemIt Parent; + typedef Item Parent; + + ItemIt() {} - ItemIt(Map& _map) : Parent(*_map.getGraph()) {} + ItemIt(Invalid i) : Parent(i) { } + + explicit ItemIt(Map& _map) : map(_map) { + map->getNotifier()->first(*this); + } + + ItemIt(const Map& _map, const Item& item) + : Parent(item), map(_map) {} + + ItemIt& operator++() { + map.getNotifier()->next(*this); + return *this; + } + + protected: + const Map& map; }; }; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/static_map.h --- a/lemon/bits/static_map.h Mon Mar 06 09:38:19 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -/* -*- C++ -*- - * - * This file is a part of LEMON, a generic C++ optimization library - * - * Copyright (C) 2003-2006 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport - * (Egervary Research Group on Combinatorial Optimization, EGRES). - * - * Permission to use, modify and distribute this software is granted - * provided that this copyright notice appears in all copies. For - * precise terms see the accompanying LICENSE file. - * - * This software is provided "AS IS" with no warranty of any kind, - * express or implied, and with no claim as to its suitability for any - * purpose. - * - */ - -#ifndef LEMON_STATIC_MAP_H -#define LEMON_STATIC_MAP_H - -#include -#include - -#include -#include -#include -#include -#include -#include - -/// \ingroup graphmaps -/// -///\file -///\brief Static sized graph maps. - -namespace lemon { - - /// \ingroup graphmaps - /// - /// \brief Graph map with static sized storage. - /// - /// The StaticMap template class is graph map structure what - /// does not indate automatically the map when a key is added to or - /// erased from the map rather it throws an exception. This map factory - /// uses the allocators to implement the container functionality. - /// - /// \param Registry The AlterationNotifier that will notify this map. - /// \param Item The item type of the graph items. - /// \param Value The value type of the map. - /// - /// \author Balazs Dezso - - - template - class StaticMap : public AlterationNotifier<_Item>::ObserverBase { - public: - - /// \brief Exception class for unsupported exceptions. - class UnsupportedOperation : public lemon::LogicError { - public: - virtual const char* exceptionName() const { - return "lemon::StaticMap::UnsupportedOperation"; - } - }; - - private: - - typedef std::vector<_Value> Container; - - public: - - /// The graph type of the map. - typedef _Graph Graph; - /// The reference map tag. - typedef True ReferenceMapTag; - - /// The key type of the map. - typedef _Item Key; - /// The value type of the map. - typedef _Value Value; - /// The const reference type of the map. - typedef typename Container::const_reference ConstReference; - /// The reference type of the map. - typedef typename Container::reference Reference; - - typedef const Value ConstValue; - typedef Value* Pointer; - typedef const Value* ConstPointer; - - typedef AlterationNotifier<_Item> Registry; - - /// The map type. - typedef StaticMap Map; - /// The base class of the map. - typedef typename Registry::ObserverBase Parent; - - /// \brief Constructor to attach the new map into the registry. - /// - /// It constructs a map and attachs it into the registry. - /// It adds all the items of the graph to the map. - StaticMap(const Graph& _g) : graph(&_g) { - attach(_g.getNotifier(_Item())); - build(); - } - - /// \brief Constructor uses given value to initialize the map. - /// - /// It constructs a map uses a given value to initialize the map. - /// It adds all the items of the graph to the map. - StaticMap(const Graph& _g, const Value& _v) : graph(&_g) { - attach(_g.getNotifier(_Item())); - unsigned size = graph->maxId(_Item()) + 1; - container.reserve(size); - container.resize(size, _v); - } - - /// \brief Copy constructor - /// - /// Copy constructor. - StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) { - if (_copy.attached()) { - attach(*_copy.getRegistry()); - container = _copy.container; - } - } - - /// \brief Destrcutor - /// - /// Destructor. - virtual ~StaticMap() { - clear(); - if (attached()) { - detach(); - } - } - - - private: - - StaticMap& operator=(const StaticMap&); - - protected: - - using Parent::attach; - using Parent::detach; - using Parent::attached; - - const Graph* getGraph() const { - return graph; - } - - public: - - /// \brief The subcript operator. - /// - /// The subscript operator. The map can be subscripted by the - /// actual items of the graph. - - Reference operator[](const Key& key) { - return container[graph->id(key)]; - } - - /// \brief The const subcript operator. - /// - /// The const subscript operator. The map can be subscripted by the - /// actual items of the graph. - - ConstReference operator[](const Key& key) const { - return container[graph->id(key)]; - } - - - /// \brief The setter function of the map. - /// - /// It the same as operator[](key) = value expression. - /// - void set(const Key& key, const Value& value) { - (*this)[key] = value; - } - - protected: - - /// \brief Adds a new key to the map. - /// - /// It adds a new key to the map. It called by the observer registry - /// and it overrides the add() member function of the observer base. - - void add(const Key&) { - throw UnsupportedOperation(); - } - - /// \brief Erases a key from the map. - /// - /// Erase a key from the map. It called by the observer registry - /// and it overrides the erase() member function of the observer base. - void erase(const Key&) { - throw UnsupportedOperation(); - } - - /// Buildes the map. - - /// It buildes the map. It called by the observer registry - /// and it overrides the build() member function of the observer base. - - void build() { - int size = graph->maxId(_Item()) + 1; - container.reserve(size); - container.resize(size); - } - - /// Clear the map. - - /// It erase all items from the map. It called by the observer registry - /// and it overrides the clear() member function of the observer base. - void clear() { - container.clear(); - } - - private: - - Container container; - const Graph *graph; - - }; - -} - -#endif diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/bits/vector_map.h --- a/lemon/bits/vector_map.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/bits/vector_map.h Mon Mar 06 10:28:37 2006 +0000 @@ -16,23 +16,21 @@ * */ -#ifndef LEMON_VECTOR_MAP_H -#define LEMON_VECTOR_MAP_H +#ifndef LEMON_BITS_VECTOR_MAP_H +#define LEMON_BITS_VECTOR_MAP_H #include #include +#include #include -#include + #include -#include -#include -/// \ingroup graphbits +///\ingroup graphbits /// ///\file ///\brief Vector based graph maps. - namespace lemon { /// \ingroup graphbits @@ -40,23 +38,19 @@ /// \brief Graph map based on the std::vector storage. /// /// The VectorMap template class is graph map structure what - /// automatically indates the map when a key is added to or erased from + /// automatically updates the map when a key is added to or erased from /// the map. This map factory uses the allocators to implement /// the container functionality. This map factory /// uses the std::vector to implement the container function. /// - /// \param Registry The AlterationNotifier that will notify this map. + /// \param Notifier The AlterationNotifier that will notify this map. /// \param Item The item type of the graph items. /// \param Value The value type of the map. /// - /// \author Balazs Dezso - - template < - typename _Graph, - typename _Item, - typename _Value - > - class VectorMap : public AlterationNotifier<_Item>::ObserverBase { + /// \author Balazs Dezso + template + class VectorMap + : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { private: /// The container type of the map. @@ -66,6 +60,8 @@ /// The graph type of the map. typedef _Graph Graph; + /// The item type of the map. + typedef _Item Item; /// The reference map tag. typedef True ReferenceMapTag; @@ -74,79 +70,52 @@ /// The value type of the map. typedef _Value Value; - typedef AlterationNotifier<_Item> Registry; + /// The notifier type. + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier; /// The map type. typedef VectorMap Map; /// The base class of the map. - typedef typename Registry::ObserverBase Parent; + typedef typename Notifier::ObserverBase Parent; /// The reference type of the map; typedef typename Container::reference Reference; - /// The pointer type of the map; - typedef typename Container::pointer Pointer; - - /// The const value type of the map. - typedef const Value ConstValue; /// The const reference type of the map; typedef typename Container::const_reference ConstReference; - /// The pointer type of the map; - typedef typename Container::const_pointer ConstPointer; - /// \brief Constructor to attach the new map into the registry. + /// \brief Constructor to attach the new map into the notifier. /// - /// It constructs a map and attachs it into the registry. + /// It constructs a map and attachs it into the notifier. /// It adds all the items of the graph to the map. - VectorMap(const Graph& _g) : graph(&_g) { - attach(_g.getNotifier(_Item())); - build(); + VectorMap(const Graph& graph) { + Parent::attach(graph.getNotifier(Item())); + container.resize(Parent::getNotifier()->maxId() + 1); } /// \brief Constructor uses given value to initialize the map. /// /// It constructs a map uses a given value to initialize the map. /// It adds all the items of the graph to the map. - VectorMap(const Graph& _g, const Value& _v) : graph(&_g) { - attach(_g.getNotifier(_Item())); - container.resize(graph->maxId(_Item()) + 1, _v); + VectorMap(const Graph& graph, const Value& value) { + Parent::attach(graph.getNotifier(Item())); + container.resize(Parent::getNotifier()->maxId() + 1, value); } /// \brief Copy constructor /// /// Copy constructor. - VectorMap(const VectorMap& _copy) - : Parent(), graph(_copy.getGraph()) { + VectorMap(const VectorMap& _copy) : Parent() { if (_copy.attached()) { - attach(*_copy.getRegistry()); + Parent::attach(*_copy.getNotifier()); container = _copy.container; } } - /// \brief Destrcutor - /// - /// Destructor. - virtual ~VectorMap() { - if (attached()) { - detach(); - } - } - - private: VectorMap& operator=(const VectorMap&); - protected: - - using Parent::attach; - using Parent::detach; - using Parent::attached; - - const Graph* getGraph() const { - return graph; - } - public: /// \brief The subcript operator. @@ -154,7 +123,7 @@ /// The subscript operator. The map can be subscripted by the /// actual items of the graph. Reference operator[](const Key& key) { - return container[graph->id(key)]; + return container[Parent::getNotifier()->id(key)]; } /// \brief The const subcript operator. @@ -162,7 +131,7 @@ /// The const subscript operator. The map can be subscripted by the /// actual items of the graph. ConstReference operator[](const Key& key) const { - return container[graph->id(key)]; + return container[Parent::getNotifier()->id(key)]; } @@ -177,10 +146,10 @@ /// \brief Adds a new key to the map. /// - /// It adds a new key to the map. It called by the observer registry + /// It adds a new key to the map. It called by the observer notifier /// and it overrides the add() member function of the observer base. virtual void add(const Key& key) { - int id = graph->id(key); + int id = Parent::getNotifier()->id(key); if (id >= (int)container.size()) { container.resize(id + 1); } @@ -188,37 +157,50 @@ /// \brief Adds more new keys to the map. /// - /// It adds more new keys to the map. It called by the observer registry + /// It adds more new keys to the map. It called by the observer notifier /// and it overrides the add() member function of the observer base. virtual void add(const std::vector& keys) { + int max = container.size() - 1; for (int i = 0; i < (int)keys.size(); ++i) { - add(keys[i]); + int id = Parent::getNotifier()->id(keys[i]); + if (id >= max) { + max = id; + } } + container.resize(max + 1); } /// \brief Erase a key from the map. /// - /// Erase a key from the map. It called by the observer registry + /// Erase a key from the map. It called by the observer notifier /// and it overrides the erase() member function of the observer base. - virtual void erase(const Key&) {} + virtual void erase(const Key& key) { + container[Parent::getNotifier()->id(key)] = Value(); + } /// \brief Erase more keys from the map. /// - /// Erase more keys from the map. It called by the observer registry + /// Erase more keys from the map. It called by the observer notifier /// and it overrides the erase() member function of the observer base. - virtual void erase(const std::vector&) {} + virtual void erase(const std::vector& keys) { + for (int i = 0; i < (int)keys.size(); ++i) { + container[Parent::getNotifier()->id(keys[i])] = Value(); + } + } /// \brief Buildes the map. /// - /// It buildes the map. It called by the observer registry + /// It buildes the map. It called by the observer notifier /// and it overrides the build() member function of the observer base. virtual void build() { - container.resize(graph->maxId(_Item()) + 1); + int size = Parent::getNotifier()->maxId() + 1; + container.reserve(size); + container.resize(size); } /// \brief Clear the map. /// - /// It erase all items from the map. It called by the observer registry + /// It erase all items from the map. It called by the observer notifier /// and it overrides the clear() member function of the observer base. virtual void clear() { container.clear(); @@ -227,7 +209,6 @@ private: Container container; - const Graph *graph; }; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/concept/graph_component.h --- a/lemon/concept/graph_component.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/concept/graph_component.h Mon Mar 06 10:28:37 2006 +0000 @@ -737,13 +737,15 @@ /// This is an observer-notifier pattern. More Obsevers can /// be registered into the notifier and whenever an alteration /// occured in the graph all the observers will notified about it. - class AlterableGraphComponent : virtual public BaseGraphComponent { + class AlterableGraphComponent : virtual public BaseIterableGraphComponent { public: /// The edge observer registry. - typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier + EdgeNotifier; /// The node observer registry. - typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier + NodeNotifier; /// \brief Gives back the edge alteration notifier. /// diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/dag_shortest_path.h --- a/lemon/dag_shortest_path.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/dag_shortest_path.h Mon Mar 06 10:28:37 2006 +0000 @@ -329,7 +329,7 @@ /// \brief The operation traits. typedef typename _Traits::OperationTraits OperationTraits; /// \brief The Node weight map. - typedef typename Graph::NodeMap WeightMap; + typedef typename Graph::template NodeMap WeightMap; private: /// Pointer to the underlying graph const Graph *graph; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/edge_set.h --- a/lemon/edge_set.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/edge_set.h Mon Mar 06 10:28:37 2006 +0000 @@ -571,7 +571,11 @@ typedef typename Parent::NodesImplBase NodesImplBase; - void eraseNode(const Node&) { + void eraseNode(const Node& node) { + if (Parent::InEdgeIt(*this, node) == INVALID && + Parent::OutEdgeIt(*this, node) == INVALID) { + return; + } throw UnsupportedOperation(); } @@ -662,7 +666,10 @@ typedef typename Parent::NodesImplBase NodesImplBase; - void eraseNode(const Node&) { + void eraseNode(const Node& node) { + if (Parent::IncEdgeIt(*this, node) == INVALID) { + return; + } throw UnsupportedOperation(); } diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/full_graph.h --- a/lemon/full_graph.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/full_graph.h Mon Mar 06 10:28:37 2006 +0000 @@ -21,10 +21,9 @@ #include - +#include #include - #include #include diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/graph_adaptor.h --- a/lemon/graph_adaptor.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/graph_adaptor.h Mon Mar 06 10:28:37 2006 +0000 @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -937,7 +938,7 @@ protected: UndirGraphAdaptorBase() - : Parent(), edge_notifier(), edge_notifier_proxy(edge_notifier) {} + : edge_notifier(*this), edge_notifier_proxy(edge_notifier) {} void setGraph(_Graph& graph) { Parent::setGraph(graph); @@ -947,7 +948,11 @@ public: ~UndirGraphAdaptorBase() { - getNotifier(Edge()).clear(); + edge_notifier.clear(); + } + + int maxId(typename Parent::Edge) const { + return Parent::maxEdgeId(); } @@ -958,7 +963,7 @@ using Parent::getNotifier; - typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier EdgeNotifier; EdgeNotifier& getNotifier(Edge) const { return edge_notifier; } protected: diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/graph_utils.h --- a/lemon/graph_utils.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/graph_utils.h Mon Mar 06 10:28:37 2006 +0000 @@ -1189,8 +1189,8 @@ virtual void build() { Map::build(); Item it; - const typename Map::Graph* graph = Map::getGraph(); - for (graph->first(it); it != INVALID; graph->next(it)) { + const typename Map::Notifier* notifier = Map::getNotifier(); + for (notifier->first(it); it != INVALID; notifier->next(it)) { Map::set(it, invMap.size()); invMap.push_back(it); } @@ -1497,7 +1497,8 @@ template class InDegMap - : protected AlterationNotifier::ObserverBase { + : protected ItemSetTraits<_Graph, typename _Graph::Edge> + ::ItemNotifier::ObserverBase { public: @@ -1505,6 +1506,9 @@ typedef int Value; typedef typename Graph::Node Key; + typedef typename ItemSetTraits<_Graph, typename _Graph::Edge> + ::ItemNotifier::ObserverBase Parent; + private: class AutoNodeMap : public DefaultMap<_Graph, Key, int> { @@ -1533,18 +1537,12 @@ /// /// Constructor for creating in-degree map. InDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { - AlterationNotifier - ::ObserverBase::attach(graph.getNotifier(typename _Graph::Edge())); + Parent::attach(graph.getNotifier(typename _Graph::Edge())); for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) { deg[it] = countInEdges(graph, it); } } - - virtual ~InDegMap() { - AlterationNotifier:: - ObserverBase::detach(); - } /// Gives back the in-degree of a Node. int operator[](const Key& key) const { @@ -1611,9 +1609,13 @@ template class OutDegMap - : protected AlterationNotifier::ObserverBase { + : protected ItemSetTraits<_Graph, typename _Graph::Edge> + ::ItemNotifier::ObserverBase { public: + + typedef typename ItemSetTraits<_Graph, typename _Graph::Edge> + ::ItemNotifier::ObserverBase Parent; typedef _Graph Graph; typedef int Value; @@ -1646,19 +1648,13 @@ /// /// Constructor for creating out-degree map. OutDegMap(const Graph& _graph) : graph(_graph), deg(_graph) { - AlterationNotifier - ::ObserverBase::attach(graph.getNotifier(typename _Graph::Edge())); + Parent::attach(graph.getNotifier(typename _Graph::Edge())); for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) { deg[it] = countOutEdges(graph, it); } } - virtual ~OutDegMap() { - AlterationNotifier:: - ObserverBase::detach(); - } - /// Gives back the out-degree of a Node. int operator[](const Key& key) const { return deg[key]; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/grid_ugraph.h --- a/lemon/grid_ugraph.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/grid_ugraph.h Mon Mar 06 10:28:37 2006 +0000 @@ -23,6 +23,7 @@ #include #include +#include #include #include diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/list_graph.h --- a/lemon/list_graph.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/list_graph.h Mon Mar 06 10:28:37 2006 +0000 @@ -23,6 +23,7 @@ ///\file ///\brief ListGraph, ListUGraph classes. +#include #include #include @@ -320,9 +321,11 @@ ///it also provides several additional useful extra functionalities. ///\sa concept::ErasableGraph. - class ListGraph : public ExtendedListGraphBase - { + class ListGraph : public ExtendedListGraphBase { public: + + typedef ExtendedListGraphBase Parent; + /// Changes the target of \c e to \c n /// Changes the target of \c e to \c n @@ -446,8 +449,8 @@ /// ///\warning Edge and node deletions cannot be restored. ///\warning Snapshots cannot be nested. - class Snapshot : protected AlterationNotifier::ObserverBase, - protected AlterationNotifier::ObserverBase + class Snapshot : protected Parent::NodeNotifier::ObserverBase, + protected Parent::EdgeNotifier::ObserverBase { public: @@ -459,7 +462,7 @@ }; - protected: + protected: ListGraph *g; std::list added_nodes; @@ -490,17 +493,13 @@ void regist(ListGraph &_g) { g=&_g; - AlterationNotifier::ObserverBase:: - attach(g->getNotifier(Node())); - AlterationNotifier::ObserverBase:: - attach(g->getNotifier(Edge())); + Parent::NodeNotifier::ObserverBase::attach(g->getNotifier(Node())); + Parent::EdgeNotifier::ObserverBase::attach(g->getNotifier(Edge())); } void deregist() { - AlterationNotifier::ObserverBase:: - detach(); - AlterationNotifier::ObserverBase:: - detach(); + Parent::NodeNotifier::ObserverBase::detach(); + Parent::EdgeNotifier::ObserverBase::detach(); g=0; } diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/matrix_maps.h --- a/lemon/matrix_maps.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/matrix_maps.h Mon Mar 06 10:28:37 2006 +0000 @@ -209,9 +209,10 @@ /// it is needed. template class DynamicMatrixMap - : protected AlterationNotifier<_Item>::ObserverBase { + : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { public: - typedef typename AlterationNotifier<_Item>::ObserverBase Parent; + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase + Parent; typedef _Graph Graph; typedef _Item Key; @@ -235,8 +236,8 @@ /// /// Creates an item matrix for the given graph. DynamicMatrixMap(const Graph& _graph) - : graph(_graph), values(size(_graph.maxId(Key()) + 1)) { - Parent::attach(graph.getNotifier(Key())); + : values(size(_graph.maxId(Key()) + 1)) { + Parent::attach(_graph.getNotifier(Key())); } /// \brief Creates an item matrix for the given graph @@ -244,14 +245,8 @@ /// Creates an item matrix for the given graph and assigns for each /// pairs of keys the given parameter. DynamicMatrixMap(const Graph& _graph, const Value& _val) - : graph(_graph), values(size(_graph.maxId(Key()) + 1), _val) { - Parent::attach(graph.getNotifier(Key())); - } - - ~DynamicMatrixMap() { - if (Parent::attached()) { - Parent::detach(); - } + : values(size(_graph.maxId(Key()) + 1), _val) { + Parent::attach(_graph.getNotifier(Key())); } /// \brief Gives back the value assigned to the \c first - \c second @@ -259,7 +254,8 @@ /// /// Gives back the value assigned to the \c first - \c second ordered pair. ConstReference operator()(const Key& first, const Key& second) const { - return values[index(graph.id(first), graph.id(second))]; + return values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))]; } /// \brief Gives back the value assigned to the \c first - \c second @@ -267,14 +263,16 @@ /// /// Gives back the value assigned to the \c first - \c second ordered pair. Reference operator()(const Key& first, const Key& second) { - return values[index(graph.id(first), graph.id(second))]; + return values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))]; } /// \brief Setter function for the matrix map. /// /// Setter function for the matrix map. void set(const Key& first, const Key& second, const Value& val) { - values[index(graph.id(first), graph.id(second))] = val; + values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))] = val; } protected: @@ -292,15 +290,15 @@ } virtual void add(const Key& key) { - if (size(graph.id(key) + 1) >= (int)values.size()) { - values.resize(size(graph.id(key) + 1)); + if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { + values.resize(size(Parent::getNotifier()->id(key) + 1)); } } virtual void erase(const Key&) {} virtual void build() { - values.resize(size(graph.maxId(Key()) + 1)); + values.resize(size(Parent::getNotifier()->maxId() + 1)); } virtual void clear() { @@ -308,7 +306,6 @@ } private: - const Graph& graph; std::vector values; }; @@ -320,9 +317,10 @@ /// it is needed. template class DynamicSymMatrixMap - : protected AlterationNotifier<_Item>::ObserverBase { + : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { public: - typedef typename AlterationNotifier<_Item>::ObserverBase Parent; + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase + Parent; typedef _Graph Graph; typedef _Item Key; @@ -346,8 +344,8 @@ /// /// Creates an item matrix for the given graph. DynamicSymMatrixMap(const Graph& _graph) - : graph(_graph), values(size(_graph.maxId(Key()) + 1)) { - Parent::attach(graph.getNotifier(Key())); + : values(size(_graph.maxId(Key()) + 1)) { + Parent::attach(_graph.getNotifier(Key())); } /// \brief Creates an item matrix for the given graph @@ -355,14 +353,8 @@ /// Creates an item matrix for the given graph and assigns for each /// pairs of keys the given parameter. DynamicSymMatrixMap(const Graph& _graph, const Value& _val) - : graph(_graph), values(size(_graph.maxId(Key()) + 1), _val) { - Parent::attach(graph.getNotifier(Key())); - } - - ~DynamicSymMatrixMap() { - if (Parent::attached()) { - Parent::detach(); - } + : values(size(_graph.maxId(Key()) + 1), _val) { + Parent::attach(_graph.getNotifier(Key())); } /// \brief Gives back the value assigned to the \c first - \c second @@ -371,7 +363,8 @@ /// Gives back the value assigned to the \c first - \c second unordered /// pair. ConstReference operator()(const Key& first, const Key& second) const { - return values[index(graph.id(first), graph.id(second))]; + return values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))]; } /// \brief Gives back the value assigned to the \c first - \c second @@ -380,14 +373,16 @@ /// Gives back the value assigned to the \c first - \c second unordered /// pair. Reference operator()(const Key& first, const Key& second) { - return values[index(graph.id(first), graph.id(second))]; + return values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))]; } /// \brief Setter function for the matrix map. /// /// Setter function for the matrix map. void set(const Key& first, const Key& second, const Value& val) { - values[index(graph.id(first), graph.id(second))] = val; + values[index(Parent::getNotifier()->id(first), + Parent::getNotifier()->id(second))] = val; } protected: @@ -405,15 +400,15 @@ } virtual void add(const Key& key) { - if (size(graph.id(key) + 1) >= (int)values.size()) { - values.resize(size(graph.id(key) + 1)); + if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { + values.resize(size(Parent::getNotifier()->id(key) + 1)); } } virtual void erase(const Key&) {} virtual void build() { - values.resize(size(graph.maxId(Key()) + 1)); + values.resize(size(Parent::getNotifier()->maxId() + 1)); } virtual void clear() { @@ -421,7 +416,6 @@ } private: - const Graph& graph; std::vector values; }; diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/smart_graph.h --- a/lemon/smart_graph.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/smart_graph.h Mon Mar 06 10:28:37 2006 +0000 @@ -27,6 +27,7 @@ #include +#include #include #include diff -r 2ba916d7aae3 -r 2ff283124dfc lemon/xy.h --- a/lemon/xy.h Mon Mar 06 09:38:19 2006 +0000 +++ b/lemon/xy.h Mon Mar 06 10:28:37 2006 +0000 @@ -151,6 +151,15 @@ }; + ///Returns an xy + + ///Returns an xy + ///\relates xy + template + inline xy make_xy(const T& x, const T& y) { + return xy(x, y); + } + ///Returns a vector multiplied by a scalar ///Returns a vector multiplied by a scalar