test/maps_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 1047 ddd3c0d3d9bf
parent 836 8ddb7deabab9
child 1057 633956ca9421
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@25
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@25
     4
 *
alpar@956
     5
 * Copyright (C) 2003-2010
alpar@25
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@25
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@25
     8
 *
alpar@25
     9
 * Permission to use, modify and distribute this software is granted
alpar@25
    10
 * provided that this copyright notice appears in all copies. For
alpar@25
    11
 * precise terms see the accompanying LICENSE file.
alpar@25
    12
 *
alpar@25
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@25
    14
 * express or implied, and with no claim as to its suitability for any
alpar@25
    15
 * purpose.
alpar@25
    16
 *
alpar@25
    17
 */
alpar@25
    18
alpar@25
    19
#include <deque>
alpar@25
    20
#include <set>
alpar@25
    21
alpar@25
    22
#include <lemon/concept_check.h>
alpar@25
    23
#include <lemon/concepts/maps.h>
alpar@25
    24
#include <lemon/maps.h>
kpeter@731
    25
#include <lemon/list_graph.h>
kpeter@741
    26
#include <lemon/smart_graph.h>
kpeter@770
    27
#include <lemon/adaptors.h>
kpeter@770
    28
#include <lemon/dfs.h>
kpeter@836
    29
#include <algorithm>
alpar@25
    30
alpar@25
    31
#include "test_tools.h"
alpar@25
    32
alpar@25
    33
using namespace lemon;
alpar@25
    34
using namespace lemon::concepts;
alpar@25
    35
alpar@25
    36
struct A {};
alpar@25
    37
inline bool operator<(A, A) { return true; }
alpar@25
    38
struct B {};
alpar@25
    39
kpeter@94
    40
class C {
kpeter@836
    41
  int _x;
kpeter@94
    42
public:
kpeter@836
    43
  C(int x) : _x(x) {}
kpeter@836
    44
  int get() const { return _x; }
kpeter@836
    45
};
kpeter@836
    46
inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
kpeter@836
    47
inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
kpeter@836
    48
kpeter@836
    49
C createC(int x) { return C(x); }
kpeter@836
    50
kpeter@836
    51
template <typename T>
kpeter@836
    52
class Less {
kpeter@836
    53
  T _t;
kpeter@836
    54
public:
kpeter@836
    55
  Less(T t): _t(t) {}
kpeter@836
    56
  bool operator()(const T& t) const { return t < _t; }
kpeter@94
    57
};
kpeter@94
    58
alpar@25
    59
class F {
alpar@25
    60
public:
alpar@25
    61
  typedef A argument_type;
alpar@25
    62
  typedef B result_type;
alpar@25
    63
kpeter@80
    64
  B operator()(const A&) const { return B(); }
kpeter@80
    65
private:
kpeter@80
    66
  F& operator=(const F&);
alpar@25
    67
};
alpar@25
    68
kpeter@80
    69
int func(A) { return 3; }
alpar@25
    70
kpeter@80
    71
int binc(int a, B) { return a+1; }
alpar@25
    72
kpeter@836
    73
template <typename T>
kpeter@836
    74
class Sum {
kpeter@836
    75
  T& _sum;
kpeter@836
    76
public:
kpeter@836
    77
  Sum(T& sum) : _sum(sum) {}
kpeter@836
    78
  void operator()(const T& t) { _sum += t; }
kpeter@836
    79
};
kpeter@836
    80
kpeter@80
    81
typedef ReadMap<A, double> DoubleMap;
kpeter@80
    82
typedef ReadWriteMap<A, double> DoubleWriteMap;
kpeter@80
    83
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
alpar@25
    84
kpeter@80
    85
typedef ReadMap<A, bool> BoolMap;
alpar@25
    86
typedef ReadWriteMap<A, bool> BoolWriteMap;
kpeter@80
    87
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
alpar@25
    88
alpar@25
    89
int main()
kpeter@80
    90
{
kpeter@80
    91
  // Map concepts
alpar@25
    92
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
kpeter@94
    93
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
alpar@25
    94
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
kpeter@94
    95
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
alpar@25
    96
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
kpeter@94
    97
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
alpar@25
    98
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
kpeter@94
    99
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
alpar@25
   100
kpeter@80
   101
  // NullMap
kpeter@80
   102
  {
kpeter@80
   103
    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
kpeter@80
   104
    NullMap<A,B> map1;
kpeter@80
   105
    NullMap<A,B> map2 = map1;
kpeter@80
   106
    map1 = nullMap<A,B>();
kpeter@80
   107
  }
kpeter@80
   108
kpeter@80
   109
  // ConstMap
kpeter@80
   110
  {
kpeter@80
   111
    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
kpeter@123
   112
    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
kpeter@80
   113
    ConstMap<A,B> map1;
deba@136
   114
    ConstMap<A,B> map2 = B();
kpeter@80
   115
    ConstMap<A,B> map3 = map1;
kpeter@80
   116
    map1 = constMap<A>(B());
kpeter@123
   117
    map1 = constMap<A,B>();
kpeter@80
   118
    map1.setAll(B());
kpeter@123
   119
    ConstMap<A,C> map4(C(1));
kpeter@123
   120
    ConstMap<A,C> map5 = map4;
kpeter@123
   121
    map4 = constMap<A>(C(2));
kpeter@123
   122
    map4.setAll(C(3));
kpeter@82
   123
kpeter@80
   124
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
kpeter@80
   125
    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
kpeter@80
   126
kpeter@80
   127
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
kpeter@123
   128
    ConstMap<A,Const<int,10> > map6;
kpeter@123
   129
    ConstMap<A,Const<int,10> > map7 = map6;
kpeter@123
   130
    map6 = constMap<A,int,10>();
kpeter@123
   131
    map7 = constMap<A,Const<int,10> >();
alpar@210
   132
    check(map6[A()] == 10 && map7[A()] == 10,
alpar@210
   133
          "Something is wrong with ConstMap");
kpeter@80
   134
  }
kpeter@80
   135
kpeter@80
   136
  // IdentityMap
kpeter@80
   137
  {
kpeter@80
   138
    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
kpeter@80
   139
    IdentityMap<A> map1;
kpeter@80
   140
    IdentityMap<A> map2 = map1;
kpeter@80
   141
    map1 = identityMap<A>();
kpeter@82
   142
kpeter@80
   143
    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
alpar@210
   144
    check(identityMap<double>()[1.0] == 1.0 &&
alpar@210
   145
          identityMap<double>()[3.14] == 3.14,
kpeter@80
   146
          "Something is wrong with IdentityMap");
kpeter@80
   147
  }
kpeter@80
   148
kpeter@80
   149
  // RangeMap
kpeter@80
   150
  {
kpeter@80
   151
    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
kpeter@80
   152
    RangeMap<B> map1;
kpeter@80
   153
    RangeMap<B> map2(10);
kpeter@80
   154
    RangeMap<B> map3(10,B());
kpeter@80
   155
    RangeMap<B> map4 = map1;
kpeter@80
   156
    RangeMap<B> map5 = rangeMap<B>();
kpeter@80
   157
    RangeMap<B> map6 = rangeMap<B>(10);
kpeter@80
   158
    RangeMap<B> map7 = rangeMap(10,B());
kpeter@80
   159
kpeter@80
   160
    checkConcept< ReferenceMap<int, double, double&, const double&>,
kpeter@80
   161
                  RangeMap<double> >();
kpeter@80
   162
    std::vector<double> v(10, 0);
kpeter@80
   163
    v[5] = 100;
kpeter@80
   164
    RangeMap<double> map8(v);
kpeter@80
   165
    RangeMap<double> map9 = rangeMap(v);
kpeter@80
   166
    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
kpeter@80
   167
          "Something is wrong with RangeMap");
kpeter@80
   168
  }
