00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
#ifndef LEMON_ARRAY_MAP_H
00018
#define LEMON_ARRAY_MAP_H
00019
00020
#include <memory>
00021
00022
#include <lemon/map_iterator.h>
00023
#include <lemon/map_bits.h>
00024
00029
00030
namespace lemon {
00031
00032
00035
00045
template <
typename MapRegistry,
typename Value>
00046 class ArrayMap :
public MapRegistry::
MapBase {
00047
00048
template <
typename MR,
typename V>
friend class ArrayMap;
00049
00050
public:
00051
00053 typedef typename MapRegistry::Graph
Graph;
00055 typedef typename MapRegistry::KeyType
KeyType;
00057 typedef typename MapRegistry::KeyIt
KeyIt;
00058
00060 typedef typename MapRegistry::MapBase MapBase;
00061
00062
00063
public:
00064
00066 typedef Value
ValueType;
00068 typedef Value&
ReferenceType;
00070 typedef Value*
PointerType;
00071
00073 typedef const Value
ConstValueType;
00075 typedef const Value&
ConstReferenceType;
00077 typedef const Value*
ConstPointerType;
00078
00079
00080
typedef std::allocator<Value> Allocator;
00081
00082
00085 ArrayMap(
const Graph& g,
MapRegistry& r) :
MapBase(g, r) {
00086 allocate_memory();
00087
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00088
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00089 allocator.construct(&(values[
id]), Value());
00090 }
00091 }
00092
00095 ArrayMap(
const Graph& g,
MapRegistry& r,
const Value& v)
00096 :
MapBase(g, r) {
00097 allocate_memory();
00098
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00099
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00100 allocator.construct(&(values[
id]), v);
00101 }
00102 }
00103
00106 ArrayMap(
const ArrayMap& copy) :
MapBase(copy) {
00107 capacity = copy.
capacity;
00108
if (capacity == 0)
return;
00109 values = allocator.allocate(capacity);
00110
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00111
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00112 allocator.construct(&(values[
id]), copy.
values[
id]);
00113 }
00114 }
00115
00118
template <
typename TT>
00119 ArrayMap(
const ArrayMap<MapRegistry, TT>& copy)
00120 :
MapBase(copy) {
00121 capacity = copy.
capacity;
00122
if (capacity == 0)
return;
00123 values = allocator.allocate(capacity);
00124
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00125
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00126 allocator.construct(&(values[
id]), copy.
values[
id]);
00127 }
00128 }
00129
00132 ArrayMap&
operator=(
const ArrayMap& copy) {
00133
if (© ==
this)
return *
this;
00134
00135
if (MapBase::getGraph() != copy.
getGraph()) {
00136
if (capacity != 0) {
00137 MapBase::destroy();
00138 allocator.deallocate(values, capacity);
00139 }
00140
00141 MapBase::operator=(copy);
00142 capacity = copy.
capacity;
00143
if (capacity == 0)
return *
this;
00144 values = allocator.allocate(capacity);
00145 }
00146
00147
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00148
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00149 allocator.construct(&(values[
id]), copy.
values[
id]);
00150 }
00151
00152
return *
this;
00153 }
00154
00157
template <
typename TT>
00158 ArrayMap&
operator=(
const ArrayMap<MapRegistry, TT>& copy) {
00159
00160
if (MapBase::getGraph() != copy.
getGraph()) {
00161
if (capacity != 0) {
00162 MapBase::destroy();
00163 allocator.deallocate(values, capacity);
00164 }
00165
00166 MapBase::operator=(copy);
00167
00168 capacity = copy.
capacity;
00169
if (capacity == 0)
return *
this;
00170 values = allocator.allocate(capacity);
00171 }
00172
00173
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00174
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00175 allocator.construct(&(values[
id]), copy.
values[
id]);
00176 }
00177
00178
return *
this;
00179 }
00180
00183 virtual ~ArrayMap() {
00184
if (capacity != 0) {
00185 MapBase::destroy();
00186 allocator.deallocate(values, capacity);
00187 }
00188 }
00189
00190
00195 ReferenceType operator[](
const KeyType& key) {
00196
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
00197
return values[
id];
00198 }
00199
00204 ConstReferenceType operator[](
const KeyType& key)
const {
00205
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
00206
return values[
id];
00207 }
00208
00212 void set(
const KeyType& key,
const ValueType& val) {
00213
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
00214 values[
id] = val;
00215 }
00216
00219 void add(
const KeyType& key) {
00220
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
00221
if (
id >= capacity) {
00222
int new_capacity = (capacity == 0 ? 1 : capacity);
00223
while (new_capacity <=
id) {
00224 new_capacity <<= 1;
00225 }
00226 Value* new_values = allocator.allocate(new_capacity);;
00227
for (
KeyIt it(*MapBase::getGraph()); it !=
INVALID; ++it) {
00228
int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
00229
if (
id != jd) {
00230 allocator.construct(&(new_values[jd]), values[jd]);
00231 allocator.destroy(&(values[jd]));
00232 }
00233 }
00234
if (capacity != 0) allocator.deallocate(values, capacity);
00235 values = new_values;
00236 capacity = new_capacity;
00237 }
00238 allocator.construct(&(values[
id]), Value());
00239 }
00240
00243 void erase(
const KeyType& key) {
00244
int id =
KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
00245 allocator.destroy(&(values[
id]));
00246 }
00247
00250 void clear() {
00251
if (capacity != 0) {
00252 MapBase::destroy();
00253 allocator.deallocate(values, capacity);
00254 capacity = 0;
00255 }
00256 }
00257
00259 typedef MapIterator<ArrayMap> Iterator;
00261 typedef MapConstIterator<ArrayMap> ConstIterator;
00262
00265 Iterator begin() {
00266
return Iterator(*
this,
KeyIt(*MapBase::getGraph()));
00267 }
00268
00271 Iterator end() {
00272
return Iterator(*
this,
INVALID);
00273 }
00274
00277 ConstIterator begin()
const {
00278
return ConstIterator(*
this,
KeyIt(*MapBase::getGraph()));
00279 }
00280
00283 ConstIterator end()
const {
00284
return ConstIterator(*
this,
INVALID);
00285 }
00286
00288 typedef MapConstKeySet<ArrayMap> ConstKeySet;
00289
00291 ConstKeySet keySet()
const {
00292
return ConstKeySet(*
this);
00293 }
00294
00296 typedef MapConstValueSet<ArrayMap> ConstValueSet;
00297
00299 ConstValueSet valueSet()
const {
00300
return ConstValueSet(*
this);
00301 }
00302
00304 typedef MapValueSet<ArrayMap> ValueSet;
00305
00307 ValueSet valueSet() {
00308
return ValueSet(*
this);
00309 }
00310
00311
private:
00312
00313
void allocate_memory() {
00314
int max_id =
KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph());
00315
if (max_id == -1) {
00316 capacity = 0;
00317 values = 0;
00318
return;
00319 }
00320 capacity = 1;
00321
while (capacity <= max_id) {
00322 capacity <<= 1;
00323 }
00324 values = allocator.allocate(capacity);
00325 }
00326
00327
int capacity;
00328 Value* values;
00329 Allocator allocator;
00330
00331
public:
00332
00333
typedef Iterator iterator;
00334
typedef ConstIterator const_iterator;
00335
typedef typename Iterator::PairValueType value_type;
00336
typedef typename Iterator::KeyType key_type;
00337
typedef typename Iterator::ValueType data_type;
00338
typedef typename Iterator::PairReferenceType reference;
00339
typedef typename Iterator::PairPointerType pointer;
00340
typedef typename ConstIterator::PairReferenceType const_reference;
00341
typedef typename ConstIterator::PairPointerType const_pointer;
00342
typedef int difference_type;
00343 };
00344
00346
00347 }
00348
00349
#endif //LEMON_ARRAY_MAP_H