00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
00020 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
00021
00022 #include <vector>
00023 #include <algorithm>
00024
00028
00029 namespace lemon {
00030
00033
00050
00051 template <typename _Item>
00052 class AlterationNotifier {
00053 public:
00054 typedef _Item Item;
00055
00057
00072
00073 class ObserverBase {
00074 protected:
00075 typedef AlterationNotifier Registry;
00076
00077 friend class AlterationNotifier;
00078
00083 ObserverBase() : registry(0) {}
00084
00085 ObserverBase(const ObserverBase& copy) {
00086 if (copy.attached()) {
00087 copy.getRegistry()->attach(*this);
00088 }
00089 }
00090
00091 virtual ~ObserverBase() {}
00092
00097 void attach(AlterationNotifier& r) {
00098 registry = &r;
00099 registry->attach(*this);
00100 }
00101
00106 void detach() {
00107 if (registry) {
00108 registry->detach(*this);
00109 }
00110 }
00111
00112
00114
00118 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
00119
00121 bool attached() const { return registry != 0; }
00122
00123 private:
00124
00125 ObserverBase& operator=(const ObserverBase& copy);
00126
00127 protected:
00128
00129 Registry* registry;
00130 int registry_index;
00131
00138
00139 virtual void add(const Item&) = 0;
00140
00147
00148 virtual void add(const std::vector<Item>& items) {
00149 for (int i = 0; i < (int)items.size(); ++i) {
00150 add(items[i]);
00151 }
00152 }
00153
00160
00161 virtual void erase(const Item&) = 0;
00162
00169 virtual void erase(const std::vector<Item>& items) {
00170 for (int i = 0; i < (int)items.size(); ++i) {
00171 erase(items[i]);
00172 }
00173 }
00174
00181
00182 virtual void build() = 0;
00183
00190
00191 virtual void clear() = 0;
00192
00193 };
00194
00195 protected:
00196
00197
00198 typedef std::vector<ObserverBase*> Container;
00199
00200 Container container;
00201
00202
00203 public:
00204
00206
00210 AlterationNotifier() {}
00211
00213
00217 AlterationNotifier(const AlterationNotifier&) {}
00218
00220
00224 AlterationNotifier& operator=(const AlterationNotifier&) {
00225 typename Container::iterator it;
00226 for (it = container.begin(); it != container.end(); ++it) {
00227 (*it)->registry = 0;
00228 }
00229 }
00230
00232
00235 ~AlterationNotifier() {
00236 typename Container::iterator it;
00237 for (it = container.begin(); it != container.end(); ++it) {
00238 (*it)->registry = 0;
00239 }
00240 }
00241
00242
00243 protected:
00244
00245 void attach(ObserverBase& observer) {
00246 container.push_back(&observer);
00247 observer.registry = this;
00248 observer.registry_index = container.size()-1;
00249 }
00250
00251 void detach(ObserverBase& base) {
00252 container.back()->registry_index = base.registry_index;
00253 container[base.registry_index] = container.back();
00254 container.pop_back();
00255 base.registry = 0;
00256 }
00257
00258 public:
00259
00266 void add(const Item& item) {
00267 typename Container::iterator it;
00268 for (it = container.begin(); it != container.end(); ++it) {
00269 (*it)->add(item);
00270 }
00271 }
00272
00279 void add(const std::vector<Item>& items) {
00280 typename Container::iterator it;
00281 for (it = container.begin(); it != container.end(); ++it) {
00282 (*it)->add(items);
00283 }
00284 }
00285
00292 void erase(const Item& key) {
00293 typename Container::iterator it;
00294 for (it = container.begin(); it != container.end(); ++it) {
00295 (*it)->erase(key);
00296 }
00297 }
00298
00305 void erase(const std::vector<Item>& items) {
00306 typename Container::iterator it;
00307 for (it = container.begin(); it != container.end(); ++it) {
00308 (*it)->erase(items);
00309 }
00310 }
00311
00317 void build() {
00318 typename Container::iterator it;
00319 for (it = container.begin(); it != container.end(); ++it) {
00320 (*it)->build();
00321 }
00322 }
00323
00324
00330 void clear() {
00331 typename Container::iterator it;
00332 for (it = container.begin(); it != container.end(); ++it) {
00333 (*it)->clear();
00334 }
00335 }
00336 };
00337
00338
00357
00358 template <typename _Base>
00359 class AlterableGraphExtender : public _Base {
00360 public:
00361
00362 typedef AlterableGraphExtender Graph;
00363 typedef _Base Parent;
00364
00365 typedef typename Parent::Node Node;
00366 typedef typename Parent::Edge Edge;
00367
00369 typedef AlterationNotifier<Edge> EdgeNotifier;
00371 typedef AlterationNotifier<Node> NodeNotifier;
00372
00373
00374 protected:
00375
00376 mutable EdgeNotifier edge_notifier;
00377
00378 mutable NodeNotifier node_notifier;
00379
00380 public:
00381
00385 EdgeNotifier& getNotifier(Edge) const {
00386 return edge_notifier;
00387 }
00388
00392 NodeNotifier& getNotifier(Node) const {
00393 return node_notifier;
00394 }
00395
00396 ~AlterableGraphExtender() {
00397 node_notifier.clear();
00398 edge_notifier.clear();
00399 }
00400
00401 };
00402
00403
00404 template <typename _Base>
00405 class AlterableEdgeSetExtender : public _Base {
00406 public:
00407
00408 typedef AlterableEdgeSetExtender Graph;
00409 typedef _Base Parent;
00410
00411 typedef typename Parent::Edge Edge;
00412
00414 typedef AlterationNotifier<Edge> EdgeNotifier;
00415
00416 protected:
00417
00418 mutable EdgeNotifier edge_notifier;
00419
00420 public:
00421
00425 EdgeNotifier& getNotifier(Edge) const {
00426 return edge_notifier;
00427 }
00428
00429 ~AlterableEdgeSetExtender() {
00430 edge_notifier.clear();
00431 }
00432
00433 };
00434
00445
00446 template <typename _Base>
00447 class AlterableUGraphExtender
00448 : public AlterableGraphExtender<_Base> {
00449 public:
00450
00451 typedef AlterableUGraphExtender Graph;
00452 typedef AlterableGraphExtender<_Base> Parent;
00453
00454 typedef typename Parent::UEdge UEdge;
00455
00457 typedef AlterationNotifier<UEdge> UEdgeNotifier;
00458
00459 protected:
00460
00461 mutable UEdgeNotifier u_edge_notifier;
00462
00463 public:
00464
00465 using Parent::getNotifier;
00466 UEdgeNotifier& getNotifier(UEdge) const {
00467 return u_edge_notifier;
00468 }
00469
00470 ~AlterableUGraphExtender() {
00471 u_edge_notifier.clear();
00472 }
00473 };
00474
00475 template <typename _Base>
00476 class AlterableUEdgeSetExtender
00477 : public AlterableEdgeSetExtender<_Base> {
00478 public:
00479
00480 typedef AlterableUEdgeSetExtender Graph;
00481 typedef AlterableEdgeSetExtender<_Base> Parent;
00482
00483 typedef typename Parent::UEdge UEdge;
00484
00485 typedef AlterationNotifier<UEdge> UEdgeNotifier;
00486
00487 protected:
00488
00489 mutable UEdgeNotifier u_edge_notifier;
00490
00491 public:
00492
00493 using Parent::getNotifier;
00494 UEdgeNotifier& getNotifier(UEdge) const {
00495 return u_edge_notifier;
00496 }
00497
00498 ~AlterableUEdgeSetExtender() {
00499 u_edge_notifier.clear();
00500 }
00501 };
00502
00503
00504
00505 template <typename _Base>
00506 class AlterableBpUGraphExtender : public _Base {
00507 public:
00508
00509 typedef _Base Parent;
00510 typedef AlterableBpUGraphExtender Graph;
00511
00512 typedef typename Parent::Node Node;
00513 typedef typename Parent::BNode BNode;
00514 typedef typename Parent::ANode ANode;
00515 typedef typename Parent::Edge Edge;
00516 typedef typename Parent::UEdge UEdge;
00517
00518
00519 typedef AlterationNotifier<Node> NodeNotifier;
00520 typedef AlterationNotifier<BNode> BNodeNotifier;
00521 typedef AlterationNotifier<ANode> ANodeNotifier;
00522 typedef AlterationNotifier<Edge> EdgeNotifier;
00523 typedef AlterationNotifier<UEdge> UEdgeNotifier;
00524
00525 protected:
00526
00527 mutable NodeNotifier nodeNotifier;
00528 mutable BNodeNotifier bNodeNotifier;
00529 mutable ANodeNotifier aNodeNotifier;
00530 mutable EdgeNotifier edgeNotifier;
00531 mutable UEdgeNotifier uEdgeNotifier;
00532
00533 public:
00534
00535 NodeNotifier& getNotifier(Node) const {
00536 return nodeNotifier;
00537 }
00538
00539 BNodeNotifier& getNotifier(BNode) const {
00540 return bNodeNotifier;
00541 }
00542
00543 ANodeNotifier& getNotifier(ANode) const {
00544 return aNodeNotifier;
00545 }
00546
00547 EdgeNotifier& getNotifier(Edge) const {
00548 return edgeNotifier;
00549 }
00550
00551 UEdgeNotifier& getNotifier(UEdge) const {
00552 return uEdgeNotifier;
00553 }
00554
00555 ~AlterableBpUGraphExtender() {
00556 nodeNotifier.clear();
00557 bNodeNotifier.clear();
00558 aNodeNotifier.clear();
00559 edgeNotifier.clear();
00560 uEdgeNotifier.clear();
00561 }
00562
00563 };
00564
00566
00567
00568 }
00569
00570 #endif