lemon/bits/static_map.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1719 674182524bd9
child 1828 fd3771591a5c
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
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@1703
   346
deba@1703
   347
  };
deba@1703
   348
deba@1703
   349
}
deba@1703
   350
deba@1703
   351
#endif