lemon/bits/static_map.h
author hegyi
Thu, 05 Jan 2006 12:30:09 +0000
changeset 1878 409a31271efd
parent 1828 fd3771591a5c
child 1909 2d806130e700
permissions -rw-r--r--
Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
     1 /* -*- C++ -*-
     2  * lemon/static_map.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_STATIC_MAP_H
    18 #define LEMON_STATIC_MAP_H
    19 
    20 #include <algorithm>
    21 #include <iostream>
    22 
    23 #include <lemon/utility.h>
    24 #include <lemon/bits/map_extender.h>
    25 #include <lemon/bits/alteration_notifier.h>
    26 #include <lemon/error.h>
    27 #include <lemon/concept_check.h>
    28 #include <lemon/concept/maps.h>
    29 
    30 /// \ingroup graphmaps
    31 ///
    32 ///\file
    33 ///\brief Static sized graph maps.
    34 
    35 namespace lemon {
    36 
    37   /// \ingroup graphmaps
    38   ///
    39   /// \brief Graph map with static sized storage.
    40   ///
    41   /// The StaticMap template class is graph map structure what
    42   /// does not update automatically the map when a key is added to or 
    43   /// erased from the map rather it throws an exception. This map factory 
    44   /// uses the allocators to implement the container functionality.
    45   ///
    46   /// \param Registry The AlterationNotifier that will notify this map.
    47   /// \param Item The item type of the graph items.
    48   /// \param Value The value type of the map.
    49   /// 
    50   /// \author Balazs Dezso
    51   	
    52 
    53   template <typename _Graph, typename _Item, typename _Value>
    54   class StaticMap : public AlterationNotifier<_Item>::ObserverBase {
    55   public:
    56 
    57     /// \brief Exception class for unsupported exceptions.
    58     class UnsupportedOperation : public lemon::LogicError {
    59     public:
    60       virtual const char* exceptionName() const {
    61 	return "lemon::StaticMap::UnsupportedOperation";
    62       }
    63     };
    64 
    65   private:
    66 		
    67     typedef std::vector<_Value> Container;	
    68 
    69   public:
    70 
    71     /// The graph type of the map. 
    72     typedef _Graph Graph;
    73     /// The reference map tag.
    74     typedef True ReferenceMapTag;
    75 
    76     /// The key type of the map.
    77     typedef _Item Key;
    78     /// The value type of the map.
    79     typedef _Value Value;
    80     /// The const reference type of the map.
    81     typedef typename Container::const_reference ConstReference;
    82     /// The reference type of the map.
    83     typedef typename Container::reference Reference;
    84 
    85     typedef const Value ConstValue;
    86     typedef Value* Pointer;
    87     typedef const Value* ConstPointer;
    88 
    89     typedef AlterationNotifier<_Item> Registry;
    90 
    91     /// The map type.
    92     typedef StaticMap Map;
    93     /// The base class of the map.
    94     typedef typename Registry::ObserverBase Parent;
    95 
    96     /// \brief Constructor to attach the new map into the registry.
    97     ///
    98     /// It constructs a map and attachs it into the registry.
    99     /// It adds all the items of the graph to the map.
   100     StaticMap(const Graph& _g) : graph(&_g) {
   101       attach(_g.getNotifier(_Item()));
   102       build();
   103     }
   104 
   105     /// \brief Constructor uses given value to initialize the map. 
   106     ///
   107     /// It constructs a map uses a given value to initialize the map. 
   108     /// It adds all the items of the graph to the map.     
   109     StaticMap(const Graph& _g, const Value& _v) : graph(&_g) { 
   110       attach(_g.getNotifier(_Item()));
   111       unsigned size = graph->maxId(_Item()) + 1;
   112       container.reserve(size);
   113       container.resize(size, _v);
   114     }
   115 
   116     /// \brief Copy constructor
   117     ///
   118     /// Copy constructor.
   119     StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) {
   120       if (_copy.attached()) {
   121 	attach(*_copy.getRegistry());
   122 	container = _copy.container;
   123       }
   124     }
   125 
   126     /// \brief Destrcutor
   127     ///
   128     /// Destructor.
   129     virtual ~StaticMap() {
   130       clear();
   131       if (attached()) {
   132 	detach();
   133       }
   134     }
   135 
   136 
   137   private:
   138 
   139     StaticMap& operator=(const StaticMap&);
   140 
   141   protected:
   142 
   143     using Parent::attach;
   144     using Parent::detach;
   145     using Parent::attached;
   146 
   147     const Graph* getGraph() const {
   148       return graph;
   149     }
   150 
   151   public:
   152 
   153     /// \brief The subcript operator.
   154     ///
   155     /// The subscript operator. The map can be subscripted by the
   156     /// actual items of the graph. 
   157      
   158     Reference operator[](const Key& key) {
   159       return container[graph->id(key)];
   160     } 
   161 		
   162     /// \brief The const subcript operator.
   163     ///
   164     /// The const subscript operator. The map can be subscripted by the
   165     /// actual items of the graph. 
   166      
   167     ConstReference operator[](const Key& key) const {
   168       return container[graph->id(key)];
   169     }
   170 
   171 
   172     /// \brief The setter function of the map.
   173     ///
   174     /// It the same as operator[](key) = value expression.
   175     ///
   176     void set(const Key& key, const Value& value) {
   177       (*this)[key] = value;
   178     }
   179 
   180   protected:
   181 
   182     /// \brief Adds a new key to the map.
   183     ///		
   184     /// It adds a new key to the map. It called by the observer registry
   185     /// and it overrides the add() member function of the observer base.
   186      
   187     void add(const Key&) {
   188       throw UnsupportedOperation();
   189     }
   190 
   191     /// \brief Erases a key from the map.
   192     ///
   193     /// Erase a key from the map. It called by the observer registry
   194     /// and it overrides the erase() member function of the observer base.     
   195     void erase(const Key&) {
   196       throw UnsupportedOperation();
   197     }
   198 
   199     /// Buildes the map.
   200 		
   201     /// It buildes the map. It called by the observer registry
   202     /// and it overrides the build() member function of the observer base.
   203 
   204     void build() { 
   205       int size = graph->maxId(_Item()) + 1;
   206       container.reserve(size);
   207       container.resize(size);
   208     }
   209 
   210     /// Clear the map.
   211 
   212     /// It erase all items from the map. It called by the observer registry
   213     /// and it overrides the clear() member function of the observer base.     
   214     void clear() { 
   215       container.clear();
   216     }
   217     
   218   private:
   219 		
   220     Container container;
   221     const Graph *graph;
   222 
   223   };
   224 
   225   /// \e
   226   template <typename _Base> 
   227   class StaticMappableGraphExtender : public _Base {
   228   public:
   229 
   230     typedef StaticMappableGraphExtender<_Base> Graph;
   231     typedef _Base Parent;
   232 
   233     typedef typename Parent::Node Node;
   234     typedef typename Parent::NodeIt NodeIt;
   235 
   236     typedef typename Parent::Edge Edge;
   237     typedef typename Parent::EdgeIt EdgeIt;
   238 
   239     
   240     template <typename _Value>
   241     class NodeMap 
   242       : public IterableMapExtender<StaticMap<Graph, Node, _Value> > {
   243     public:
   244       typedef StaticMappableGraphExtender Graph;
   245       typedef IterableMapExtender<StaticMap<Graph, Node, _Value> > Parent;
   246 
   247       NodeMap(const Graph& _g) 
   248 	: Parent(_g) {}
   249       NodeMap(const Graph& _g, const _Value& _v) 
   250 	: Parent(_g, _v) {}
   251 
   252       NodeMap& operator=(const NodeMap& cmap) {
   253 	return operator=<NodeMap>(cmap);
   254       }
   255 
   256 
   257       /// \brief Template assign operator.
   258       ///
   259       /// The given parameter should be conform to the ReadMap
   260       /// concecpt and could be indiced by the current item set of
   261       /// the NodeMap. In this case the value for each item
   262       /// is assigned by the value of the given ReadMap. 
   263       template <typename CMap>
   264       NodeMap& operator=(const CMap& cmap) {
   265 	checkConcept<concept::ReadMap<Node, _Value>, CMap>();
   266 	const typename Parent::Graph* graph = Parent::getGraph();
   267 	Node it;
   268 	for (graph->first(it); it != INVALID; graph->next(it)) {
   269 	  Parent::set(it, cmap[it]);
   270 	}
   271 	return *this;
   272       }
   273 
   274     };
   275 
   276     template <typename _Value>
   277     class EdgeMap 
   278       : public IterableMapExtender<StaticMap<Graph, Edge, _Value> > {
   279     public:
   280       typedef StaticMappableGraphExtender Graph;
   281       typedef IterableMapExtender<StaticMap<Graph, Edge, _Value> > Parent;
   282 
   283       EdgeMap(const Graph& _g) 
   284 	: Parent(_g) {}
   285       EdgeMap(const Graph& _g, const _Value& _v) 
   286 	: Parent(_g, _v) {}
   287 
   288       EdgeMap& operator=(const EdgeMap& cmap) {
   289 	return operator=<EdgeMap>(cmap);
   290       }
   291 
   292       template <typename CMap>
   293       EdgeMap& operator=(const CMap& cmap) {
   294 	checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
   295 	const typename Parent::Graph* graph = Parent::getGraph();
   296 	Edge it;
   297 	for (graph->first(it); it != INVALID; graph->next(it)) {
   298 	  Parent::set(it, cmap[it]);
   299 	}
   300 	return *this;
   301       }
   302     };
   303     
   304   };
   305 
   306   /// \e
   307   template <typename _Base> 
   308   class StaticMappableUndirGraphExtender : 
   309     public StaticMappableGraphExtender<_Base> {
   310   public:
   311 
   312     typedef StaticMappableUndirGraphExtender Graph;
   313     typedef StaticMappableGraphExtender<_Base> Parent;
   314 
   315     typedef typename Parent::UndirEdge UndirEdge;
   316 
   317     template <typename _Value>
   318     class UndirEdgeMap 
   319       : public IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > {
   320     public:
   321       typedef StaticMappableUndirGraphExtender Graph;
   322       typedef IterableMapExtender<
   323 	StaticMap<Graph, UndirEdge, _Value> > Parent;
   324 
   325       UndirEdgeMap(const Graph& _g) 
   326 	: Parent(_g) {}
   327       UndirEdgeMap(const Graph& _g, const _Value& _v) 
   328 	: Parent(_g, _v) {}
   329 
   330       UndirEdgeMap& operator=(const UndirEdgeMap& cmap) {
   331 	return operator=<UndirEdgeMap>(cmap);
   332       }
   333 
   334       template <typename CMap>
   335       UndirEdgeMap& operator=(const CMap& cmap) {
   336 	checkConcept<concept::ReadMap<UndirEdge, _Value>, CMap>();
   337 	const typename Parent::Graph* graph = Parent::getGraph();
   338 	UndirEdge it;
   339 	for (graph->first(it); it != INVALID; graph->next(it)) {
   340 	  Parent::set(it, cmap[it]);
   341 	}
   342 	return *this;
   343       }
   344     };
   345 
   346   };
   347 
   348   template <typename _Base>
   349   class StaticMappableUndirBipartiteGraphExtender : public _Base {
   350   public:
   351 
   352     typedef _Base Parent;
   353     typedef StaticMappableUndirBipartiteGraphExtender Graph;
   354 
   355     typedef typename Parent::Node Node;
   356     typedef typename Parent::UpperNode UpperNode;
   357     typedef typename Parent::LowerNode LowerNode;
   358     typedef typename Parent::Edge Edge;
   359     typedef typename Parent::UndirEdge UndirEdge;
   360     
   361     template <typename _Value>
   362     class UpperNodeMap 
   363       : public IterableMapExtender<StaticMap<Graph, UpperNode, _Value> > {
   364     public:
   365       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   366       typedef IterableMapExtender<StaticMap<Graph, UpperNode, _Value> > 
   367       Parent;
   368     
   369       UpperNodeMap(const Graph& _g) 
   370 	: Parent(_g) {}
   371       UpperNodeMap(const Graph& _g, const _Value& _v) 
   372 	: Parent(_g, _v) {}
   373     
   374       UpperNodeMap& operator=(const UpperNodeMap& cmap) {
   375 	return operator=<UpperNodeMap>(cmap);
   376       }
   377     
   378 
   379       /// \brief Template assign operator.
   380       ///
   381       /// The given parameter should be conform to the ReadMap
   382       /// concept and could be indiced by the current item set of
   383       /// the UpperNodeMap. In this case the value for each item
   384       /// is assigned by the value of the given ReadMap. 
   385       template <typename CMap>
   386       UpperNodeMap& operator=(const CMap& cmap) {
   387 	checkConcept<concept::ReadMap<UpperNode, _Value>, CMap>();
   388 	const typename Parent::Graph* graph = Parent::getGraph();
   389 	UpperNode it;
   390 	for (graph->first(it); it != INVALID; graph->next(it)) {
   391 	  Parent::set(it, cmap[it]);
   392 	}
   393 	return *this;
   394       }
   395     
   396     };
   397 
   398     template <typename _Value>
   399     class LowerNodeMap 
   400       : public IterableMapExtender<StaticMap<Graph, LowerNode, _Value> > {
   401     public:
   402       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   403       typedef IterableMapExtender<StaticMap<Graph, LowerNode, _Value> > 
   404       Parent;
   405     
   406       LowerNodeMap(const Graph& _g) 
   407 	: Parent(_g) {}
   408       LowerNodeMap(const Graph& _g, const _Value& _v) 
   409 	: Parent(_g, _v) {}
   410     
   411       LowerNodeMap& operator=(const LowerNodeMap& cmap) {
   412 	return operator=<LowerNodeMap>(cmap);
   413       }
   414     
   415 
   416       /// \brief Template assign operator.
   417       ///
   418       /// The given parameter should be conform to the ReadMap
   419       /// concept and could be indiced by the current item set of
   420       /// the LowerNodeMap. In this case the value for each item
   421       /// is assigned by the value of the given ReadMap. 
   422       template <typename CMap>
   423       LowerNodeMap& operator=(const CMap& cmap) {
   424 	checkConcept<concept::ReadMap<LowerNode, _Value>, CMap>();
   425 	const typename Parent::Graph* graph = Parent::getGraph();
   426 	LowerNode it;
   427 	for (graph->first(it); it != INVALID; graph->next(it)) {
   428 	  Parent::set(it, cmap[it]);
   429 	}
   430 	return *this;
   431       }
   432     
   433     };
   434 
   435   protected:
   436 
   437     template <typename _Value>
   438     class NodeMapBase : public Parent::NodeNotifier::ObserverBase {
   439     public:
   440       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   441 
   442       typedef Node Key;
   443       typedef _Value Value;
   444 
   445       /// The reference type of the map;
   446       typedef typename LowerNodeMap<_Value>::Reference Reference;
   447       /// The pointer type of the map;
   448       typedef typename LowerNodeMap<_Value>::Pointer Pointer;
   449       
   450       /// The const value type of the map.
   451       typedef const Value ConstValue;
   452       /// The const reference type of the map;
   453       typedef typename LowerNodeMap<_Value>::ConstReference ConstReference;
   454       /// The pointer type of the map;
   455       typedef typename LowerNodeMap<_Value>::ConstPointer ConstPointer;
   456 
   457       typedef True ReferenceMapTag;
   458 
   459       NodeMapBase(const Graph& _g) 
   460 	: graph(&_g), lowerMap(_g), upperMap(_g) {
   461 	Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
   462       }
   463       NodeMapBase(const Graph& _g, const _Value& _v) 
   464 	: graph(&_g), lowerMap(_g, _v), 
   465 	  upperMap(_g, _v) {
   466 	Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
   467       }
   468 
   469       virtual ~NodeMapBase() {      
   470 	if (Parent::NodeNotifier::ObserverBase::attached()) {
   471 	  Parent::NodeNotifier::ObserverBase::detach();
   472 	}
   473       }
   474     
   475       ConstReference operator[](const Key& node) const {
   476 	if (Parent::upper(node)) {
   477 	  return upperMap[node];
   478 	} else {
   479 	  return lowerMap[node];
   480 	}
   481       } 
   482 
   483       Reference operator[](const Key& node) {
   484 	if (Parent::upper(node)) {
   485 	  return upperMap[node];
   486 	} else {
   487 	  return lowerMap[node];
   488 	}
   489       }
   490 
   491       void set(const Key& node, const Value& value) {
   492 	if (Parent::upper(node)) {
   493 	  upperMap.set(node, value);
   494 	} else {
   495 	  lowerMap.set(node, value);
   496 	}
   497       }
   498 
   499     protected:
   500       
   501       virtual void add(const Node&) {}
   502       virtual void erase(const Node&) {}
   503       virtual void clear() {}
   504       virtual void build() {}
   505 
   506       const Graph* getGraph() const { return graph; }
   507       
   508     private:
   509       const Graph* graph;
   510       LowerNodeMap<_Value> lowerMap;
   511       UpperNodeMap<_Value> upperMap;
   512     };
   513     
   514   public:
   515 
   516     template <typename _Value>
   517     class NodeMap 
   518       : public IterableMapExtender<NodeMapBase<_Value> > {
   519     public:
   520       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   521       typedef IterableMapExtender< NodeMapBase<_Value> > Parent;
   522     
   523       NodeMap(const Graph& _g) 
   524 	: Parent(_g) {}
   525       NodeMap(const Graph& _g, const _Value& _v) 
   526 	: Parent(_g, _v) {}
   527     
   528       NodeMap& operator=(const NodeMap& cmap) {
   529 	return operator=<NodeMap>(cmap);
   530       }
   531     
   532 
   533       /// \brief Template assign operator.
   534       ///
   535       /// The given parameter should be conform to the ReadMap
   536       /// concept and could be indiced by the current item set of
   537       /// the NodeMap. In this case the value for each item
   538       /// is assigned by the value of the given ReadMap. 
   539       template <typename CMap>
   540       NodeMap& operator=(const CMap& cmap) {
   541 	checkConcept<concept::ReadMap<Node, _Value>, CMap>();
   542 	const typename Parent::Graph* graph = Parent::getGraph();
   543 	Node it;
   544 	for (graph->first(it); it != INVALID; graph->next(it)) {
   545 	  Parent::set(it, cmap[it]);
   546 	}
   547 	return *this;
   548       }
   549     
   550     };
   551 
   552 
   553 
   554     template <typename _Value>
   555     class EdgeMap 
   556       : public IterableMapExtender<StaticMap<Graph, Edge, _Value> > {
   557     public:
   558       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   559       typedef IterableMapExtender<StaticMap<Graph, Edge, _Value> > Parent;
   560     
   561       EdgeMap(const Graph& _g) 
   562 	: Parent(_g) {}
   563       EdgeMap(const Graph& _g, const _Value& _v) 
   564 	: Parent(_g, _v) {}
   565     
   566       EdgeMap& operator=(const EdgeMap& cmap) {
   567 	return operator=<EdgeMap>(cmap);
   568       }
   569     
   570       template <typename CMap>
   571       EdgeMap& operator=(const CMap& cmap) {
   572 	checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
   573 	const typename Parent::Graph* graph = Parent::getGraph();
   574 	Edge it;
   575 	for (graph->first(it); it != INVALID; graph->next(it)) {
   576 	  Parent::set(it, cmap[it]);
   577 	}
   578 	return *this;
   579       }
   580     };
   581 
   582     template <typename _Value>
   583     class UndirEdgeMap 
   584       : public IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > {
   585     public:
   586       typedef StaticMappableUndirBipartiteGraphExtender Graph;
   587       typedef IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > 
   588       Parent;
   589     
   590       UndirEdgeMap(const Graph& _g) 
   591 	: Parent(_g) {}
   592       UndirEdgeMap(const Graph& _g, const _Value& _v) 
   593 	: Parent(_g, _v) {}
   594     
   595       UndirEdgeMap& operator=(const UndirEdgeMap& cmap) {
   596 	return operator=<UndirEdgeMap>(cmap);
   597       }
   598     
   599       template <typename CMap>
   600       UndirEdgeMap& operator=(const CMap& cmap) {
   601 	checkConcept<concept::ReadMap<UndirEdge, _Value>, CMap>();
   602 	const typename Parent::Graph* graph = Parent::getGraph();
   603 	UndirEdge it;
   604 	for (graph->first(it); it != INVALID; graph->next(it)) {
   605 	  Parent::set(it, cmap[it]);
   606 	}
   607 	return *this;
   608       }
   609     };
   610   
   611   };
   612 
   613 }
   614 
   615 #endif