kpeter@80
   169
kpeter@80
   170
  // SparseMap
kpeter@80
   171
  {
kpeter@80
   172
    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
kpeter@80
   173
    SparseMap<A,B> map1;
deba@136
   174
    SparseMap<A,B> map2 = B();
kpeter@80
   175
    SparseMap<A,B> map3 = sparseMap<A,B>();
kpeter@80
   176
    SparseMap<A,B> map4 = sparseMap<A>(B());
kpeter@80
   177
kpeter@80
   178
    checkConcept< ReferenceMap<double, int, int&, const int&>,
kpeter@80
   179
                  SparseMap<double, int> >();
kpeter@80
   180
    std::map<double, int> m;
kpeter@80
   181
    SparseMap<double, int> map5(m);
kpeter@80
   182
    SparseMap<double, int> map6(m,10);
kpeter@80
   183
    SparseMap<double, int> map7 = sparseMap(m);
kpeter@80
   184
    SparseMap<double, int> map8 = sparseMap(m,10);
kpeter@80
   185
alpar@210
   186
    check(map5[1.0] == 0 && map5[3.14] == 0 &&
alpar@210
   187
          map6[1.0] == 10 && map6[3.14] == 10,
kpeter@80
   188
          "Something is wrong with SparseMap");
kpeter@80
   189
    map5[1.0] = map6[3.14] = 100;
alpar@210
   190
    check(map5[1.0] == 100 && map5[3.14] == 0 &&
alpar@210
   191
          map6[1.0] == 10 && map6[3.14] == 100,
kpeter@80
   192
          "Something is wrong with SparseMap");
kpeter@80
   193
  }
kpeter@80
   194
kpeter@80
   195
  // ComposeMap
kpeter@80
   196
  {
kpeter@80
   197
    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
kpeter@80
   198
    checkConcept<ReadMap<B,double>, CompMap>();
alpar@554
   199
    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
kpeter@80
   200
    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
kpeter@82
   201
kpeter@80
   202
    SparseMap<double, bool> m1(false); m1[3.14] = true;
kpeter@80
   203
    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
alpar@210
   204
    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
alpar@210
   205
          "Something is wrong with ComposeMap")
kpeter@80
   206
  }
kpeter@80
   207
kpeter@80
   208
  // CombineMap
kpeter@80
   209
  {
kpeter@80
   210
    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
kpeter@80
   211
    checkConcept<ReadMap<A,double>, CombMap>();
alpar@554
   212
    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
kpeter@80
   213
    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
kpeter@80
   214
kpeter@80
   215
    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
kpeter@80
   216
          "Something is wrong with CombineMap");
kpeter@80
   217
  }
kpeter@80
   218
kpeter@80
   219
  // FunctorToMap, MapToFunctor
kpeter@80
   220
  {
kpeter@80
   221
    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
kpeter@80
   222
    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
kpeter@80
   223
    FunctorToMap<F> map1;
alpar@554
   224
    FunctorToMap<F> map2 = FunctorToMap<F>(F());
kpeter@80
   225
    B b = functorToMap(F())[A()];
kpeter@80
   226
kpeter@80
   227
    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
alpar@956
   228
    MapToFunctor<ReadMap<A,B> > map =
alpar@956
   229
      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
kpeter@80
   230
alpar@210
   231
    check(functorToMap(&func)[A()] == 3,
alpar@210
   232
          "Something is wrong with FunctorToMap");
alpar@210
   233
    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
alpar@210
   234
          "Something is wrong with MapToFunctor");
alpar@210
   235
    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
alpar@210
   236
          mapToFunctor(functorToMap(&func))[A()] == 3,
kpeter@80
   237
          "Something is wrong with FunctorToMap or MapToFunctor");
kpeter@80
   238
    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
kpeter@80
   239
          "Something is wrong with FunctorToMap or MapToFunctor");
kpeter@80
   240
  }
kpeter@80
   241
kpeter@80
   242
  // ConvertMap
