lemon/bits/static_map.h
author alpar
Fri, 07 Oct 2005 11:05:35 +0000
changeset 1716 d8c28868f074
child 1719 674182524bd9
permissions -rw-r--r--
Sym -> Undir
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@1703
    24
#include <lemon/bits/map_iterator.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@1703
    65
    typedef True AdaptibleTag;
deba@1703
    66
		
deba@1703
    67
    /// The graph type of the map. 
deba@1703
    68
    typedef _Graph Graph;
deba@1703
    69
    /// The key type of the map.
deba@1703
    70
    typedef _Item Key;
deba@1703
    71
    /// The id map type of the map.
deba@1703
    72
    typedef AlterationNotifier<_Item> Registry;
deba@1703
    73
    /// The value type of the map.
deba@1703
    74
    typedef _Value Value;
deba@1703
    75
deba@1703
    76
    /// The map type.
deba@1703
    77
    typedef StaticMap Map;
deba@1703
    78
    /// The base class of the map.
deba@1703
    79
    typedef typename Registry::ObserverBase Parent;
deba@1703
    80
deba@1703
    81
  private:
deba@1703
    82
		
deba@1703
    83
    typedef std::vector<Value> Container;	
deba@1703
    84
deba@1703
    85
  public:
deba@1703
    86
deba@1703
    87
    /// \brief Constructor to attach the new map into the registry.
deba@1703
    88
    ///
deba@1703
    89
    /// It constructs a map and attachs it into the registry.
deba@1703
    90
    /// It adds all the items of the graph to the map.
deba@1703
    91
    StaticMap(const Graph& _g) : graph(&_g) {
deba@1703
    92
      attach(_g.getNotifier(_Item()));
deba@1703
    93
      build();
deba@1703
    94
    }
deba@1703
    95
deba@1703
    96
    /// \brief Constructor uses given value to initialize the map. 
deba@1703
    97
    ///
deba@1703
    98
    /// It constructs a map uses a given value to initialize the map. 
deba@1703
    99
    /// It adds all the items of the graph to the map.     
deba@1703
   100
    StaticMap(const Graph& _g, const Value& _v) : graph(&_g) { 
deba@1703
   101
      attach(_g.getNotifier(_Item()));
deba@1703
   102
      unsigned size = graph->maxId(_Item()) + 1;
deba@1703
   103
      container.reserve(size);
deba@1703
   104
      container.resize(size, _v);
deba@1703
   105
    }
deba@1703
   106
deba@1703
   107
    /// \brief Copy constructor
deba@1703
   108
    ///
deba@1703
   109
    /// Copy constructor.
deba@1703
   110
    StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) {
deba@1703
   111
      if (_copy.attached()) {
deba@1703
   112
	attach(*_copy.getRegistry());
deba@1703
   113
	container = _copy.container;
deba@1703
   114
      }
deba@1703
   115
    }
deba@1703
   116
deba@1703
   117
    /// \brief Destrcutor
deba@1703
   118
    ///
deba@1703
   119
    /// Destructor.
deba@1703
   120
    virtual ~StaticMap() {
deba@1703
   121
      clear();
deba@1703
   122
      if (attached()) {
deba@1703
   123
	detach();
deba@1703
   124
      }
deba@1703
   125
    }
deba@1703
   126
deba@1703
   127
deba@1703
   128
  private:
deba@1703
   129
deba@1703
   130
    StaticMap& operator=(const StaticMap&);
deba@1703
   131
deba@1703
   132
  protected:
deba@1703
   133
deba@1703
   134
    using Parent::attach;
deba@1703
   135
    using Parent::detach;
deba@1703
   136
    using Parent::attached;
deba@1703
   137
deba@1703
   138
    const Graph* getGraph() const {
deba@1703
   139
      return graph;
deba@1703
   140
    }
deba@1703
   141
deba@1703
   142
  public:
deba@1703
   143
deba@1703
   144
    typedef typename Container::reference Reference;
deba@1703
   145
    typedef typename Container::pointer Pointer;
deba@1703
   146
    typedef const Value ConstValue;
deba@1703
   147
    typedef typename Container::const_reference ConstReference;
deba@1703
   148
    typedef typename Container::const_pointer ConstPointer;
deba@1703
   149
deba@1703
   150
    /// \brief The subcript operator.
deba@1703
   151
    ///
deba@1703
   152
    /// The subscript operator. The map can be subscripted by the
deba@1703
   153
    /// actual items of the graph. 
deba@1703
   154
     
deba@1703
   155
    Reference operator[](const Key& key) {
deba@1703
   156
      return container[graph->id(key)];
deba@1703
   157
    } 
deba@1703
   158
		
deba@1703
   159
    /// \brief The const subcript operator.
deba@1703
   160
    ///
