0
5
0
| ... | ... |
@@ -32,67 +32,68 @@ |
| 32 | 32 |
|
| 33 | 33 |
// \ingroup graphbits |
| 34 | 34 |
// |
| 35 | 35 |
// \brief Notifier class to notify observes about alterations in |
| 36 | 36 |
// a container. |
| 37 | 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. |
|
| 38 |
// The simple graphs can be refered as two containers: a node container |
|
| 39 |
// and an edge container. But they do not store values directly, they |
|
| 40 |
// are just key continars for more value containers, which are the |
|
| 41 |
// node and edge maps. |
|
| 42 | 42 |
// |
| 43 |
// The |
|
| 43 |
// The node and edge sets of the graphs can be changed as we add or erase |
|
| 44 | 44 |
// nodes and edges in the graph. LEMON would like to handle easily |
| 45 | 45 |
// that the node and edge maps should contain values for all nodes or |
| 46 | 46 |
// edges. If we want to check on every indicing if the map contains |
| 47 | 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 |
|
| 48 |
// in the library. We use another solution: we notify all maps about |
|
| 49 | 49 |
// an alteration in the graph, which cause only drawback on the |
| 50 | 50 |
// alteration of the graph. |
| 51 | 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. |
|
| 52 |
// This class provides an interface to a node or edge container. |
|
| 53 |
// The first() and next() member functions make possible |
|
| 54 |
// to iterate on the keys of the container. |
|
| 55 |
// The id() function returns an integer id for each key. |
|
| 56 |
// The maxId() function gives back an upper bound of the ids. |
|
| 56 | 57 |
// |
| 57 | 58 |
// 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 |
// |
|
| 59 |
// about each alteration in the container. The alterations have four type: |
|
| 60 |
// add(), erase(), build() and clear(). The add() and |
|
| 61 |
// erase() signal that only one or few items added or erased to or |
|
| 62 |
// from the graph. If all items are erased from the graph or if a new graph |
|
| 63 |
// is built from an empty graph, then it can be signaled with the |
|
| 63 | 64 |
// clear() and build() members. Important rule that if we erase items |
| 64 |
// from |
|
| 65 |
// from graphs we should first signal the alteration and after that erase |
|
| 65 | 66 |
// them from the container, on the other way on item addition we should |
| 66 | 67 |
// first extend the container and just after that signal the alteration. |
| 67 | 68 |
// |
| 68 | 69 |
// The alteration can be observed with a class inherited from the |
| 69 |
// |
|
| 70 |
// ObserverBase nested class. The signals can be handled with |
|
| 70 | 71 |
// overriding the virtual functions defined in the base class. The |
| 71 | 72 |
// observer base can be attached to the notifier with the |
| 72 |
// |
|
| 73 |
// attach() member and can be detached with detach() function. The |
|
| 73 | 74 |
// alteration handlers should not call any function which signals |
| 74 | 75 |
// an other alteration in the same notifier and should not |
| 75 | 76 |
// detach any observer from the notifier. |
| 76 | 77 |
// |
| 77 |
// Alteration observers try to be exception safe. If an \e add() or |
|
| 78 |
// a \e clear() function throws an exception then the remaining |
|
| 78 |
// Alteration observers try to be exception safe. If an add() or |
|
| 79 |
// a clear() function throws an exception then the remaining |
|
| 79 | 80 |
// 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. |
|
| 81 |
// be rolled back by calling the erase() or clear() functions. |
|
| 82 |
// Hence erase() and clear() should not throw exception. |
|
| 83 |
// Actullay, they can throw only \ref ImmediateDetach exception, |
|
| 84 |
// which detach the observer from the notifier. |
|
| 84 | 85 |
// |
| 85 |
// There are some |
|
| 86 |
// There are some cases, when the alteration observing is not completly |
|
| 86 | 87 |
// reliable. If we want to carry out the node degree in the graph |
| 87 |
// as in the \ref InDegMap and we use the |
|
| 88 |
// as in the \ref InDegMap and we use the reverseArc(), then it cause |
|
| 88 | 89 |
// 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. |
|
| 90 |
// only erasing and adding but not the reversing, it will stores bad |
|
| 91 |
// degrees. Apart form that the subgraph adaptors cannot even signal |
|
| 92 |
// the alterations because just a setting in the filter map can modify |
|
| 93 |
// the graph and this cannot be watched in any way. |
|
| 93 | 94 |
// |
| 94 | 95 |
// \param _Container The container which is observed. |
| 95 | 96 |
// \param _Item The item type which is obserbved. |
| 96 | 97 |
|
| 97 | 98 |
template <typename _Container, typename _Item> |
| 98 | 99 |
class AlterationNotifier {
|
| ... | ... |
@@ -100,32 +101,31 @@ |
| 100 | 101 |
|
| 101 | 102 |
typedef True Notifier; |
| 102 | 103 |
|
| 103 | 104 |
typedef _Container Container; |
| 104 | 105 |
typedef _Item Item; |
| 105 | 106 |
|
| 106 |
// \brief Exception which can be called from \e clear() and |
|
| 107 |
// \e erase(). |
|
| 107 |
// \brief Exception which can be called from clear() and |
|
| 108 |
// erase(). |
|
| 108 | 109 |
// |
| 109 |
// From the |
|
| 110 |
// From the clear() and erase() function only this |
|
| 110 | 111 |
// exception is allowed to throw. The exception immediatly |
| 111 | 112 |
// detaches the current observer from the notifier. Because the |
| 112 |
// |
|
| 113 |
// clear() and erase() should not throw other exceptions |
|
| 113 | 114 |
// it can be used to invalidate the observer. |
| 114 | 115 |
struct ImmediateDetach {};
|
| 115 | 116 |
|
| 116 | 117 |
// \brief ObserverBase is the base class for the observers. |
| 117 | 118 |
// |
| 118 | 119 |
// ObserverBase is the abstract base class for the observers. |
| 119 | 120 |
// It will be notified about an item was inserted into or |
| 120 | 121 |
// erased from the graph. |
| 121 | 122 |
// |
| 122 | 123 |
// The observer interface contains some pure virtual functions |
| 123 | 124 |
// to override. The add() and erase() functions are |
| 124 |
// to notify the oberver when one item is added or |
|
| 125 |
// erased. |
|
| 125 |
// to notify the oberver when one item is added or erased. |
|
| 126 | 126 |
// |
| 127 | 127 |
// The build() and clear() members are to notify the observer |
| 128 | 128 |
// about the container is built from an empty container or |
| 129 | 129 |
// is cleared to an empty container. |
| 130 | 130 |
class ObserverBase {
|
| 131 | 131 |
protected: |
| ... | ... |
@@ -33,31 +33,30 @@ |
| 33 | 33 |
namespace lemon {
|
| 34 | 34 |
|
| 35 | 35 |
// \ingroup graphbits |
| 36 | 36 |
// |
| 37 | 37 |
// \brief Graph map based on the array storage. |
| 38 | 38 |
// |
| 39 |
// The ArrayMap template class is graph map structure what |
|
| 40 |
// automatically updates the map when a key is added to or erased from |
|
| 41 |
// the map. This map uses the allocators to implement |
|
| 42 |
// the container functionality. |
|
| 39 |
// The ArrayMap template class is graph map structure that automatically |
|
| 40 |
// updates the map when a key is added to or erased from the graph. |
|
| 41 |
// This map uses the allocators to implement the container functionality. |
|
| 43 | 42 |
// |
| 44 |
// The template parameters are the Graph the current Item type and |
|
| 43 |
// The template parameters are the Graph, the current Item type and |
|
| 45 | 44 |
// the Value type of the map. |
| 46 | 45 |
template <typename _Graph, typename _Item, typename _Value> |
| 47 | 46 |
class ArrayMap |
| 48 | 47 |
: public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
|
| 49 | 48 |
public: |
| 50 |
// The graph type |
|
| 49 |
// The graph type. |
|
| 51 | 50 |
typedef _Graph Graph; |
| 52 |
// The item type |
|
| 51 |
// The item type. |
|
| 53 | 52 |
typedef _Item Item; |
| 54 | 53 |
// The reference map tag. |
| 55 | 54 |
typedef True ReferenceMapTag; |
| 56 | 55 |
|
| 57 |
// The key type of the |
|
| 56 |
// The key type of the map. |
|
| 58 | 57 |
typedef _Item Key; |
| 59 | 58 |
// The value type of the map. |
| 60 | 59 |
typedef _Value Value; |
| 61 | 60 |
|
| 62 | 61 |
// The const reference type of the map. |
| 63 | 62 |
typedef const _Value& ConstReference; |
| ... | ... |
@@ -197,13 +196,13 @@ |
| 197 | 196 |
} |
| 198 | 197 |
|
| 199 | 198 |
protected: |
| 200 | 199 |
|
| 201 | 200 |
// \brief Adds a new key to the map. |
| 202 | 201 |
// |
| 203 |
// It adds a new key to the map. It called by the observer notifier |
|
| 202 |
// It adds a new key to the map. It is called by the observer notifier |
|
| 204 | 203 |
// and it overrides the add() member function of the observer base. |
| 205 | 204 |
virtual void add(const Key& key) {
|
| 206 | 205 |
Notifier* nf = Parent::notifier(); |
| 207 | 206 |
int id = nf->id(key); |
| 208 | 207 |
if (id >= capacity) {
|
| 209 | 208 |
int new_capacity = (capacity == 0 ? 1 : capacity); |
| ... | ... |
@@ -225,13 +224,13 @@ |
| 225 | 224 |
} |
| 226 | 225 |
allocator.construct(&(values[id]), Value()); |
| 227 | 226 |
} |
| 228 | 227 |
|
| 229 | 228 |
// \brief Adds more new keys to the map. |
| 230 | 229 |
// |
| 231 |
// It adds more new keys to the map. It called by the observer notifier |
|
| 230 |
// It adds more new keys to the map. It is called by the observer notifier |
|
| 232 | 231 |
// and it overrides the add() member function of the observer base. |
| 233 | 232 |
virtual void add(const std::vector<Key>& keys) {
|
| 234 | 233 |
Notifier* nf = Parent::notifier(); |
| 235 | 234 |
int max_id = -1; |
| 236 | 235 |
for (int i = 0; i < int(keys.size()); ++i) {
|
| 237 | 236 |
int id = nf->id(keys[i]); |
| ... | ... |
@@ -269,33 +268,33 @@ |
| 269 | 268 |
allocator.construct(&(values[id]), Value()); |
| 270 | 269 |
} |
| 271 | 270 |
} |
| 272 | 271 |
|
| 273 | 272 |
// \brief Erase a key from the map. |
| 274 | 273 |
// |
| 275 |
// Erase a key from the map. It called by the observer notifier |
|
| 274 |
// Erase a key from the map. It is called by the observer notifier |
|
| 276 | 275 |
// and it overrides the erase() member function of the observer base. |
| 277 | 276 |
virtual void erase(const Key& key) {
|
| 278 | 277 |
int id = Parent::notifier()->id(key); |
| 279 | 278 |
allocator.destroy(&(values[id])); |
| 280 | 279 |
} |
| 281 | 280 |
|
| 282 | 281 |
// \brief Erase more keys from the map. |
| 283 | 282 |
// |
| 284 |
// Erase more keys from the map. It called by the observer notifier |
|
| 283 |
// Erase more keys from the map. It is called by the observer notifier |
|
| 285 | 284 |
// and it overrides the erase() member function of the observer base. |
| 286 | 285 |
virtual void erase(const std::vector<Key>& keys) {
|
| 287 | 286 |
for (int i = 0; i < int(keys.size()); ++i) {
|
| 288 | 287 |
int id = Parent::notifier()->id(keys[i]); |
| 289 | 288 |
allocator.destroy(&(values[id])); |
| 290 | 289 |
} |
| 291 | 290 |
} |
| 292 | 291 |
|
| 293 |
// \brief |
|
| 292 |
// \brief Builds the map. |
|
| 294 | 293 |
// |
| 295 |
// It |
|
| 294 |
// It builds the map. It is called by the observer notifier |
|
| 296 | 295 |
// and it overrides the build() member function of the observer base. |
| 297 | 296 |
virtual void build() {
|
| 298 | 297 |
Notifier* nf = Parent::notifier(); |
| 299 | 298 |
allocate_memory(); |
| 300 | 299 |
Item it; |
| 301 | 300 |
for (nf->first(it); it != INVALID; nf->next(it)) {
|
| ... | ... |
@@ -303,13 +302,13 @@ |
| 303 | 302 |
allocator.construct(&(values[id]), Value()); |
| 304 | 303 |
} |
| 305 | 304 |
} |
| 306 | 305 |
|
| 307 | 306 |
// \brief Clear the map. |
| 308 | 307 |
// |
| 309 |
// It erase all items from the map. It called by the observer notifier |
|
| 308 |
// It erase all items from the map. It is called by the observer notifier |
|
| 310 | 309 |
// and it overrides the clear() member function of the observer base. |
| 311 | 310 |
virtual void clear() {
|
| 312 | 311 |
Notifier* nf = Parent::notifier(); |
| 313 | 312 |
if (capacity != 0) {
|
| 314 | 313 |
Item it; |
| 315 | 314 |
for (nf->first(it); it != INVALID; nf->next(it)) {
|
| ... | ... |
@@ -27,13 +27,13 @@ |
| 27 | 27 |
|
| 28 | 28 |
#include <lemon/concept_check.h> |
| 29 | 29 |
#include <lemon/concepts/maps.h> |
| 30 | 30 |
|
| 31 | 31 |
//\ingroup digraphbits |
| 32 | 32 |
//\file |
| 33 |
//\brief Extenders for the |
|
| 33 |
//\brief Extenders for the graph types |
|
| 34 | 34 |
namespace lemon {
|
| 35 | 35 |
|
| 36 | 36 |
// \ingroup digraphbits |
| 37 | 37 |
// |
| 38 | 38 |
// \brief BaseDigraph to BaseGraph extender |
| 39 | 39 |
template <typename Base> |
| ... | ... |
@@ -26,18 +26,18 @@ |
| 26 | 26 |
|
| 27 | 27 |
#include <lemon/concept_check.h> |
| 28 | 28 |
#include <lemon/concepts/maps.h> |
| 29 | 29 |
|
| 30 | 30 |
//\ingroup graphbits |
| 31 | 31 |
//\file |
| 32 |
//\brief Extenders for the |
|
| 32 |
//\brief Extenders for the graph types |
|
| 33 | 33 |
namespace lemon {
|
| 34 | 34 |
|
| 35 | 35 |
// \ingroup graphbits |
| 36 | 36 |
// |
| 37 |
// \brief Extender for the |
|
| 37 |
// \brief Extender for the digraph implementations |
|
| 38 | 38 |
template <typename Base> |
| 39 | 39 |
class DigraphExtender : public Base {
|
| 40 | 40 |
public: |
| 41 | 41 |
|
| 42 | 42 |
typedef Base Parent; |
| 43 | 43 |
typedef DigraphExtender Digraph; |
| ... | ... |
@@ -35,15 +35,15 @@ |
| 35 | 35 |
namespace lemon {
|
| 36 | 36 |
|
| 37 | 37 |
// \ingroup graphbits |
| 38 | 38 |
// |
| 39 | 39 |
// \brief Graph map based on the std::vector storage. |
| 40 | 40 |
// |
| 41 |
// The VectorMap template class is graph map structure what |
|
| 42 |
// automatically updates the map when a key is added to or erased from |
|
| 43 |
// |
|
| 41 |
// The VectorMap template class is graph map structure that automatically |
|
| 42 |
// updates the map when a key is added to or erased from the graph. |
|
| 43 |
// This map type uses std::vector to store the values. |
|
| 44 | 44 |
// |
| 45 | 45 |
// \tparam _Graph The graph this map is attached to. |
| 46 | 46 |
// \tparam _Item The item type of the graph items. |
| 47 | 47 |
// \tparam _Value The value type of the map. |
| 48 | 48 |
template <typename _Graph, typename _Item, typename _Value> |
| 49 | 49 |
class VectorMap |
| ... | ... |
@@ -166,24 +166,24 @@ |
| 166 | 166 |
} |
| 167 | 167 |
|
| 168 | 168 |
protected: |
| 169 | 169 |
|
| 170 | 170 |
// \brief Adds a new key to the map. |
| 171 | 171 |
// |
| 172 |
// It adds a new key to the map. It called by the observer notifier |
|
| 172 |
// It adds a new key to the map. It is called by the observer notifier |
|
| 173 | 173 |
// and it overrides the add() member function of the observer base. |
| 174 | 174 |
virtual void add(const Key& key) {
|
| 175 | 175 |
int id = Parent::notifier()->id(key); |
| 176 | 176 |
if (id >= int(container.size())) {
|
| 177 | 177 |
container.resize(id + 1); |
| 178 | 178 |
} |
| 179 | 179 |
} |
| 180 | 180 |
|
| 181 | 181 |
// \brief Adds more new keys to the map. |
| 182 | 182 |
// |
| 183 |
// It adds more new keys to the map. It called by the observer notifier |
|
| 183 |
// It adds more new keys to the map. It is called by the observer notifier |
|
| 184 | 184 |
// and it overrides the add() member function of the observer base. |
| 185 | 185 |
virtual void add(const std::vector<Key>& keys) {
|
| 186 | 186 |
int max = container.size() - 1; |
| 187 | 187 |
for (int i = 0; i < int(keys.size()); ++i) {
|
| 188 | 188 |
int id = Parent::notifier()->id(keys[i]); |
| 189 | 189 |
if (id >= max) {
|
| ... | ... |
@@ -192,41 +192,41 @@ |
| 192 | 192 |
} |
| 193 | 193 |
container.resize(max + 1); |
| 194 | 194 |
} |
| 195 | 195 |
|
| 196 | 196 |
// \brief Erase a key from the map. |
| 197 | 197 |
// |
| 198 |
// Erase a key from the map. It called by the observer notifier |
|
| 198 |
// Erase a key from the map. It is called by the observer notifier |
|
| 199 | 199 |
// and it overrides the erase() member function of the observer base. |
| 200 | 200 |
virtual void erase(const Key& key) {
|
| 201 | 201 |
container[Parent::notifier()->id(key)] = Value(); |
| 202 | 202 |
} |
| 203 | 203 |
|
| 204 | 204 |
// \brief Erase more keys from the map. |
| 205 | 205 |
// |
| 206 |
// |
|
| 206 |
// It erases more keys from the map. It is called by the observer notifier |
|
| 207 | 207 |
// and it overrides the erase() member function of the observer base. |
| 208 | 208 |
virtual void erase(const std::vector<Key>& keys) {
|
| 209 | 209 |
for (int i = 0; i < int(keys.size()); ++i) {
|
| 210 | 210 |
container[Parent::notifier()->id(keys[i])] = Value(); |
| 211 | 211 |
} |
| 212 | 212 |
} |
| 213 | 213 |
|
| 214 |
// \brief |
|
| 214 |
// \brief Build the map. |
|
| 215 | 215 |
// |
| 216 |
// It |
|
| 216 |
// It builds the map. It is called by the observer notifier |
|
| 217 | 217 |
// and it overrides the build() member function of the observer base. |
| 218 | 218 |
virtual void build() {
|
| 219 | 219 |
int size = Parent::notifier()->maxId() + 1; |
| 220 | 220 |
container.reserve(size); |
| 221 | 221 |
container.resize(size); |
| 222 | 222 |
} |
| 223 | 223 |
|
| 224 | 224 |
// \brief Clear the map. |
| 225 | 225 |
// |
| 226 |
// It |
|
| 226 |
// It erases all items from the map. It is called by the observer notifier |
|
| 227 | 227 |
// and it overrides the clear() member function of the observer base. |
| 228 | 228 |
virtual void clear() {
|
| 229 | 229 |
container.clear(); |
| 230 | 230 |
} |
| 231 | 231 |
|
| 232 | 232 |
private: |
0 comments (0 inline)