kpeter@80
   243
  {
alpar@210
   244
    checkConcept<ReadMap<double,double>,
alpar@210
   245
      ConvertMap<ReadMap<double, int>, double> >();
kpeter@80
   246
    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
kpeter@80
   247
    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
kpeter@80
   248
  }
kpeter@80
   249
kpeter@80
   250
  // ForkMap
kpeter@80
   251
  {
kpeter@80
   252
    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
kpeter@82
   253
kpeter@80
   254
    typedef RangeMap<double> RM;
kpeter@80
   255
    typedef SparseMap<int, double> SM;
kpeter@80
   256
    RM m1(10, -1);
kpeter@80
   257
    SM m2(-1);
kpeter@80
   258
    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
kpeter@80
   259
    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
kpeter@80
   260
    ForkMap<RM, SM> map1(m1,m2);
kpeter@80
   261
    ForkMap<SM, RM> map2 = forkMap(m2,m1);
kpeter@80
   262
    map2.set(5, 10);
alpar@210
   263
    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
alpar@210
   264
          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
kpeter@80
   265
          "Something is wrong with ForkMap");
kpeter@80
   266
  }
kpeter@82
   267
kpeter@80
   268
  // Arithmetic maps:
kpeter@80
   269
  // - AddMap, SubMap, MulMap, DivMap
kpeter@80
   270
  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
kpeter@80
   271
  // - NegMap, NegWriteMap, AbsMap
kpeter@80
   272
  {
kpeter@80
   273
    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
kpeter@80
   274
    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
kpeter@80
   275
    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
kpeter@80
   276
    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
kpeter@82
   277
kpeter@80
   278
    ConstMap<int, double> c1(1.0), c2(3.14);
kpeter@80
   279
    IdentityMap<int> im;
kpeter@80
   280
    ConvertMap<IdentityMap<int>, double> id(im);
alpar@210
   281
    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
alpar@210
   282
          "Something is wrong with AddMap");
alpar@210
   283
    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
alpar@210
   284
          "Something is wrong with SubMap");
alpar@210
   285
    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
alpar@210
   286
          "Something is wrong with MulMap");
alpar@210
   287
    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
alpar@210
   288
          "Something is wrong with DivMap");
kpeter@82
   289
kpeter@80
   290
    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
kpeter@80
   291
    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
kpeter@80
   292
    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
kpeter@80
   293
    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
kpeter@80
   294
    checkConcept<DoubleMap, NegMap<DoubleMap> >();
kpeter@80
   295
    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
kpeter@80
   296
    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
alpar@25
   297
kpeter@80
   298
    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
kpeter@80
   299
          "Something is wrong with ShiftMap");
alpar@210
   300
    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
alpar@210
   301
          shiftWriteMap(id, 2.0)[10] == 12.0,
kpeter@80
   302
          "Something is wrong with ShiftWriteMap");
kpeter@80
   303
    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
kpeter@80
   304
          "Something is wrong with ScaleMap");
alpar@210
   305
    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
alpar@210
   306
          scaleWriteMap(id, 2.0)[10] == 20.0,
kpeter@80
   307
          "Something is wrong with ScaleWriteMap");
kpeter@80
   308
    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
kpeter@80
   309
          "Something is wrong with NegMap");
kpeter@80
   310
    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
kpeter@80
   311
          "Something is wrong with NegWriteMap");
kpeter@80
   312
    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
kpeter@80
   313
          "Something is wrong with AbsMap");
kpeter@80
   314
  }
kpeter@82
   315
kpeter@82
   316
  // Logical maps:
kpeter@82
   317
  // - TrueMap, FalseMap
kpeter@82
   318
  // - AndMap, OrMap
kpeter@82
   319
  // - NotMap, NotWriteMap
kpeter@82
   320
  // - EqualMap, LessMap
kpeter@80
   321
  {
kpeter@82
   322
    checkConcept<BoolMap, TrueMap<A> >();
kpeter@82
   323
    checkConcept<BoolMap, FalseMap<A> >();
kpeter@82
   324
    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
kpeter@82
   325
    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
kpeter@80
   326
    checkConcept<BoolMap, NotMap<BoolMap> >();
kpeter@80
   327
    checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
kpeter@82
   328
    checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
kpeter@82
   329
    checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
kpeter@82
   330
kpeter@82
   331
    TrueMap<int> tm;
kpeter@82
   332
    FalseMap<int> fm;
kpeter@80
   333
    RangeMap<bool> rm(2);
kpeter@80
   334
    rm[0] = true; rm[1] = false;
alpar@210
   335
    check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
alpar@210
   336
          !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
kpeter@82
   337
          "Something is wrong with AndMap");
alpar@210
   338
    check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
alpar@210
   339
          orMap(fm,rm)[0] && !orMap(fm,rm)[1],
kpeter@82
   340
          "Something is wrong with OrMap");
alpar@210
   341
    check(!notMap(rm)[0] && notMap(rm)[1],
alpar@210
   342
          "Something is wrong with NotMap");
alpar@210
   343
    check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
alpar@210
   344
          "Something is wrong with NotWriteMap");
kpeter@82
   345
kpeter@82
   346
    ConstMap<int, double> cm(2.0);
kpeter@82
   347
    IdentityMap<int> im;
kpeter@82
   348
    ConvertMap<IdentityMap<int>, double> id(im);
kpeter@82
   349
    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
kpeter@82
   350
          "Something is wrong with LessMap");
kpeter@82
   351
    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
kpeter@82
   352
          "Something is wrong with EqualMap");
kpeter@80
   353
  }
alpar@209
   354
kpeter@167
   355
  // LoggerBoolMap
