src/work/deba/map_registry.h
changeset 675 38755a4d4b51
parent 595 e10b5e9419ef
child 676 7ec5e7e6c7b4
equal deleted inserted replaced
2:fa75bc25b7fe 3:65b68a0d195c
     3 
     3 
     4 #include <vector>
     4 #include <vector>
     5 
     5 
     6 using namespace std;
     6 using namespace std;
     7 
     7 
       
     8 /** 
       
     9     Registry class to register edge or node maps in the graph. The
       
    10     registry helps you to implement an observer pattern. If you add
       
    11     or erase an edge or node you must notify all the maps about the
       
    12     event.
       
    13 */
     8 
    14 
     9 namespace hugo {
    15 namespace hugo {
    10 	template <typename G, typename K, typename KIt>
    16 
    11 	class MapRegistry;
    17   template <typename G, typename K, typename KIt>
       
    18   class MapRegistry {
       
    19   public:
       
    20     typedef G Graph;
       
    21     typedef K Key;
       
    22     typedef KIt KeyIt;
       
    23 	
       
    24 
       
    25 
       
    26     class MapBase {
       
    27     public:
       
    28       typedef G Graph;
       
    29       typedef MapRegistry<G, K, KIt> Registry;
       
    30       typedef K Key;
       
    31       typedef KIt KeyIt;
       
    32 	
       
    33       friend class Registry;
       
    34 		
       
    35       /** 
       
    36 	  Default constructor.
       
    37       */	
       
    38 		
       
    39       MapBase() : graph(0), registry(0) {}
       
    40 
       
    41       /** 
       
    42 	  Simple constructor to register into a graph registry.
       
    43       */
       
    44 	
       
    45       MapBase(Graph& g, Registry& r) : graph(&g), registry(0) {
       
    46 	r.attach(*this);
       
    47       }
       
    48 
       
    49       /** 
       
    50 	  Copy constructor with registering into the map.
       
    51       */	
       
    52 	
       
    53       MapBase(const MapBase& copy) : registry(0), graph(copy.graph) {
       
    54 	if (copy.registry) {
       
    55 	  copy.registry->attach(*this);
       
    56 	}
       
    57       } 
       
    58 	
       
    59       /** 
       
    60 	  Assign operator.
       
    61       */	
       
    62 
       
    63       const MapBase& operator=(const MapBase& copy) {
       
    64 	if (registry) {
       
    65 	  registry->detach(*this);
       
    66 	}
       
    67 	graph = copy.graph;
       
    68 	if (copy.registry) {
       
    69 	  copy.registry->attach(*this);
       
    70 	}
       
    71       }
       
    72 	
       
    73 
       
    74       /** 
       
    75 	  Destructor.
       
    76       */		
       
    77 
       
    78       virtual ~MapBase() {
       
    79 	if (registry) {
       
    80 	  registry->detach(*this);
       
    81 	}
       
    82       }
       
    83 	
       
    84     protected:
       
    85 		
       
    86       Graph* graph;
       
    87       Registry* registry;
       
    88 
       
    89       int registry_index;
       
    90 	
       
    91       /**
       
    92 	 Helper function to implement constructors in the subclasses.
       
    93       */
       
    94 	
       
    95       virtual void init() {
       
    96 	for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
       
    97 	  add(it);
       
    98 	}
       
    99       }
       
   100 	
       
   101       /**
       
   102 	 Helper function to implement the destructor in the subclasses.
       
   103       */
       
   104 	
       
   105       virtual void destroy() {
       
   106 	for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
       
   107 	  erase(it);
       
   108 	}
       
   109       }
       
   110 	
       
   111       /** 
       
   112 	  The add member function should be overloaded in the subclasses.
       
   113 	  \e Add extends the map with the new node.
       
   114       */
       
   115 	
       
   116       virtual void add(const Key&) = 0;	
       
   117       /** 
       
   118 	  The erase member function should be overloaded in the subclasses.
       
   119 	  \e Erase removes the node from the map.
       
   120       */
       
   121 	
       
   122       virtual void erase(const Key&) = 0;
       
   123 	
       
   124       /**
       
   125 	 Exception class to throw at unsupported operation.
       
   126       */
       
   127 	
       
   128       class NotSupportedOperationException {};
       
   129 
       
   130     };
       
   131 	
       
   132   protected:
       
   133 	
       
   134     typedef std::vector<MapBase*> Container; 
       
   135     Container container;
       
   136 
       
   137 		
       
   138     public:
       
   139 	
       
   140     MapRegistry() {}
       
   141 	
       
   142     MapRegistry(const MapRegistry&) {}
       
   143 		
       
   144     MapRegistry& operator=(const MapRegistry&) {
       
   145       for (it = container.begin(); it != container.end(); ++it) {
       
   146 	(*it)->destroy();
       
   147 	(*it)->graph = 0;
       
   148 	(*it)->registry = 0;
       
   149       }
       
   150     }
       
   151 				
       
   152     ~MapRegistry() {
       
   153       typename Container::iterator it;
       
   154       for (it = container.begin(); it != container.end(); ++it) {
       
   155 	(*it)->destroy();
       
   156 	(*it)->registry = 0;
       
   157 	(*it)->graph = 0;
       
   158       }
       
   159     }
       
   160 	
       
   161 	
       
   162     public:
       
   163 	
       
   164     void attach(MapBase& map) {
       
   165       if (map.registry) {
       
   166 	map.registry->detach(map);
       
   167       }
       
   168       container.push_back(&map);
       
   169       map.registry = this;
       
   170       map.registry_index = container.size()-1;
       
   171     } 
       
   172 	
       
   173     void detach(MapBase& map) {
       
   174       container.back()->registry_index = map.registry_index; 
       
   175       container[map.registry_index] = container.back();
       
   176       container.pop_back();
       
   177       map.registry = 0;
       
   178       map.graph = 0;
       
   179     }
       
   180 	
       
   181 		
       
   182     virtual void add(Key& key) {
       
   183       typename Container::iterator it;
       
   184       for (it = container.begin(); it != container.end(); ++it) {
       
   185 	(*it)->add(key);
       
   186       }
       
   187     }	
       
   188 		
       
   189     virtual void erase(Key& key) {
       
   190       typename Container::iterator it;
       
   191       for (it = container.begin(); it != container.end(); ++it) {
       
   192 	(*it)->erase(key);
       
   193       }
       
   194     }
       
   195 
       
   196   };
       
   197 
    12 }
   198 }
    13 
   199 
    14 #include "map_base.h"
       
    15 
       
    16 namespace hugo {
       
    17 
       
    18 	template <typename G, typename K, typename KIt>
       
    19 	class MapRegistry {
       
    20 	public:
       
    21 		typedef G Graph;
       
    22 		typedef K Key;
       
    23 		typedef KIt KeyIt;
       
    24 	
       
    25 		typedef MapBase<Graph, Key, KIt> Map;
       
    26 		friend class Base;
       
    27 	
       
    28 	protected:
       
    29 	
       
    30 		typedef std::vector<Map*> Container; 
       
    31 	  Container container;
       
    32 
       
    33 		
       
    34 	public:
       
    35 	
       
    36 		MapRegistry() {}
       
    37 	
       
    38 		MapRegistry(const MapRegistry&) {}
       
    39 		
       
    40 		MapRegistry& operator=(const MapRegistry&) {
       
    41 			for (it = container.begin(); it != container.end(); ++it) {
       
    42 				(*it)->destroy();
       
    43 				(*it)->graph = 0;
       
    44 				(*it)->registry = 0;
       
    45 			}
       
    46 		}
       
    47 				
       
    48 		~MapRegistry() {
       
    49 			typename Container::iterator it;
       
    50 			for (it = container.begin(); it != container.end(); ++it) {
       
    51 				(*it)->destroy();
       
    52 				(*it)->registry = 0;
       
    53 				(*it)->graph = 0;
       
    54 			}
       
    55 		}
       
    56 	
       
    57 	
       
    58 	public:
       
    59 	
       
    60 		void attach(Map& map) {
       
    61 			if (map.registry) {
       
    62 				map.registry->detach(map);
       
    63 			}
       
    64 			container.push_back(&map);
       
    65 			map.registry = this;
       
    66 			map.registry_index = container.size()-1;
       
    67 		} 
       
    68 	
       
    69 		void detach(Map& map) {
       
    70 			container.back()->registry_index = map.registry_index; 
       
    71 			container[map.registry_index] = container.back();
       
    72 			container.pop_back();
       
    73 			map.registry = 0;
       
    74 			map.graph = 0;
       
    75 		}
       
    76 	
       
    77 		
       
    78 		virtual void add(Key& key) {
       
    79 			typename Container::iterator it;
       
    80 			for (it = container.begin(); it != container.end(); ++it) {
       
    81 				(*it)->add(key);
       
    82 			}
       
    83 		}	
       
    84 		
       
    85 		virtual void erase(Key& key) {
       
    86 			typename Container::iterator it;
       
    87 			for (it = container.begin(); it != container.end(); ++it) {
       
    88 				(*it)->erase(key);
       
    89 			}
       
    90 		}
       
    91 
       
    92 	};
       
    93 
       
    94 }
       
    95 
       
    96 #endif
   200 #endif