deba@378: #ifndef MAP_BASE_H
deba@378: #define MAP_BASE_H
deba@378: 
deba@378: /**
deba@378: 	Template base class for implementing mapping on nodes.
deba@378: 	\param The first template parameter is the Graph class. The Graph
deba@378: 		must have an \emp node_maps member with \emp MapRegistry class.
deba@378: 	\param The second template parameter is the  type of the class.
deba@378: 	
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@378: 		typedef K KeyType;
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@378: 		MapBase() : registry(0) {}
deba@378: 
deba@378: 		/** 
deba@378: 			Simple constructor to register into a graph registry.
deba@378: 		*/
deba@378: 	
deba@378: 		MapBase(Registry& r) : registry(0) {
deba@378: 			registry->add(*this);
deba@378: 		}
deba@378: 
deba@378: 		/** 
deba@378: 			Copy constructor with registering into the map.
deba@378: 		*/	
deba@378: 	
deba@378: 		MapBase(const MapBase& copy) : registry(0) {
deba@378: 			if (registry) {
deba@378: 				registry->add(*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@378: 				registry->erase(*this);
deba@378: 			}
deba@378: 			registry = copy.registry;
deba@378: 			if (registry) {
deba@378: 				registry->add(*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@378: 				registry->erase(*this);
deba@378: 			}
deba@378: 		}
deba@378: 	
deba@378: 	protected:
deba@378: 		
deba@378: 		Registry* registry;
deba@378: 
deba@378: 		int registry_index;
deba@378: 	
deba@378: 		/**
deba@378: 			Helper function to implement the default constructor in the subclasses.
deba@378: 		*/
deba@378: 	
deba@378: 		virtual void init(Graph& g) {
deba@378: 
deba@378: 			for (KeyIt it(g); g.valid(it); g.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@378: 		virtual void destroy(Graph& g) {
deba@378: 			for (KeyIt it(g); g.valid(it); g.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@378: 		virtual void add(const KeyType&) = 0;
deba@378: 	
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@378: 		virtual void erase(const KeyType&) = 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