kpeter@159
   356
  {
kpeter@159
   357
    typedef std::vector<int> vec;
kpeter@767
   358
    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
kpeter@767
   359
    checkConcept<WriteMap<int, bool>,
kpeter@767
   360
                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
kpeter@767
   361
kpeter@159
   362
    vec v1;
kpeter@159
   363
    vec v2(10);
alpar@210
   364
    LoggerBoolMap<std::back_insert_iterator<vec> >
alpar@210
   365
      map1(std::back_inserter(v1));
kpeter@167
   366
    LoggerBoolMap<vec::iterator> map2(v2.begin());
kpeter@159
   367
    map1.set(10, false);
kpeter@159
   368
    map1.set(20, true);   map2.set(20, true);
kpeter@159
   369
    map1.set(30, false);  map2.set(40, false);
kpeter@159
   370
    map1.set(50, true);   map2.set(50, true);
kpeter@159
   371
    map1.set(60, true);   map2.set(60, true);
kpeter@159
   372
    check(v1.size() == 3 && v2.size() == 10 &&
alpar@210
   373
          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
alpar@210
   374
          v2[0]==20 && v2[1]==50 && v2[2]==60,
kpeter@167
   375
          "Something is wrong with LoggerBoolMap");
alpar@209
   376
kpeter@159
   377
    int i = 0;
kpeter@167
   378
    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
kpeter@159
   379
          it != map2.end(); ++it )
kpeter@167
   380
      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
alpar@956
   381
kpeter@770
   382
    typedef ListDigraph Graph;
kpeter@770
   383
    DIGRAPH_TYPEDEFS(Graph);
kpeter@770
   384
    Graph gr;
kpeter@770
   385
kpeter@770
   386
    Node n0 = gr.addNode();
kpeter@770
   387
    Node n1 = gr.addNode();
kpeter@770
   388
    Node n2 = gr.addNode();
kpeter@770
   389
    Node n3 = gr.addNode();
alpar@956
   390
kpeter@770
   391
    gr.addArc(n3, n0);
kpeter@770
   392
    gr.addArc(n3, n2);
kpeter@770
   393
    gr.addArc(n0, n2);
kpeter@770
   394
    gr.addArc(n2, n1);
kpeter@770
   395
    gr.addArc(n0, n1);
alpar@956
   396
kpeter@770
   397
    {
kpeter@770
   398
      std::vector<Node> v;
kpeter@770
   399
      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
kpeter@770
   400
kpeter@770
   401
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
kpeter@770
   402
            "Something is wrong with LoggerBoolMap");
kpeter@770
   403
    }
kpeter@770
   404
    {
kpeter@770
   405
      std::vector<Node> v(countNodes(gr));
kpeter@770
   406
      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
alpar@956
   407
kpeter@770
   408
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
kpeter@770
   409
            "Something is wrong with LoggerBoolMap");
kpeter@770
   410
    }
kpeter@741
   411
  }
alpar@956
   412
kpeter@767
   413
  // IdMap, RangeIdMap
kpeter@767
   414
  {
kpeter@767
   415
    typedef ListDigraph Graph;
kpeter@767
   416
    DIGRAPH_TYPEDEFS(Graph);
kpeter@767
   417
kpeter@767
   418
    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
kpeter@767
   419
    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
kpeter@767
   420
    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
kpeter@767
   421
    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
alpar@956
   422
kpeter@767
   423
    Graph gr;
kpeter@767
   424
    IdMap<Graph, Node> nmap(gr);
kpeter@767
   425
    IdMap<Graph, Arc> amap(gr);
kpeter@767
   426
    RangeIdMap<Graph, Node> nrmap(gr);
kpeter@767
   427
    RangeIdMap<Graph, Arc> armap(gr);
alpar@956
   428
kpeter@767
   429
    Node n0 = gr.addNode();
kpeter@767
   430
    Node n1 = gr.addNode();
kpeter@767
   431
    Node n2 = gr.addNode();
alpar@956
   432
kpeter@767
   433
    Arc a0 = gr.addArc(n0, n1);
kpeter@767
   434
    Arc a1 = gr.addArc(n0, n2);
kpeter@767
   435
    Arc a2 = gr.addArc(n2, n1);
kpeter@767
   436
    Arc a3 = gr.addArc(n2, n0);
alpar@956
   437
kpeter@767
   438
    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
kpeter@767
   439
    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
kpeter@767
   440
    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
kpeter@767
   441
kpeter@767
   442
    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
kpeter@767
   443
    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
kpeter@767
   444
    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
kpeter@767
   445
    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
kpeter@767
   446
kpeter@767
   447
    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
kpeter@767
   448
    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
alpar@956
   449
kpeter@767
   450
    check(nrmap.size() == 3 && armap.size() == 4,
kpeter@767
   451
          "Wrong RangeIdMap::size()");
kpeter@767
   452
kpeter@767
   453
    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
kpeter@767
   454
    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
kpeter@767
   455
    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
alpar@956
   456
kpeter@767
   457
    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
kpeter@767
   458
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
kpeter@767
   459
    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
kpeter@767
   460
    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
kpeter@767
   461
kpeter@767
   462
    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
kpeter@767
   463
    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
alpar@956
   464
kpeter@767
   465
    gr.erase(n1);
alpar@956
   466
kpeter@767
   467
    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
kpeter@767
   468
    nrmap.swap(n2, n0);
kpeter@767
   469
    if (armap[a1] == 1) armap.swap(a1, a3);
kpeter@767
   470
    armap.swap(a3, a1);
alpar@956
   471
kpeter@767
   472
    check(nrmap.size() == 2 && armap.size() == 2,
kpeter@767
   473
          "Wrong RangeIdMap::size()");
kpeter@767
   474
kpeter@767
   475
    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
kpeter@767
   476
    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
alpar@956
   477
kpeter@767
   478
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
kpeter@767
   479
    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
kpeter@767
   480
kpeter@767
   481
    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
kpeter@767
   482
    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
kpeter@767
   483
  }
alpar@956
   484
kpeter@770
   485
  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
