A demonstration how to use _optional_ boolean tags.
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 +}