lemon/bits/static_map.h
author hegyi
Wed, 23 Nov 2005 16:24:59 +0000
changeset 1831 75ab76fc4bf2
parent 1810 474d093466a5
child 1875 98698b69a902
permissions -rw-r--r--
No segmentation fault caused by zero long edges.
     1 /* -*- C++ -*-
     2  * lemon/static_map.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 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