kpeter@770
   486
  {
kpeter@770
   487
    typedef ListGraph Graph;
kpeter@770
   488
    GRAPH_TYPEDEFS(Graph);
alpar@956
   489
kpeter@770
   490
    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
kpeter@770
   491
    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
kpeter@770
   492
    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
kpeter@770
   493
    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
kpeter@770
   494
    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
kpeter@770
   495
    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
kpeter@770
   496
kpeter@770
   497
    Graph gr;
kpeter@770
   498
    Node n0 = gr.addNode();
kpeter@770
   499
    Node n1 = gr.addNode();
kpeter@770
   500
    Node n2 = gr.addNode();
alpar@956
   501
kpeter@770
   502
    gr.addEdge(n0,n1);
kpeter@770
   503
    gr.addEdge(n1,n2);
kpeter@770
   504
    gr.addEdge(n0,n2);
kpeter@770
   505
    gr.addEdge(n2,n1);
kpeter@770
   506
    gr.addEdge(n1,n2);
kpeter@770
   507
    gr.addEdge(n0,n1);
alpar@956
   508
kpeter@770
   509
    for (EdgeIt e(gr); e != INVALID; ++e) {
kpeter@770
   510
      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
kpeter@770
   511
      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
kpeter@770
   512
    }
alpar@956
   513
kpeter@836
   514
    check(mapCompare(gr,
kpeter@836
   515
          sourceMap(orienter(gr, constMap<Edge, bool>(true))),
kpeter@836
   516
          targetMap(orienter(gr, constMap<Edge, bool>(false)))),
kpeter@836
   517
          "Wrong SourceMap or TargetMap");
kpeter@770
   518
kpeter@770
   519
    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
kpeter@770
   520
    Digraph dgr(gr, constMap<Edge, bool>(true));
kpeter@770
   521
    OutDegMap<Digraph> odm(dgr);
kpeter@770
   522
    InDegMap<Digraph> idm(dgr);
alpar@956
   523
kpeter@770
   524
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
kpeter@770
   525
    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
alpar@956
   526
kpeter@770
   527
    gr.addEdge(n2, n0);
kpeter@770
   528
kpeter@770
   529
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
kpeter@770
   530
    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
kpeter@770
   531
  }
alpar@956
   532
kpeter@731
   533
  // CrossRefMap
kpeter@731
   534
  {
kpeter@731
   535
    typedef ListDigraph Graph;
kpeter@731
   536
    DIGRAPH_TYPEDEFS(Graph);
kpeter@731
   537
kpeter@731
   538
    checkConcept<ReadWriteMap<Node, int>,
kpeter@731
   539
                 CrossRefMap<Graph, Node, int> >();
kpeter@767
   540
    checkConcept<ReadWriteMap<Node, bool>,
kpeter@767
   541
                 CrossRefMap<Graph, Node, bool> >();
kpeter@767
   542
    checkConcept<ReadWriteMap<Node, double>,
kpeter@767
   543
                 CrossRefMap<Graph, Node, double> >();
alpar@956
   544
kpeter@731
   545
    Graph gr;
kpeter@731
   546
    typedef CrossRefMap<Graph, Node, char> CRMap;
kpeter@731
   547
    CRMap map(gr);
alpar@956
   548
kpeter@731
   549
    Node n0 = gr.addNode();
kpeter@731
   550
    Node n1 = gr.addNode();
kpeter@731
   551
    Node n2 = gr.addNode();
alpar@956
   552
kpeter@731
   553
    map.set(n0, 'A');
kpeter@731
   554
    map.set(n1, 'B');
kpeter@731
   555
    map.set(n2, 'C');
alpar@956
   556
kpeter@767
   557
    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
kpeter@767
   558
          "Wrong CrossRefMap");
kpeter@767
   559
    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
kpeter@767
   560
          "Wrong CrossRefMap");
kpeter@767
   561
    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
kpeter@767
   562
          "Wrong CrossRefMap");
kpeter@767
   563
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
kpeter@767
   564
          "Wrong CrossRefMap::count()");
alpar@956
   565
kpeter@771
   566
    CRMap::ValueIt it = map.beginValue();
kpeter@767
   567
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
kpeter@767
   568
          it == map.endValue(), "Wrong value iterator");
alpar@956
   569
kpeter@731
   570
    map.set(n2, 'A');
kpeter@767
   571
kpeter@767
   572
    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
kpeter@767
   573
          "Wrong CrossRefMap");
kpeter@767
   574
    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
kpeter@767
   575
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
kpeter@767
   576
    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
kpeter@767
   577
          "Wrong CrossRefMap");
kpeter@767
   578
    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
kpeter@767
   579
          "Wrong CrossRefMap::count()");
kpeter@767
   580
kpeter@767
   581
    it = map.beginValue();
kpeter@767
   582
    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
kpeter@767
   583
          it == map.endValue(), "Wrong value iterator");
kpeter@767
   584
kpeter@731
   585
    map.set(n0, 'C');
kpeter@731
   586
kpeter@731
   587
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
kpeter@731
   588
          "Wrong CrossRefMap");
kpeter@731
   589
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
kpeter@731
   590
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
kpeter@731
   591
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
kpeter@767
   592
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
kpeter@767
   593
          "Wrong CrossRefMap::count()");
kpeter@731
   594
kpeter@767
   595
    it = map.beginValue();
kpeter@731
   596
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
kpeter@731
   597
          it == map.endValue(), "Wrong value iterator");
kpeter@159
   598
  }
alpar@25
   599
kpeter@731
   600
  // CrossRefMap
