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