Changes in lemon/bits/alteration_notifier.h [314:2cc60866a0c9:236:da953e387d31] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/bits/alteration_notifier.h
r314 r236 25 25 #include <lemon/core.h> 26 26 27 // \ingroup graphbits28 // \file29 // \brief Observer notifier for graph alteration observers.27 ///\ingroup graphbits 28 ///\file 29 ///\brief Observer notifier for graph alteration observers. 30 30 31 31 namespace lemon { 32 32 33 // \ingroup graphbits 34 // 35 // \brief Notifier class to notify observes about alterations in 36 // a container. 37 // 38 // The simple graph's can be refered as two containers, one node container 39 // and one edge container. But they are not standard containers they 40 // does not store values directly they are just key continars for more 41 // value containers which are the node and edge maps. 42 // 43 // The graph's node and edge sets can be changed as we add or erase 44 // nodes and edges in the graph. LEMON would like to handle easily 45 // that the node and edge maps should contain values for all nodes or 46 // edges. If we want to check on every indicing if the map contains 47 // the current indicing key that cause a drawback in the performance 48 // in the library. We use another solution we notify all maps about 49 // an alteration in the graph, which cause only drawback on the 50 // alteration of the graph. 51 // 52 // This class provides an interface to the container. The \e first() and \e 53 // next() member functions make possible to iterate on the keys of the 54 // container. The \e id() function returns an integer id for each key. 55 // The \e maxId() function gives back an upper bound of the ids. 56 // 57 // For the proper functonality of this class, we should notify it 58 // about each alteration in the container. The alterations have four type 59 // as \e add(), \e erase(), \e build() and \e clear(). The \e add() and 60 // \e erase() signals that only one or few items added or erased to or 61 // from the graph. If all items are erased from the graph or from an empty 62 // graph a new graph is builded then it can be signaled with the 63 // clear() and build() members. Important rule that if we erase items 64 // from graph we should first signal the alteration and after that erase 65 // them from the container, on the other way on item addition we should 66 // first extend the container and just after that signal the alteration. 67 // 68 // The alteration can be observed with a class inherited from the 69 // \e ObserverBase nested class. The signals can be handled with 70 // overriding the virtual functions defined in the base class. The 71 // observer base can be attached to the notifier with the 72 // \e attach() member and can be detached with detach() function. The 73 // alteration handlers should not call any function which signals 74 // an other alteration in the same notifier and should not 75 // detach any observer from the notifier. 76 // 77 // Alteration observers try to be exception safe. If an \e add() or 78 // a \e clear() function throws an exception then the remaining 79 // observeres will not be notified and the fulfilled additions will 80 // be rolled back by calling the \e erase() or \e clear() 81 // functions. Thence the \e erase() and \e clear() should not throw 82 // exception. Actullay, it can be throw only \ref ImmediateDetach 83 // exception which detach the observer from the notifier. 84 // 85 // There are some place when the alteration observing is not completly 86 // reliable. If we want to carry out the node degree in the graph 87 // as in the \ref InDegMap and we use the reverseEdge that cause 88 // unreliable functionality. Because the alteration observing signals 89 // only erasing and adding but not the reversing it will stores bad 90 // degrees. The sub graph adaptors cannot signal the alterations because 91 // just a setting in the filter map can modify the graph and this cannot 92 // be watched in any way. 93 // 94 // \param _Container The container which is observed. 95 // \param _Item The item type which is obserbved. 33 /// \ingroup graphbits 34 /// 35 /// \brief Notifier class to notify observes about alterations in 36 /// a container. 37 /// 38 /// The simple graph's can be refered as two containers, one node container 39 /// and one edge container. But they are not standard containers they 40 /// does not store values directly they are just key continars for more 41 /// value containers which are the node and edge maps. 42 /// 43 /// The graph's node and edge sets can be changed as we add or erase 44 /// nodes and edges in the graph. LEMON would like to handle easily 45 /// that the node and edge maps should contain values for all nodes or 46 /// edges. If we want to check on every indicing if the map contains 47 /// the current indicing key that cause a drawback in the performance 48 /// in the library. We use another solution we notify all maps about 49 /// an alteration in the graph, which cause only drawback on the 50 /// alteration of the graph. 51 /// 52 /// This class provides an interface to the container. The \e first() and \e 53 /// next() member functions make possible to iterate on the keys of the 54 /// container. The \e id() function returns an integer id for each key. 55 /// The \e maxId() function gives back an upper bound of the ids. 56 /// 57 /// For the proper functonality of this class, we should notify it 58 /// about each alteration in the container. The alterations have four type 59 /// as \e add(), \e erase(), \e build() and \e clear(). The \e add() and 60 /// \e erase() signals that only one or few items added or erased to or 61 /// from the graph. If all items are erased from the graph or from an empty 62 /// graph a new graph is builded then it can be signaled with the 63 /// clear() and build() members. Important rule that if we erase items 64 /// from graph we should first signal the alteration and after that erase 65 /// them from the container, on the other way on item addition we should 66 /// first extend the container and just after that signal the alteration. 67 /// 68 /// The alteration can be observed with a class inherited from the 69 /// \e ObserverBase nested class. The signals can be handled with 70 /// overriding the virtual functions defined in the base class. The 71 /// observer base can be attached to the notifier with the 72 /// \e attach() member and can be detached with detach() function. The 73 /// alteration handlers should not call any function which signals 74 /// an other alteration in the same notifier and should not 75 /// detach any observer from the notifier. 76 /// 77 /// Alteration observers try to be exception safe. If an \e add() or 78 /// a \e clear() function throws an exception then the remaining 79 /// observeres will not be notified and the fulfilled additions will 80 /// be rolled back by calling the \e erase() or \e clear() 81 /// functions. Thence the \e erase() and \e clear() should not throw 82 /// exception. Actullay, it can be throw only 83 /// \ref AlterationObserver::ImmediateDetach ImmediateDetach 84 /// exception which detach the observer from the notifier. 85 /// 86 /// There are some place when the alteration observing is not completly 87 /// reliable. If we want to carry out the node degree in the graph 88 /// as in the \ref InDegMap and we use the reverseEdge that cause 89 /// unreliable functionality. Because the alteration observing signals 90 /// only erasing and adding but not the reversing it will stores bad 91 /// degrees. The sub graph adaptors cannot signal the alterations because 92 /// just a setting in the filter map can modify the graph and this cannot 93 /// be watched in any way. 94 /// 95 /// \param _Container The container which is observed. 96 /// \param _Item The item type which is obserbved. 96 97 97 98 template <typename _Container, typename _Item> … … 104 105 typedef _Item Item; 105 106 106 // \brief Exception which can be called from \e clear() and107 // \e erase().108 // 109 // From the \e clear() and \e erase() function only this110 // exception is allowed to throw. The exception immediatly111 // detaches the current observer from the notifier. Because the112 // \e clear() and \e erase() should not throw other exceptions113 // it can be used to invalidate the observer.107 /// \brief Exception which can be called from \e clear() and 108 /// \e erase(). 109 /// 110 /// From the \e clear() and \e erase() function only this 111 /// exception is allowed to throw. The exception immediatly 112 /// detaches the current observer from the notifier. Because the 113 /// \e clear() and \e erase() should not throw other exceptions 114 /// it can be used to invalidate the observer. 114 115 struct ImmediateDetach {}; 115 116 116 // \brief ObserverBase is the base class for the observers. 117 // 118 // ObserverBase is the abstract base class for the observers. 119 // It will be notified about an item was inserted into or 120 // erased from the graph. 121 // 122 // The observer interface contains some pure virtual functions 123 // to override. The add() and erase() functions are 124 // to notify the oberver when one item is added or 125 // erased. 126 // 127 // The build() and clear() members are to notify the observer 128 // about the container is built from an empty container or 129 // is cleared to an empty container. 117 /// \brief ObserverBase is the base class for the observers. 118 /// 119 /// ObserverBase is the abstract base class for the observers. 120 /// It will be notified about an item was inserted into or 121 /// erased from the graph. 122 /// 123 /// The observer interface contains some pure virtual functions 124 /// to override. The add() and erase() functions are 125 /// to notify the oberver when one item is added or 126 /// erased. 127 /// 128 /// The build() and clear() members are to notify the observer 129 /// about the container is built from an empty container or 130 /// is cleared to an empty container. 131 130 132 class ObserverBase { 131 133 protected: … … 134 136 friend class AlterationNotifier; 135 137 136 // \brief Default constructor. 137 // 138 // Default constructor for ObserverBase. 138 /// \brief Default constructor. 139 /// 140 /// Default constructor for ObserverBase. 141 /// 139 142 ObserverBase() : _notifier(0) {} 140 143 141 // \brief Constructor which attach the observer into notifier.142 // 143 // Constructor which attach the observer into notifier.144 /// \brief Constructor which attach the observer into notifier. 145 /// 146 /// Constructor which attach the observer into notifier. 144 147 ObserverBase(AlterationNotifier& nf) { 145 148 attach(nf); 146 149 } 147 150 148 // \brief Constructor which attach the obserever to the same notifier.149 // 150 // Constructor which attach the obserever to the same notifier as151 // the other observer is attached to.151 /// \brief Constructor which attach the obserever to the same notifier. 152 /// 153 /// Constructor which attach the obserever to the same notifier as 154 /// the other observer is attached to. 152 155 ObserverBase(const ObserverBase& copy) { 153 156 if (copy.attached()) { … … 156 159 } 157 160 158 // \brief Destructor161 /// \brief Destructor 159 162 virtual ~ObserverBase() { 160 163 if (attached()) { … … 163 166 } 164 167 165 // \brief Attaches the observer into an AlterationNotifier. 166 // 167 // This member attaches the observer into an AlterationNotifier. 168 /// \brief Attaches the observer into an AlterationNotifier. 169 /// 170 /// This member attaches the observer into an AlterationNotifier. 171 /// 168 172 void attach(AlterationNotifier& nf) { 169 173 nf.attach(*this); 170 174 } 171 175 172 // \brief Detaches the observer into an AlterationNotifier. 173 // 174 // This member detaches the observer from an AlterationNotifier. 176 /// \brief Detaches the observer into an AlterationNotifier. 177 /// 178 /// This member detaches the observer from an AlterationNotifier. 179 /// 175 180 void detach() { 176 181 _notifier->detach(*this); 177 182 } 178 183 179 // \brief Gives back a pointer to the notifier which the map 180 // attached into. 181 // 182 // This function gives back a pointer to the notifier which the map 183 // attached into. 184 /// \brief Gives back a pointer to the notifier which the map 185 /// attached into. 186 /// 187 /// This function gives back a pointer to the notifier which the map 188 /// attached into. 189 /// 184 190 Notifier* notifier() const { return const_cast<Notifier*>(_notifier); } 185 191 186 // Gives back true when the observer is attached into a notifier.192 /// Gives back true when the observer is attached into a notifier. 187 193 bool attached() const { return _notifier != 0; } 188 194 … … 196 202 typename std::list<ObserverBase*>::iterator _index; 197 203 198 // \brief The member function to notificate the observer about an199 // item is added to the container.200 // 201 // The add() member function notificates the observer about an item202 // is added to the container. It have to be overrided in the203 // subclasses.204 /// \brief The member function to notificate the observer about an 205 /// item is added to the container. 206 /// 207 /// The add() member function notificates the observer about an item 208 /// is added to the container. It have to be overrided in the 209 /// subclasses. 204 210 virtual void add(const Item&) = 0; 205 211 206 // \brief The member function to notificate the observer about207 // more item is added to the container.208 // 209 // The add() member function notificates the observer about more item210 // is added to the container. It have to be overrided in the211 // subclasses.212 /// \brief The member function to notificate the observer about 213 /// more item is added to the container. 214 /// 215 /// The add() member function notificates the observer about more item 216 /// is added to the container. It have to be overrided in the 217 /// subclasses. 212 218 virtual void add(const std::vector<Item>& items) = 0; 213 219 214 // \brief The member function to notificate the observer about an215 // item is erased from the container.216 // 217 // The erase() member function notificates the observer about an218 // item is erased from the container. It have to be overrided in219 // the subclasses.220 /// \brief The member function to notificate the observer about an 221 /// item is erased from the container. 222 /// 223 /// The erase() member function notificates the observer about an 224 /// item is erased from the container. It have to be overrided in 225 /// the subclasses. 220 226 virtual void erase(const Item&) = 0; 221 227 222 // \brief The member function to notificate the observer about223 // more item is erased from the container.224 // 225 // The erase() member function notificates the observer about more item226 // is erased from the container. It have to be overrided in the227 // subclasses.228 /// \brief The member function to notificate the observer about 229 /// more item is erased from the container. 230 /// 231 /// The erase() member function notificates the observer about more item 232 /// is erased from the container. It have to be overrided in the 233 /// subclasses. 228 234 virtual void erase(const std::vector<Item>& items) = 0; 229 235 230 // \brief The member function to notificate the observer about the 231 // container is built. 232 // 233 // The build() member function notificates the observer about the 234 // container is built from an empty container. It have to be 235 // overrided in the subclasses. 236 /// \brief The member function to notificate the observer about the 237 /// container is built. 238 /// 239 /// The build() member function notificates the observer about the 240 /// container is built from an empty container. It have to be 241 /// overrided in the subclasses. 242 236 243 virtual void build() = 0; 237 244 238 // \brief The member function to notificate the observer about all239 // items are erased from the container.240 // 241 // The clear() member function notificates the observer about all242 // items are erased from the container. It have to be overrided in243 // the subclasses.245 /// \brief The member function to notificate the observer about all 246 /// items are erased from the container. 247 /// 248 /// The clear() member function notificates the observer about all 249 /// items are erased from the container. It have to be overrided in 250 /// the subclasses. 244 251 virtual void clear() = 0; 245 252 … … 256 263 public: 257 264 258 // \brief Default constructor.259 // 260 // The default constructor of the AlterationNotifier.261 // It creates an empty notifier.265 /// \brief Default constructor. 266 /// 267 /// The default constructor of the AlterationNotifier. 268 /// It creates an empty notifier. 262 269 AlterationNotifier() 263 270 : container(0) {} 264 271 265 // \brief Constructor.266 // 267 // Constructor with the observed container parameter.272 /// \brief Constructor. 273 /// 274 /// Constructor with the observed container parameter. 268 275 AlterationNotifier(const Container& _container) 269 276 : container(&_container) {} 270 277 271 // \brief Copy Constructor of the AlterationNotifier.272 // 273 // Copy constructor of the AlterationNotifier.274 // It creates only an empty notifier because the copiable275 // notifier's observers have to be registered still into that notifier.278 /// \brief Copy Constructor of the AlterationNotifier. 279 /// 280 /// Copy constructor of the AlterationNotifier. 281 /// It creates only an empty notifier because the copiable 282 /// notifier's observers have to be registered still into that notifier. 276 283 AlterationNotifier(const AlterationNotifier& _notifier) 277 284 : container(_notifier.container) {} 278 285 279 // \brief Destructor. 280 // 281 // Destructor of the AlterationNotifier. 286 /// \brief Destructor. 287 /// 288 /// Destructor of the AlterationNotifier. 289 /// 282 290 ~AlterationNotifier() { 283 291 typename Observers::iterator it; … … 287 295 } 288 296 289 // \brief Sets the container.290 // 291 // Sets the container.297 /// \brief Sets the container. 298 /// 299 /// Sets the container. 292 300 void setContainer(const Container& _container) { 293 301 container = &_container; … … 300 308 public: 301 309 302 // \brief First item in the container. 303 // 304 // Returns the first item in the container. It is 305 // for start the iteration on the container. 310 311 312 /// \brief First item in the container. 313 /// 314 /// Returns the first item in the container. It is 315 /// for start the iteration on the container. 306 316 void first(Item& item) const { 307 317 container->first(item); 308 318 } 309 319 310 // \brief Next item in the container.311 // 312 // Returns the next item in the container. It is313 // for iterate on the container.320 /// \brief Next item in the container. 321 /// 322 /// Returns the next item in the container. It is 323 /// for iterate on the container. 314 324 void next(Item& item) const { 315 325 container->next(item); 316 326 } 317 327 318 // \brief Returns the id of the item.319 // 320 // Returns the id of the item provided by the container.328 /// \brief Returns the id of the item. 329 /// 330 /// Returns the id of the item provided by the container. 321 331 int id(const Item& item) const { 322 332 return container->id(item); 323 333 } 324 334 325 // \brief Returns the maximum id of the container.326 // 327 // Returns the maximum id of the container.335 /// \brief Returns the maximum id of the container. 336 /// 337 /// Returns the maximum id of the container. 328 338 int maxId() const { 329 339 return container->maxId(Item()); … … 345 355 public: 346 356 347 // \brief Notifies all the registed observers about an item added to 348 // the container. 349 // 350 // It notifies all the registed observers about an item added to 351 // the container. 357 /// \brief Notifies all the registed observers about an item added to 358 /// the container. 359 /// 360 /// It notifies all the registed observers about an item added to 361 /// the container. 362 /// 352 363 void add(const Item& item) { 353 364 typename Observers::reverse_iterator it; … … 365 376 } 366 377 367 // \brief Notifies all the registed observers about more item added to 368 // the container. 369 // 370 // It notifies all the registed observers about more item added to 371 // the container. 378 /// \brief Notifies all the registed observers about more item added to 379 /// the container. 380 /// 381 /// It notifies all the registed observers about more item added to 382 /// the container. 383 /// 372 384 void add(const std::vector<Item>& items) { 373 385 typename Observers::reverse_iterator it; … … 385 397 } 386 398 387 // \brief Notifies all the registed observers about an item erased from 388 // the container. 389 // 390 // It notifies all the registed observers about an item erased from 391 // the container. 399 /// \brief Notifies all the registed observers about an item erased from 400 /// the container. 401 /// 402 /// It notifies all the registed observers about an item erased from 403 /// the container. 404 /// 392 405 void erase(const Item& item) throw() { 393 406 typename Observers::iterator it = _observers.begin(); … … 404 417 } 405 418 406 // \brief Notifies all the registed observers about more item erased 407 // from the container. 408 // 409 // It notifies all the registed observers about more item erased from 410 // the container. 419 /// \brief Notifies all the registed observers about more item erased 420 /// from the container. 421 /// 422 /// It notifies all the registed observers about more item erased from 423 /// the container. 424 /// 411 425 void erase(const std::vector<Item>& items) { 412 426 typename Observers::iterator it = _observers.begin(); … … 423 437 } 424 438 425 // \brief Notifies all the registed observers about the container is426 // built.427 // 428 // Notifies all the registed observers about the container is built429 // from an empty container.439 /// \brief Notifies all the registed observers about the container is 440 /// built. 441 /// 442 /// Notifies all the registed observers about the container is built 443 /// from an empty container. 430 444 void build() { 431 445 typename Observers::reverse_iterator it; … … 443 457 } 444 458 445 // \brief Notifies all the registed observers about all items are446 // erased.447 // 448 // Notifies all the registed observers about all items are erased449 // from the container.459 /// \brief Notifies all the registed observers about all items are 460 /// erased. 461 /// 462 /// Notifies all the registed observers about all items are erased 463 /// from the container. 450 464 void clear() { 451 465 typename Observers::iterator it = _observers.begin();
Note: See TracChangeset
for help on using the changeset viewer.