kpeter@731
   601
  {
alpar@742
   602
    typedef SmartDigraph Graph;
kpeter@731
   603
    DIGRAPH_TYPEDEFS(Graph);
kpeter@731
   604
kpeter@731
   605
    checkConcept<ReadWriteMap<Node, int>,
kpeter@731
   606
                 CrossRefMap<Graph, Node, int> >();
alpar@956
   607
kpeter@731
   608
    Graph gr;
kpeter@731
   609
    typedef CrossRefMap<Graph, Node, char> CRMap;
kpeter@731
   610
    typedef CRMap::ValueIterator ValueIt;
kpeter@731
   611
    CRMap map(gr);
alpar@956
   612
kpeter@731
   613
    Node n0 = gr.addNode();
kpeter@731
   614
    Node n1 = gr.addNode();
kpeter@731
   615
    Node n2 = gr.addNode();
alpar@956
   616
kpeter@731
   617
    map.set(n0, 'A');
kpeter@731
   618
    map.set(n1, 'B');
kpeter@731
   619
    map.set(n2, 'C');
kpeter@731
   620
    map.set(n2, 'A');
kpeter@731
   621
    map.set(n0, 'C');
kpeter@731
   622
kpeter@731
   623
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
kpeter@731
   624
          "Wrong CrossRefMap");
kpeter@731
   625
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
kpeter@731
   626
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
kpeter@731
   627
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
kpeter@731
   628
kpeter@731
   629
    ValueIt it = map.beginValue();
kpeter@731
   630
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
kpeter@731
   631
          it == map.endValue(), "Wrong value iterator");
kpeter@731
   632
  }
alpar@956
   633
deba@740
   634
  // Iterable bool map
deba@740
   635
  {
deba@740
   636
    typedef SmartGraph Graph;
deba@740
   637
    typedef SmartGraph::Node Item;
deba@740
   638
deba@740
   639
    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
kpeter@741
   640
    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
deba@740
   641
deba@740
   642
    const int num = 10;
deba@740
   643
    Graph g;
deba@740
   644
    std::vector<Item> items;
deba@740
   645
    for (int i = 0; i < num; ++i) {
deba@740
   646
      items.push_back(g.addNode());
deba@740
   647
    }
deba@740
   648
deba@740
   649
    Ibm map1(g, true);
deba@740
   650
    int n = 0;
deba@740
   651
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
deba@740
   652
      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
deba@740
   653
      ++n;
deba@740
   654
    }
deba@740
   655
    check(n == num, "Wrong number");
deba@740
   656
deba@740
   657
    n = 0;
deba@740
   658
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
deba@740
   659
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
deba@740
   660
        ++n;
deba@740
   661
    }
deba@740
   662
    check(n == num, "Wrong number");
deba@740
   663
    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
deba@740
   664
    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
deba@740
   665
deba@740
   666
    map1[items[5]] = true;
deba@740
   667
deba@740
   668
    n = 0;
deba@740
   669
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
deba@740
   670
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
deba@740
   671
        ++n;
deba@740
   672
    }
deba@740
   673
    check(n == num, "Wrong number");
deba@740
   674
deba@740
   675
    map1[items[num / 2]] = false;
deba@740
   676
    check(map1[items[num / 2]] == false, "Wrong map value");
deba@740
   677
deba@740
   678
    n = 0;
deba@740
   679
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
deba@740
   680
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
deba@740
   681
        ++n;
deba@740
   682
    }
deba@740
   683
    check(n == num - 1, "Wrong number");
deba@740
   684
deba@740
   685
    n = 0;
deba@740
   686
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
deba@740
   687
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
deba@740
   688
        ++n;
deba@740
   689
    }
deba@740
   690
    check(n == 1, "Wrong number");
deba@740
   691
deba@740
   692
    map1[items[0]] = false;
deba@740
   693
    check(map1[items[0]] == false, "Wrong map value");
deba@740
   694
deba@740
   695
    map1[items[num - 1]] = false;
deba@740
   696
    check(map1[items[num - 1]] == false, "Wrong map value");
deba@740
   697
deba@740
   698
    n = 0;
deba@740
   699
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
deba@740
   700
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
deba@740
   701
        ++n;
deba@740
   702
    }
deba@740
   703
    check(n == num - 3, "Wrong number");
deba@740
   704
    check(map1.trueNum() == num - 3, "Wrong number");
deba@740
   705
deba@740
   706
    n = 0;
deba@740
   707
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
deba@740
   708
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
deba@740
   709
        ++n;
deba@740
   710
    }
deba@740
   711
    check(n == 3, "Wrong number");
deba@740
   712
    check(map1.falseNum() == 3, "Wrong number");
deba@740
   713
  }
deba@740
   714
deba@740
   715
  // Iterable int map
deba@740
   716
  {
deba@740
   717
    typedef SmartGraph Graph;
deba@740
   718
    typedef SmartGraph::Node Item;
deba@740
   719
    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
deba@740
   720
kpeter@741
   721
    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
deba@740
   722
deba@740
   723
    const int num = 10;
deba@740
   724
    Graph g;
deba@740
   725
    std::vector<Item> items;
deba@740
   726
    for (int i = 0; i < num; ++i) {
deba@740
   727
      items.push_back(g.addNode());
deba@740
   728
    }
deba@740
   729
deba@740
   730
    Iim map1(g);
deba@740
   731
    check(map1.size() == 0, "Wrong size");
deba@740
   732
deba@740
   733
    for (int i = 0; i < num; ++i) {
deba@740
   734
      map1[items[i]] = i;
deba@740
   735
    }
deba@740
   736
    check(map1.size() == num, "Wrong size");
deba@740
   737
deba@740
   738
    for (int i = 0; i < num; ++i) {
deba@740
   739
      Iim::ItemIt it(map1, i);
deba@740
   740
      check(static_cast<Item>(it) == items[i], "Wrong value");
deba@740
   741
      ++it;
deba@740
   742
      check(static_cast<Item>(it) == INVALID, "Wrong value");
deba@740
   743
    }
deba@740
   744
deba@740
   745
    for (int i = 0; i < num; ++i) {
deba@740
   746
      map1[items[i]] = i % 2;
deba@740
   747
    }
deba@740
   748
    check(map1.size() == 2, "Wrong size");
deba@740
   749
deba@740
   750
    int n = 0;
deba@740
   751
    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
kpeter@741
   752
      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
deba@740
   753
      ++n;
deba@740
   754
    }