deba@1703
   161
    /// The const subscript operator. The map can be subscripted by the
deba@1703
   162
    /// actual items of the graph. 
deba@1703
   163
     
deba@1703
   164
    ConstReference operator[](const Key& key) const {
deba@1703
   165
      return container[graph->id(key)];
deba@1703
   166
    }
deba@1703
   167
deba@1703
   168
deba@1703
   169
    /// \brief The setter function of the map.
deba@1703
   170
    ///
deba@1703
   171
    /// It the same as operator[](key) = value expression.
deba@1703
   172
    ///
deba@1703
   173
    void set(const Key& key, const Value& value) {
deba@1703
   174
      (*this)[key] = value;
deba@1703
   175
    }
deba@1703
   176
deba@1703
   177
  protected:
deba@1703
   178
deba@1703
   179
    /// \brief Adds a new key to the map.
deba@1703
   180
    ///		
deba@1703
   181
    /// It adds a new key to the map. It called by the observer registry
deba@1703
   182
    /// and it overrides the add() member function of the observer base.
deba@1703
   183
     
deba@1703
   184
    void add(const Key&) {
deba@1703
   185
      throw UnsupportedOperation();
deba@1703
   186
    }
deba@1703
   187
deba@1703
   188
    /// \brief Erases a key from the map.
deba@1703
   189
    ///
deba@1703
   190
    /// Erase a key from the map. It called by the observer registry
deba@1703
   191
    /// and it overrides the erase() member function of the observer base.     
deba@1703
   192
    void erase(const Key&) {
deba@1703
   193
      throw UnsupportedOperation();
deba@1703
   194
    }
deba@1703
   195
deba@1703
   196
    /// Buildes the map.
deba@1703
   197
		
deba@1703
   198
    /// It buildes the map. It called by the observer registry
deba@1703
   199
    /// and it overrides the build() member function of the observer base.
deba@1703
   200
deba@1703
   201
    void build() { 
deba@1703
   202
      int size = graph->maxId(_Item()) + 1;
deba@1703
   203
      container.reserve(size);
deba@1703
   204
      container.resize(size);
deba@1703
   205
    }
deba@1703
   206
deba@1703
   207
    /// Clear the map.
deba@1703
   208
deba@1703
   209
    /// It erase all items from the map. It called by the observer registry
deba@1703
   210
    /// and it overrides the clear() member function of the observer base.     
deba@1703
   211
    void clear() { 
deba@1703
   212
      container.clear();
deba@1703
   213
    }
deba@1703
   214
    
deba@1703
   215
  private:
deba@1703
   216
		
deba@1703
   217
    Container container;
deba@1703
   218
    const Graph *graph;
deba@1703
   219
deba@1703
   220
  };
deba@1703
   221
deba@1703
   222
  /// \e
deba@1703
   223
  template <typename _Base> 
