lemon/bits/static_map.h
author deba
Fri, 14 Oct 2005 10:48:34 +0000
changeset 1719 674182524bd9
parent 1703 eb90e3d6bddc
child 1810 474d093466a5
permissions -rw-r--r--
Traits moved to own file
Tag for reference maps
Possibility to handle proper the return type
of the operator[]() const -- value or reference
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@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