deba@740
   755
    check(n == (num + 1) / 2, "Wrong number");
deba@740
   756
deba@740
   757
    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
kpeter@741
   758
      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
deba@740
   759
      ++n;
deba@740
   760
    }
deba@740
   761
    check(n == num, "Wrong number");
deba@740
   762
deba@740
   763
  }
deba@740
   764
deba@740
   765
  // Iterable value map
deba@740
   766
  {
deba@740
   767
    typedef SmartGraph Graph;
deba@740
   768
    typedef SmartGraph::Node Item;
deba@740
   769
    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
deba@740
   770
deba@740
   771
    checkConcept<ReadWriteMap<Item, double>, Ivm>();
deba@740
   772
deba@740
   773
    const int num = 10;
deba@740
   774
    Graph g;
deba@740
   775
    std::vector<Item> items;
deba@740
   776
    for (int i = 0; i < num; ++i) {
deba@740
   777
      items.push_back(g.addNode());
deba@740
   778
    }
deba@740
   779
deba@740
   780
    Ivm map1(g, 0.0);
deba@740
   781
    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
deba@740
   782
    check(*map1.beginValue() == 0.0, "Wrong value");
deba@740
   783
deba@740
   784
    for (int i = 0; i < num; ++i) {
deba@740
   785
      map1.set(items[i], static_cast<double>(i));
deba@740
   786
    }
deba@740
   787
    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
deba@740
   788
deba@740
   789
    for (int i = 0; i < num; ++i) {
deba@740
   790
      Ivm::ItemIt it(map1, static_cast<double>(i));
deba@740
   791
      check(static_cast<Item>(it) == items[i], "Wrong value");
deba@740
   792
      ++it;
deba@740
   793
      check(static_cast<Item>(it) == INVALID, "Wrong value");
deba@740
   794
    }
deba@740
   795
kpeter@771
   796
    for (Ivm::ValueIt vit = map1.beginValue();
deba@740
   797
         vit != map1.endValue(); ++vit) {
deba@740
   798
      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
kpeter@771
   799
            "Wrong ValueIt");
deba@740
   800
    }
deba@740
   801
deba@740
   802
    for (int i = 0; i < num; ++i) {
deba@740
   803
      map1.set(items[i], static_cast<double>(i % 2));
deba@740
   804
    }
deba@740
   805
    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
deba@740
   806
deba@740
   807
    int n = 0;
deba@740
   808
    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
kpeter@741
   809
      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
deba@740
   810
      ++n;
deba@740
   811
    }
deba@740
   812
    check(n == (num + 1) / 2, "Wrong number");
deba@740
   813
deba@740
   814
    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
kpeter@741
   815
      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
deba@740
   816
      ++n;
deba@740
   817
    }
deba@740
   818
    check(n == num, "Wrong number");
deba@740
   819
deba@740
   820
  }
alpar@956
   821
kpeter@836
   822
  // Graph map utilities:
kpeter@836
   823
  // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
kpeter@836
   824
  // mapFind(), mapFindIf(), mapCount(), mapCountIf()
kpeter@836
   825
  // mapCopy(), mapCompare(), mapFill()
kpeter@836
   826
  {
kpeter@836
   827
    DIGRAPH_TYPEDEFS(SmartDigraph);
kpeter@836
   828
kpeter@836
   829
    SmartDigraph g;
kpeter@836
   830
    Node n1 = g.addNode();
kpeter@836
   831
    Node n2 = g.addNode();
kpeter@836
   832
    Node n3 = g.addNode();
alpar@956
   833
kpeter@836
   834
    SmartDigraph::NodeMap<int> map1(g);
kpeter@836
   835
    SmartDigraph::ArcMap<char> map2(g);
kpeter@836
   836
    ConstMap<Node, A> cmap1 = A();
kpeter@836
   837
    ConstMap<Arc, C> cmap2 = C(0);
alpar@956
   838
kpeter@836
   839
    map1[n1] = 10;
kpeter@836
   840
    map1[n2] = 5;
kpeter@836
   841
    map1[n3] = 12;
alpar@956
   842
kpeter@836
   843
    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
kpeter@836
   844
    check(mapMin(g, map1) == n2, "Wrong mapMin()");
kpeter@836
   845
    check(mapMax(g, map1) == n3, "Wrong mapMax()");
kpeter@836
   846
    check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
kpeter@836
   847
    check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
kpeter@836
   848
    check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
kpeter@836
   849
    check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
kpeter@836
   850
kpeter@836
   851
    check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
kpeter@836
   852
    check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
kpeter@836
   853
kpeter@836
   854
    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
kpeter@836
   855
    check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
kpeter@836
   856
kpeter@836
   857
    Arc a1 = g.addArc(n1, n2);
kpeter@836
   858
    Arc a2 = g.addArc(n1, n3);
kpeter@836
   859
    Arc a3 = g.addArc(n2, n3);
kpeter@836
   860
    Arc a4 = g.addArc(n3, n1);
alpar@956
   861
kpeter@836
   862
    map2[a1] = 'b';
kpeter@836
   863
    map2[a2] = 'a';
kpeter@836
   864
    map2[a3] = 'b';
kpeter@836
   865
    map2[a4] = 'c';
kpeter@836
   866
kpeter@836
   867
    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
kpeter@836
   868
    check(mapMin(g, map2) == a2, "Wrong mapMin()");
kpeter@836
   869
    check(mapMax(g, map2) == a4, "Wrong mapMax()");
kpeter@836
   870
    check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
kpeter@836
   871
    check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
kpeter@836
   872
    check(mapMinValue(g, map2, std::greater<int>()) == 'c',
kpeter@836
   873
          "Wrong mapMinValue()");
kpeter@836
   874
    check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
kpeter@836
   875
          "Wrong mapMaxValue()");