deba@1703
   224
  class StaticMappableGraphExtender : public _Base {
deba@1703
   225
  public:
deba@1703
   226
deba@1703
   227
    typedef StaticMappableGraphExtender<_Base> Graph;
deba@1703
   228
    typedef _Base Parent;
deba@1703
   229
deba@1703
   230
    typedef typename Parent::Node Node;
deba@1703
   231
    typedef typename Parent::NodeIt NodeIt;
deba@1703
   232
deba@1703
   233
    typedef typename Parent::Edge Edge;
deba@1703
   234
    typedef typename Parent::EdgeIt EdgeIt;
deba@1703
   235
deba@1703
   236
    
deba@1703
   237
    template <typename _Value>
deba@1703
   238
    class NodeMap 
deba@1703
   239
      : public IterableMapExtender<StaticMap<Graph, Node, _Value> > {
deba@1703
   240
    public:
deba@1703
   241
      typedef StaticMappableGraphExtender Graph;
deba@1703
   242
      typedef IterableMapExtender<StaticMap<Graph, Node, _Value> > Parent;
deba@1703
   243
deba@1703
   244
      NodeMap(const Graph& _g) 
deba@1703
   245
	: Parent(_g) {}
deba@1703
   246
      NodeMap(const Graph& _g, const _Value& _v) 
deba@1703
   247
	: Parent(_g, _v) {}
deba@1703
   248
deba@1703
   249
      NodeMap& operator=(const NodeMap& cmap) {
deba@1703
   250
	return operator=<NodeMap>(cmap);
deba@1703
   251
      }
deba@1703
   252
deba@1703
   253
deba@1703
   254
      /// \brief Template assign operator.
deba@1703
   255
      ///
deba@1703
   256
      /// The given parameter should be conform to the ReadMap
deba@1703
   257
      /// concecpt and could be indiced by the current item set of
deba@1703
   258
      /// the NodeMap. In this case the value for each item
deba@1703
   259
      /// is assigned by the value of the given ReadMap. 
deba@1703
   260
      template <typename CMap>
deba@1703
   261
      NodeMap& operator=(const CMap& cmap) {
deba@1703
   262
	checkConcept<concept::ReadMap<Node, _Value>, CMap>();
deba@1703
   263
	const typename Parent::Graph* graph = Parent::getGraph();
deba@1703
   264
	Node it;
deba@1703
   265
	for (graph->first(it); it != INVALID; graph->next(it)) {
deba@1703
   266
	  Parent::set(it, cmap[it]);
deba@1703
   267
	}
deba@1703
   268
	return *this;
deba@1703
   269
      }
deba@1703
   270
deba@1703
   271
    };
deba@1703
   272
deba@1703
   273
    template <typename _Value>
deba@1703
   274
    class EdgeMap 
deba@1703
   275
      : public IterableMapExtender<StaticMap<Graph, Edge, _Value> > {
deba@1703
   276
    public:
deba@1703
   277
      typedef StaticMappableGraphExtender Graph;
deba@1703
   278
      typedef IterableMapExtender<StaticMap<Graph, Edge, _Value> > Parent;
deba@1703
   279
deba@1703
   280
      EdgeMap(const Graph& _g) 
deba@1703
   281
	: Parent(_g) {}
deba@1703
   282
      EdgeMap(const Graph& _g, const _Value& _v) 
deba@1703
   283
	: Parent(_g, _v) {}
deba@1703
   284
deba@1703
   285
      EdgeMap& operator=(const EdgeMap& cmap) {
deba@1703
   286
	return operator=<EdgeMap>(cmap);
deba@1703
   287
      }
deba@1703
   288
deba@1703
   289
      template <typename CMap>
deba@1703
   290
      EdgeMap& operator=(const CMap& cmap) {
deba@1703
   291
	checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
deba@1703
   292
	const typename Parent::Graph* graph = Parent::getGraph();
deba@1703
   293
	Edge it;
deba@1703
   294
	for (graph->first(it); it != INVALID; graph->next(it)) {
deba@1703
   295
	  Parent::set(it, cmap[it]);
deba@1703
   296
	}
deba@1703
   297
	return *this;
deba@1703
   298
      }
deba@1703
   299
    };
deba@1703
   300
    
deba@1703
   301
  };
deba@1703
   302
deba@1703
   303
  /// \e
deba@1703
   304
  template <typename _Base> 
deba@1703
   305
  class StaticMappableUndirGraphExtender : 
deba@1703
   306
    public StaticMappableGraphExtender<_Base> {
deba@1703
   307
  public:
deba@1703
   308
deba@1703
   309
    typedef StaticMappableUndirGraphExtender Graph;
deba@1703
   310
    typedef StaticMappableGraphExtender<_Base> Parent;
deba@1703
   311
deba@1703
   312
    typedef typename Parent::UndirEdge UndirEdge;
deba@1703
   313
deba@1703
   314
    template <typename _Value>
deba@1703
   315
    class UndirEdgeMap 
deba@1703
   316
      : public IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > {
deba@1703
   317
    public:
deba@1703
   318
      typedef StaticMappableUndirGraphExtender Graph;
deba@1703
   319
      typedef IterableMapExtender<
deba@1703
   320
	StaticMap<Graph, UndirEdge, _Value> > Parent;
deba@1703
   321
deba@1703
   322
      UndirEdgeMap(const Graph& _g) 
deba@1703
   323
	: Parent(_g) {}
deba@1703
   324
      UndirEdgeMap(const Graph& _g, const _Value& _v) 
deba@1703
   325
	: Parent(_g, _v) {}
deba@1703
   326
deba@1703
   327
      UndirEdgeMap& operator=(const UndirEdgeMap& cmap) {
deba@1703
   328
	return operator=<UndirEdgeMap>(cmap);
deba@1703
   329
      }
deba@1703
   330
deba@1703
   331
      template <typename CMap>
deba@1703
   332
      UndirEdgeMap& operator=(const CMap& cmap) {
deba@1703
   333
	checkConcept<concept::ReadMap<UndirEdge, _Value>, CMap>();
deba@1703
   334
	const typename Parent::Graph* graph = Parent::getGraph();
deba@1703
   335
	UndirEdge it;
deba@1703
   336
	for (graph->first(it); it != INVALID; graph->next(it)) {
deba@1703
   337
	  Parent::set(it, cmap[it]);
deba@1703
   338
	}
deba@1703
   339
	return *this;
deba@1703
   340
      }
deba@1703
   341
    };
deba@1703
   342
deba@1703
   343
deba@1703
   344
  };
deba@1703
   345
deba@1703
   346
}
deba@1703
   347
deba@1703
   348
#endif