deba@378: #ifndef MAP_BASE_H
deba@378: #define MAP_BASE_H
deba@378: 
deba@595: using namespace std;
deba@595: 
deba@378: /**
deba@595: 	Template base class for implementing mapping on nodes and edges.
deba@595: 	\param The first template parameter is the Graph class.
deba@595: 	\param The second template parameter is the key type.
deba@595: 	\param The third template parameter is an iterator on
deba@595: 		the keys.
deba@378: */
deba@378: 
deba@378: 
deba@378: namespace hugo {
deba@378: 	template <typename G, typename K, typename KIt>
deba@378: 	class MapBase;
deba@378: }
deba@378: 
deba@378: #include "map_registry.h"
deba@378: 
deba@378: namespace hugo {
deba@378: 
deba@378: 	template <typename G, typename K, typename KIt>
deba@378: 	class MapBase {
deba@378: 	public:
deba@378: 		typedef G Graph;
deba@378: 		typedef MapRegistry<G, K, KIt> Registry;
deba@595: 		typedef K Key;
deba@378: 		typedef KIt KeyIt;
deba@378: 	
deba@378: 		friend class Registry;
deba@378: 		
deba@378: 		/** 
deba@378: 			Default constructor.
deba@378: 		*/	
deba@378: 		
deba@595: 		MapBase() : graph(0), registry(0) {}
deba@378: 
deba@378: 		/** 
deba@378: 			Simple constructor to register into a graph registry.
deba@378: 		*/
deba@378: 	
deba@571: 		MapBase(Graph& g, Registry& r) : graph(&g), registry(0) {
deba@595: 			r.attach(*this);
deba@378: 		}
deba@378: 
deba@378: 		/** 
deba@378: 			Copy constructor with registering into the map.
deba@378: 		*/	
deba@378: 	
deba@571: 		MapBase(const MapBase& copy) : registry(0), graph(copy.graph) {
deba@571: 			if (copy.registry) {
deba@571: 				copy.registry->attach(*this);
deba@378: 			}
deba@378: 		} 
deba@378: 	
deba@378: 		/** 
deba@378: 			Assign operator.
deba@378: 		*/	
deba@378: 
deba@378: 		const MapBase& operator=(const MapBase& copy) {
deba@378: 			if (registry) {
deba@571: 				registry->detach(*this);
deba@378: 			}
deba@571: 			graph = copy.graph;
deba@571: 			if (copy.registry) {
deba@571: 				copy.registry->attach(*this);
deba@378: 			}
deba@378: 		}
deba@378: 	
deba@378: 
deba@378: 		/** 
deba@378: 			Destructor.
deba@378: 		*/		
deba@378: 
deba@378: 		virtual ~MapBase() {
deba@378: 			if (registry) {
deba@571: 				registry->detach(*this);
deba@378: 			}
deba@378: 		}
deba@378: 	
deba@378: 	protected:
deba@378: 		
deba@595: 		Graph* graph;
deba@378: 		Registry* registry;
deba@378: 
deba@378: 		int registry_index;
deba@378: 	
deba@378: 		/**
deba@595: 			Helper function to implement constructors in the subclasses.
deba@378: 		*/
deba@378: 	
deba@571: 		virtual void init() {
deba@571: 			for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@378: 				add(it);
deba@378: 			}
deba@378: 		}
deba@378: 	
deba@378: 		/**
deba@378: 			Helper function to implement the destructor in the subclasses.
deba@378: 		*/
deba@378: 	
deba@571: 		virtual void destroy() {
deba@571: 			for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@378: 				erase(it);
deba@378: 			}
deba@378: 		}
deba@378: 	
deba@378: 		/** 
deba@378: 			The add member function should be overloaded in the subclasses.
deba@378: 			\e Add extends the map with the new node.
deba@378: 		*/
deba@378: 	
deba@595: 		virtual void add(const Key&) = 0;	
deba@378: 		/** 
deba@378: 			The erase member function should be overloaded in the subclasses.
deba@378: 			\e Erase removes the node from the map.
deba@378: 		*/
deba@378: 	
deba@595: 		virtual void erase(const Key&) = 0;
deba@378: 	
deba@378: 		/**
deba@378: 			Exception class to throw at unsupported operation.
deba@378: 		*/
deba@378: 	
deba@378: 		class NotSupportedOperationException {};
deba@378: 
deba@378: 	};
deba@378: 	
deba@378: }
deba@378: 
deba@378: #endif