src/work/klao/tag_demo.cc
author marci
Thu, 17 Feb 2005 15:14:13 +0000
changeset 1153 4b0468de3a31
permissions -rw-r--r--
if you have a nuclear power plant and wanna compute small magic squares, then let's do it
klao@976
     1
#include <iostream>
klao@976
     2
#include <boost/utility.hpp>
klao@976
     3
klao@976
     4
using namespace std;
klao@976
     5
using namespace boost;
klao@976
     6
klao@976
     7
struct True {
klao@976
     8
  static const bool value = true;
klao@976
     9
};
klao@976
    10
struct False {
klao@976
    11
  static const bool value = false;
klao@976
    12
};
klao@976
    13
klao@976
    14
// Here are some graph structures. Some of them define the type "OneTag"
klao@976
    15
// to True or False, some does not. Not defining a tag is (or at least
klao@976
    16
// should be) equivalent to defining it to "False".
klao@976
    17
struct Graph1 {};
klao@976
    18
struct Graph2 {
klao@976
    19
  typedef True OneTag;
klao@976
    20
};
klao@976
    21
struct Graph3 {
klao@976
    22
  typedef False OneTag;
klao@976
    23
};
klao@976
    24
klao@976
    25
klao@976
    26
/**************** The first method to use tags ****************/
klao@976
    27
klao@976
    28
template <typename Graph, typename Enable = void>
klao@976
    29
struct HasOneTag {
klao@976
    30
  typedef False TheTag;
klao@976
    31
};
klao@976
    32
klao@976
    33
// specialization for those graphs which defined the tag to be true:
klao@976
    34
template <typename Graph>
klao@976
    35
struct HasOneTag<Graph, typename enable_if<typename Graph::OneTag>::type > {
klao@976
    36
  typedef True TheTag;
klao@976
    37
};
klao@976
    38
klao@976
    39
template <typename Graph>
klao@976
    40
int cn1(const Graph &, False) {
klao@976
    41
  return 0;
klao@976
    42
}
klao@976
    43
klao@976
    44
template <typename Graph>
klao@976
    45
int cn1(const Graph &, True) {
klao@976
    46
  return 1;
klao@976
    47
}
klao@976
    48
klao@976
    49
template <typename Graph>
klao@976
    50
int cn1(const Graph &g) {
klao@976
    51
  return cn1(g, typename HasOneTag<Graph>::TheTag());
klao@976
    52
}
klao@976
    53
klao@976
    54
/**************** The second method ****************/
klao@976
    55
klao@976
    56
// An artificial type to provoke a conversion to avoid ambuguity...
klao@976
    57
template <typename T>
klao@976
    58
struct Wrap {
klao@976
    59
  const T &value;
klao@976
    60
  Wrap(const T &t) : value(t) {}
klao@976
    61
};
klao@976
    62
klao@976
    63
template <typename Graph>
klao@976
    64
typename enable_if<typename Graph::OneTag, int>::type
klao@976
    65
_cn2(const Graph &) {
klao@976
    66
  return 1;
klao@976
    67
}
klao@976
    68
klao@976
    69
template <typename Graph>
klao@976
    70
int _cn2(Wrap<Graph>) {
klao@976
    71
  return 0;
klao@976
    72
}
klao@976
    73
klao@976
    74
template <typename Graph>
klao@976
    75
int cn2(const Graph& g) {
klao@976
    76
  return _cn2<Graph>(g);
klao@976
    77
}
klao@976
    78
klao@976
    79
klao@976
    80
int main() {
klao@976
    81
  Graph1 g1;
klao@976
    82
  Graph2 g2;
klao@976
    83
  Graph3 g3;
klao@976
    84
klao@976
    85
  cout << "The first method:\n";
klao@976
    86
  cout << "G1: " << cn1(g1) << endl;
klao@976
    87
  cout << "G2: " << cn1(g2) << endl;
klao@976
    88
  cout << "G3: " << cn1(g3) << endl;
klao@976
    89
klao@976
    90
  cout << "The second method:\n";
klao@976
    91
  cout << "G1: " << cn2(g1) << endl;
klao@976
    92
  cout << "G2: " << cn2(g2) << endl;
klao@976
    93
  cout << "G3: " << cn2(g3) << endl;
klao@976
    94
klao@976
    95
}