A demonstration how to use _optional_ boolean tags.
authorklao
Wed, 10 Nov 2004 19:59:14 +0000
changeset 97604591f9a4173
parent 975 12b9993b217c
child 977 48962802d168
A demonstration how to use _optional_ boolean tags.
src/work/klao/Makefile
src/work/klao/tag_demo.cc
     1.1 --- a/src/work/klao/Makefile	Wed Nov 10 12:51:30 2004 +0000
     1.2 +++ b/src/work/klao/Makefile	Wed Nov 10 19:59:14 2004 +0000
     1.3 @@ -1,4 +1,4 @@
     1.4 -BINARIES = path_test map_test iter_map_test
     1.5 -INCLUDEDIRS= -I. -I.. -I../.. -I../{marci,jacint,alpar,johanna,athos,akos}
     1.6 +BINARIES = tag_demo
     1.7 +INCLUDEDIRS= -I. -I.. -I../.. -I../{marci,jacint,alpar,johanna,athos,akos} -I$(HOME)/boost
     1.8  include ../makefile
     1.9  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/work/klao/tag_demo.cc	Wed Nov 10 19:59:14 2004 +0000
     2.3 @@ -0,0 +1,95 @@
     2.4 +#include <iostream>
     2.5 +#include <boost/utility.hpp>
     2.6 +
     2.7 +using namespace std;
     2.8 +using namespace boost;
     2.9 +
    2.10 +struct True {
    2.11 +  static const bool value = true;
    2.12 +};
    2.13 +struct False {
    2.14 +  static const bool value = false;
    2.15 +};
    2.16 +
    2.17 +// Here are some graph structures. Some of them define the type "OneTag"
    2.18 +// to True or False, some does not. Not defining a tag is (or at least
    2.19 +// should be) equivalent to defining it to "False".
    2.20 +struct Graph1 {};
    2.21 +struct Graph2 {
    2.22 +  typedef True OneTag;
    2.23 +};
    2.24 +struct Graph3 {
    2.25 +  typedef False OneTag;
    2.26 +};
    2.27 +
    2.28 +
    2.29 +/**************** The first method to use tags ****************/
    2.30 +
    2.31 +template <typename Graph, typename Enable = void>
    2.32 +struct HasOneTag {
    2.33 +  typedef False TheTag;
    2.34 +};
    2.35 +
    2.36 +// specialization for those graphs which defined the tag to be true:
    2.37 +template <typename Graph>
    2.38 +struct HasOneTag<Graph, typename enable_if<typename Graph::OneTag>::type > {
    2.39 +  typedef True TheTag;
    2.40 +};
    2.41 +
    2.42 +template <typename Graph>
    2.43 +int cn1(const Graph &, False) {
    2.44 +  return 0;
    2.45 +}
    2.46 +
    2.47 +template <typename Graph>
    2.48 +int cn1(const Graph &, True) {
    2.49 +  return 1;
    2.50 +}
    2.51 +
    2.52 +template <typename Graph>
    2.53 +int cn1(const Graph &g) {
    2.54 +  return cn1(g, typename HasOneTag<Graph>::TheTag());
    2.55 +}
    2.56 +
    2.57 +/**************** The second method ****************/
    2.58 +
    2.59 +// An artificial type to provoke a conversion to avoid ambuguity...
    2.60 +template <typename T>
    2.61 +struct Wrap {
    2.62 +  const T &value;
    2.63 +  Wrap(const T &t) : value(t) {}
    2.64 +};
    2.65 +
    2.66 +template <typename Graph>
    2.67 +typename enable_if<typename Graph::OneTag, int>::type
    2.68 +_cn2(const Graph &) {
    2.69 +  return 1;
    2.70 +}
    2.71 +
    2.72 +template <typename Graph>
    2.73 +int _cn2(Wrap<Graph>) {
    2.74 +  return 0;
    2.75 +}
    2.76 +
    2.77 +template <typename Graph>
    2.78 +int cn2(const Graph& g) {
    2.79 +  return _cn2<Graph>(g);
    2.80 +}
    2.81 +
    2.82 +
    2.83 +int main() {
    2.84 +  Graph1 g1;
    2.85 +  Graph2 g2;
    2.86 +  Graph3 g3;
    2.87 +
    2.88 +  cout << "The first method:\n";
    2.89 +  cout << "G1: " << cn1(g1) << endl;
    2.90 +  cout << "G2: " << cn1(g2) << endl;
    2.91 +  cout << "G3: " << cn1(g3) << endl;
    2.92 +
    2.93 +  cout << "The second method:\n";
    2.94 +  cout << "G1: " << cn2(g1) << endl;
    2.95 +  cout << "G2: " << cn2(g2) << endl;
    2.96 +  cout << "G3: " << cn2(g3) << endl;
    2.97 +
    2.98 +}