author | marci |
Thu, 17 Feb 2005 15:14:13 +0000 | |
changeset 1153 | 4b0468de3a31 |
permissions | -rw-r--r-- |
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 |
} |