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