[Lemon-commits] deba: r3080 - in hugo/trunk/lemon: . bits
Lemon SVN
svn at lemon.cs.elte.hu
Tue Nov 21 18:28:08 CET 2006
Author: deba
Date: Tue Nov 21 18:28:08 2006
New Revision: 3080
Modified:
hugo/trunk/lemon/bits/alteration_notifier.h
hugo/trunk/lemon/matrix_maps.h
Log:
Keeping order of alteration observers
Removing some automatic callback generation
// exception safety reason
Modified: hugo/trunk/lemon/bits/alteration_notifier.h
==============================================================================
--- hugo/trunk/lemon/bits/alteration_notifier.h (original)
+++ hugo/trunk/lemon/bits/alteration_notifier.h Tue Nov 21 18:28:08 2006
@@ -20,6 +20,7 @@
#define LEMON_BITS_ALTERATION_NOTIFIER_H
#include <vector>
+#include <list>
#include <lemon/bits/utility.h>
@@ -173,8 +174,7 @@
/// This member attaches the observer into an AlterationNotifier.
///
void attach(AlterationNotifier& _notifier) {
- notifier = &_notifier;
- notifier->attach(*this);
+ _notifier.attach(*this);
}
/// \brief Detaches the observer into an AlterationNotifier.
@@ -203,7 +203,7 @@
protected:
Notifier* notifier;
- int notifier_index;
+ typename std::list<ObserverBase*>::iterator index;
/// \brief The member function to notificate the observer about an
/// item is added to the container.
@@ -211,7 +211,6 @@
/// 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
@@ -220,28 +219,14 @@
/// The add() member function notificates the observer about more item
/// is added to the container. It have to be overrided in the
/// subclasses.
-
- virtual void add(const std::vector<Item>& items) {
- 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;
- }
- }
+ virtual void add(const std::vector<Item>& items) = 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.
-
+ /// the subclasses.
virtual void erase(const Item&) = 0;
/// \brief The member function to notificate the observer about
@@ -250,11 +235,7 @@
/// The erase() member function notificates the observer about more item
/// is erased from the container. It have to be overrided in the
/// subclasses.
- virtual void erase(const std::vector<Item>& items) {
- for (int i = 0; i < (int)items.size(); ++i) {
- erase(items[i]);
- }
- }
+ virtual void erase(const std::vector<Item>& items) = 0;
/// \brief The member function to notificate the observer about the
/// container is built.
@@ -263,20 +244,7 @@
/// container is built from an empty container. It have to be
/// overrided in the subclasses.
- 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;
- }
- }
+ virtual void build() = 0;
/// \brief The member function to notificate the observer about all
/// items are erased from the container.
@@ -284,12 +252,7 @@
/// 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() {
- Item it;
- for (notifier->first(it); it != INVALID; notifier->next(it)) {
- erase(it);
- }
- }
+ virtual void clear() = 0;
};
@@ -297,7 +260,7 @@
const Container* container;
- typedef std::vector<ObserverBase*> Observers;
+ typedef std::list<ObserverBase*> Observers;
Observers observers;
@@ -383,15 +346,13 @@
protected:
void attach(ObserverBase& observer) {
- observers.push_back(&observer);
+ observer.index = observers.insert(observers.begin(), &observer);
observer.notifier = this;
- observer.notifier_index = observers.size() - 1;
}
void detach(ObserverBase& observer) {
- observers.back()->notifier_index = observer.notifier_index;
- observers[observer.notifier_index] = observers.back();
- observers.pop_back();
+ observers.erase(observer.index);
+ observer.index = observers.end();
observer.notifier = 0;
}
@@ -404,15 +365,15 @@
/// the container.
///
void add(const Item& item) {
- typename Observers::iterator it;
+ typename Observers::reverse_iterator it;
try {
- for (it = observers.begin(); it != observers.end(); ++it) {
+ for (it = observers.rbegin(); it != observers.rend(); ++it) {
(*it)->add(item);
}
} catch (...) {
typename Observers::iterator jt;
- for (jt = observers.begin(); jt != it; ++jt) {
- (*it)->erase(item);
+ for (jt = it.base(); jt != observers.end(); ++jt) {
+ (*jt)->erase(item);
}
throw;
}
@@ -425,15 +386,15 @@
/// the container.
///
void add(const std::vector<Item>& items) {
- typename Observers::iterator it;
+ typename Observers::reverse_iterator it;
try {
- for (it = observers.begin(); it != observers.end(); ++it) {
+ for (it = observers.rbegin(); it != observers.rend(); ++it) {
(*it)->add(items);
}
} catch (...) {
typename Observers::iterator jt;
- for (jt = observers.begin(); jt != it; ++jt) {
- (*it)->erase(items);
+ for (jt = it.base(); jt != observers.end(); ++jt) {
+ (*jt)->erase(items);
}
throw;
}
@@ -445,14 +406,16 @@
/// It notifies all the registed observers about an item erased from
/// the container.
///
- void erase(const Item& key) throw() {
- int i = 0;
- while (i != (int)observers.size()) {
+ void erase(const Item& item) throw() {
+ typename Observers::iterator it = observers.begin();
+ while (it != observers.end()) {
try {
- observers[i]->erase(key);
- ++i;
+ (*it)->erase(item);
+ ++it;
} catch (const ImmediateDetach&) {
- observers[i]->detach();
+ it = observers.erase(it);
+ (*it)->index = observers.end();
+ (*it)->notifier = 0;
}
}
}
@@ -464,13 +427,15 @@
/// the container.
///
void erase(const std::vector<Item>& items) {
- int i = 0;
- while (i != (int)observers.size()) {
+ typename Observers::iterator it = observers.begin();
+ while (it != observers.end()) {
try {
- observers[i]->erase(items);
- ++i;
+ (*it)->erase(items);
+ ++it;
} catch (const ImmediateDetach&) {
- observers[i]->detach();
+ it = observers.erase(it);
+ (*it)->index = observers.end();
+ (*it)->notifier = 0;
}
}
}
@@ -481,15 +446,15 @@
/// Notifies all the registed observers about the container is built
/// from an empty container.
void build() {
- typename Observers::iterator it;
+ typename Observers::reverse_iterator it;
try {
- for (it = observers.begin(); it != observers.end(); ++it) {
+ for (it = observers.rbegin(); it != observers.rend(); ++it) {
(*it)->build();
}
} catch (...) {
typename Observers::iterator jt;
- for (jt = observers.begin(); jt != it; ++jt) {
- (*it)->clear();
+ for (jt = it.base(); jt != observers.end(); ++jt) {
+ (*jt)->clear();
}
throw;
}
@@ -501,13 +466,15 @@
/// Notifies all the registed observers about all items are erased
/// from the container.
void clear() {
- int i = 0;
- while (i != (int)observers.size()) {
+ typename Observers::iterator it = observers.begin();
+ while (it != observers.end()) {
try {
- observers[i]->clear();
- ++i;
+ (*it)->clear();
+ ++it;
} catch (const ImmediateDetach&) {
- observers[i]->detach();
+ it = observers.erase(it);
+ (*it)->index = observers.end();
+ (*it)->notifier = 0;
}
}
}
Modified: hugo/trunk/lemon/matrix_maps.h
==============================================================================
--- hugo/trunk/lemon/matrix_maps.h (original)
+++ hugo/trunk/lemon/matrix_maps.h Tue Nov 21 18:28:08 2006
@@ -354,8 +354,22 @@
}
}
+ virtual void add(const std::vector<Key>& keys) {
+ int new_size = 0;
+ for (int i = 0; i < (int)keys.size(); ++i) {
+ if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
+ new_size = size(Parent::getNotifier()->id(keys[i]) + 1);
+ }
+ }
+ if (new_size > (int)values.size()) {
+ values.resize(new_size);
+ }
+ }
+
virtual void erase(const Key&) {}
+ virtual void erase(const std::vector<Key>&) {}
+
virtual void build() {
values.resize(size(Parent::getNotifier()->maxId() + 1));
}
@@ -495,8 +509,22 @@
}
}
+ virtual void add(const std::vector<Key>& keys) {
+ int new_size = 0;
+ for (int i = 0; i < (int)keys.size(); ++i) {
+ if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
+ new_size = size(Parent::getNotifier()->id(keys[i]) + 1);
+ }
+ }
+ if (new_size > (int)values.size()) {
+ values.resize(new_size);
+ }
+ }
+
virtual void erase(const Key&) {}
+ virtual void erase(const std::vector<Key>&) {}
+
virtual void build() {
values.resize(size(Parent::getNotifier()->maxId() + 1));
}
More information about the Lemon-commits
mailing list