kpeter@836
   876
kpeter@836
   877
    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
kpeter@836
   878
    check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
kpeter@836
   879
    check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
kpeter@836
   880
kpeter@836
   881
    check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
kpeter@836
   882
          "Wrong mapMin()");
kpeter@836
   883
    check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
kpeter@836
   884
          "Wrong mapMax()");
kpeter@836
   885
    check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
kpeter@836
   886
          "Wrong mapMinValue()");
kpeter@836
   887
    check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
kpeter@836
   888
          "Wrong mapMaxValue()");
kpeter@836
   889
kpeter@836
   890
    // mapFind(), mapFindIf()
kpeter@836
   891
    check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
kpeter@836
   892
    check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
kpeter@836
   893
    check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
kpeter@836
   894
    check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
kpeter@836
   895
    check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
kpeter@836
   896
    check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
kpeter@836
   897
kpeter@836
   898
    check(mapFindIf(g, map1, Less<int>(7)) == n2,
kpeter@836
   899
          "Wrong mapFindIf()");
kpeter@836
   900
    check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
kpeter@836
   901
          "Wrong mapFindIf()");
kpeter@836
   902
    check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
kpeter@836
   903
          "Wrong mapFindIf()");
kpeter@836
   904
    check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
kpeter@836
   905
          "Wrong mapFindIf()");
kpeter@836
   906
kpeter@836
   907
    // mapCount(), mapCountIf()
kpeter@836
   908
    check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
kpeter@836
   909
    check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
kpeter@836
   910
    check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
kpeter@836
   911
    check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
kpeter@836
   912
    check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
kpeter@836
   913
    check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
kpeter@836
   914
    check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
kpeter@836
   915
kpeter@836
   916
    check(mapCountIf(g, map1, Less<int>(11)) == 2,
kpeter@836
   917
          "Wrong mapCountIf()");
kpeter@836
   918
    check(mapCountIf(g, map1, Less<int>(13)) == 3,
kpeter@836
   919
          "Wrong mapCountIf()");
kpeter@836
   920
    check(mapCountIf(g, map1, Less<int>(5)) == 0,
kpeter@836
   921
          "Wrong mapCountIf()");
kpeter@836
   922
    check(mapCountIf(g, map2, Less<char>('d')) == 4,
kpeter@836
   923
          "Wrong mapCountIf()");
kpeter@836
   924
    check(mapCountIf(g, map2, Less<char>('c')) == 3,
kpeter@836
   925
          "Wrong mapCountIf()");
kpeter@836
   926
    check(mapCountIf(g, map2, Less<char>('a')) == 0,
kpeter@836
   927
          "Wrong mapCountIf()");
alpar@956
   928
kpeter@836
   929
    // MapIt, ConstMapIt
kpeter@836
   930
/*
kpeter@836
   931
These tests can be used after applying bugfix #330
kpeter@836
   932
    typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
kpeter@836
   933
    typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
kpeter@836
   934
    check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
kpeter@836
   935
          "Wrong NodeMap<>::MapIt");
kpeter@836
   936
    check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
kpeter@836
   937
          "Wrong NodeMap<>::MapIt");
alpar@956
   938
kpeter@836
   939
    int sum = 0;
kpeter@836
   940
    std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
kpeter@836
   941
    check(sum == 27, "Wrong NodeMap<>::MapIt");
kpeter@836
   942
    std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
kpeter@836
   943
    check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
kpeter@836
   944
*/
kpeter@836
   945
kpeter@836
   946
    // mapCopy(), mapCompare(), mapFill()
kpeter@836
   947
    check(mapCompare(g, map1, map1), "Wrong mapCompare()");
kpeter@836
   948
    check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
kpeter@836
   949
    check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
kpeter@836
   950
    check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
kpeter@836
   951
    check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
kpeter@836
   952
kpeter@836
   953
    SmartDigraph::NodeMap<int> map3(g, 0);
kpeter@836
   954
    SmartDigraph::ArcMap<char> map4(g, 'a');
alpar@956
   955
kpeter@836
   956
    check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
alpar@956
   957
    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
alpar@956
   958
kpeter@836
   959
    mapCopy(g, map1, map3);
kpeter@836
   960
    mapCopy(g, map2, map4);
kpeter@836
   961
kpeter@836
   962
    check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
alpar@956
   963
    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
alpar@956
   964
kpeter@836
   965
    Undirector<SmartDigraph> ug(g);
kpeter@836
   966
    Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
kpeter@836
   967
    Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
alpar@956
   968
kpeter@836
   969
    check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
kpeter@836
   970
    check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
kpeter@836
   971
    check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
kpeter@836
   972
    check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
alpar@956
   973
kpeter@836
   974
    mapCopy(g, map2, umap1);
kpeter@836
   975
kpeter@836
   976
    check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
kpeter@836
   977
    check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
kpeter@836
   978
    check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
kpeter@836
   979
    check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
alpar@956
   980
kpeter@836
   981
    mapCopy(g, map2, umap1);
kpeter@836
   982
    mapCopy(g, umap1, map2);
kpeter@836
   983
    mapCopy(ug, map2, umap1);
kpeter@836
   984
    mapCopy(ug, umap1, map2);
alpar@956
   985
kpeter@836
   986
    check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
kpeter@836
   987
    mapCopy(ug, umap1, umap2);
kpeter@836
   988
    check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
alpar@956
   989
kpeter@836
   990
    check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
kpeter@836
   991
    mapFill(g, map1, 2);
kpeter@836
   992
    check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
kpeter@836
   993
kpeter@836
   994
    check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
kpeter@836
   995
    mapCopy(g, constMap<Arc>('z'), map2);
kpeter@836
   996
    check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
kpeter@836
   997
  }
alpar@956
   998
alpar@25
   999
  return 0;
alpar@25
  1000
}