diff -r ca63ec3424d8 -r bd01c5a3f989 src/lemon/alteration_observer_registry.h --- a/src/lemon/alteration_observer_registry.h Thu Dec 16 12:15:02 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -/* -*- C++ -*- - * src/lemon/notifier.h - Part of LEMON, a generic C++ optimization library - * - * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport - * (Egervary Combinatorial Optimization Research Group, 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_ALTERATION_OBSERVER_REGISTRY_H -#define LEMON_ALTERATION_OBSERVER_REGISTRY_H - -#include -#include - -///\ingroup graphmaps -///\file -///\brief Observer registry for graph alteration observers. - -using namespace std; - -namespace lemon { - - /// \addtogroup graphmaps - /// @{ - - /// Registry class to register objects observes alterations in the graph. - - /// 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. - /// - /// The most important application of the alteration observing is the - /// dynamic map implementation when the observers are observing the - /// alterations in the graph. - /// - /// \param _Item The item type what the observers are observing, usually - /// edge or node. - /// - /// \author Balazs Dezso - - template - class AlterationNotifier { - public: - typedef _Item Item; - - /// 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. - /// - /// The observer interface contains some pure virtual functions - /// to override. The add() and erase() functions are - /// to notify the oberver when one item is added or - /// erased. - /// - /// The build() and clear() members are to notify the observer - /// about the container is builded from an empty container or - /// is cleared to an empty container. - /// - /// \author Balazs Dezso - - class ObserverBase { - protected: - typedef AlterationNotifier Registry; - - friend class AlterationNotifier; - - /// Default constructor. - - /// Default constructor for ObserverBase. - /// - ObserverBase() : registry(0) {} - - virtual ~ObserverBase() {} - - /// Attaches the observer into an AlterationNotifier. - - /// This member attaches the observer into an AlterationNotifier. - /// - void attach(AlterationNotifier& r) { - registry = &r; - registry->attach(*this); - } - - /// Detaches the observer into an AlterationNotifier. - - /// This member detaches the observer from an AlterationNotifier. - /// - void detach() { - if (registry) { - registry->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 - /// attached into. - /// - Registry* getRegistry() const { return const_cast(registry); } - - /// Gives back true when the observer is attached into a registry. - bool attached() const { return registry != 0; } - - private: - - ObserverBase(const ObserverBase& copy); - ObserverBase& operator=(const ObserverBase& copy); - - protected: - - Registry* registry; - int registry_index; - - public: - - /// \brief The member function to notificate the observer about an - /// item is added to the container. - /// - /// The add() member function notificates the observer about an item - /// is added to the container. It have to be overrided in the - /// subclasses. - - virtual void add(const Item&) = 0; - - - /// \brief The member function to notificate the observer about an - /// item is erased from the container. - /// - /// The erase() member function notificates the observer about an - /// item is erased from the container. It have to be overrided in - /// the subclasses. - - virtual void erase(const Item&) = 0; - - /// \brief The member function to notificate the observer about the - /// container is builded. - /// - /// The build() member function notificates the observer about the - /// container is builded from an empty container. It have to be - /// overrided in the subclasses. - - virtual void build() = 0; - - /// \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; - - }; - - protected: - - - typedef std::vector Container; - - Container container; - - - public: - - /// Default constructor. - - /// - /// The default constructor of the AlterationNotifier. - /// It creates an empty registry. - AlterationNotifier() {} - - /// 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 AlterationObserverRegistry&) {} - - /// Assign operator. - - /// Assign operator for the AlterationNotifier. - /// It makes the registry only empty because the copiable - /// registry's observers have to be registered still into that registry. - AlterationNotifier& operator=(const AlterationObserverRegistry&) { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->registry = 0; - } - } - - /// Destructor. - - /// Destructor of the AlterationNotifier. - /// - ~AlterationNotifier() { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->registry = 0; - } - } - - - protected: - - void attach(ObserverBase& observer) { - container.push_back(&observer); - observer.registry = this; - observer.registry_index = container.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; - } - - public: - - /// Notifies all the registered observers about an Item added to the container. - - /// It notifies all the registered observers about an Item added to the container. - /// - void add(const Item& key) { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->add(key); - } - } - - /// Notifies all the registered observers about an Item erased from the container. - - /// It notifies all the registered 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) { - (*it)->erase(key); - } - } - - - /// Notifies all the registered observers about the container is builded. - - /// Notifies all the registered observers about the container is builded - /// from an empty container. - void build() { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->build(); - } - } - - - /// Notifies all the registered observers about all Items are erased. - - /// Notifies all the registered observers about all Items are erased - /// from the container. - void clear() { - typename Container::iterator it; - for (it = container.begin(); it != container.end(); ++it) { - (*it)->clear(); - } - } - }; - - - /// \brief Class to extend a graph with the functionality of alteration - /// observing. - /// - /// AlterableGraphExtender extends the _Base graphs functionality with - /// the possibility of alteration observing. It defines two observer - /// registrys for the nodes and mapes. - /// - /// \todo Document what "alteration observing" is. And probably find a - /// better (shorter) name. - /// - /// \param _Base is the base class to extend. - /// - /// \pre _Base is conform to the BaseGraphComponent concept. - /// - /// \post AlterableGraphExtender<_Base> is conform to the - /// AlterableGraphComponent concept. - /// - /// \author Balazs Dezso - - template - class AlterableGraphExtender : public _Base { - public: - - typedef AlterableGraphExtender Graph; - typedef _Base Parent; - - typedef typename Parent::Node Node; - typedef typename Parent::Edge Edge; - - /// The edge observer registry. - typedef AlterationNotifier EdgeObserverRegistry; - /// The node observer registry. - typedef AlterationNotifier NodeObserverRegistry; - - - protected: - - mutable EdgeNotifier edge_observers; - - mutable NodeNotifier node_observers; - - public: - - EdgeNotifier& getObserverRegistry(Edge = INVALID) const { - return edge_observers; - } - - NodeNotifier& getObserverRegistry(Node = INVALID) const { - return node_observers; - } - - ~AlterableGraphExtender() { - node_observers.clear(); - edge_observers.clear(); - } - - }; - - /// \brief Class to extend an undirected graph with the functionality of - /// alteration observing. - /// - /// \todo Document. - /// - /// \sa AlterableGraphExtender - /// - /// \bug This should be done some other way. Possibilities: template - /// specialization (not very easy, if at all possible); some kind of - /// enable_if boost technique? - - template - class AlterableUndirGraphExtender - : public AlterableGraphExtender<_Base> { - public: - - typedef AlterableUndirGraphExtender Graph; - typedef AlterableGraphExtender<_Base> Parent; - - typedef typename Parent::UndirEdge UndirEdge; - - /// The edge observer registry. - typedef AlterationNotifier UndirEdgeObserverRegistry; - - protected: - - mutable UndirEdgeNotifier undir_edge_observers; - - public: - - using Parent::getNotifier; - UndirEdgeNotifier& getObserverRegistry(UndirEdge) const { - return undir_edge_observers; - } - - ~AlterableUndirGraphExtender() { - undir_edge_observers.clear(); - } - }; - -/// @} - - -} - -#endif