diff --git a/src/lib/meta/function-erasure.hpp b/src/lib/meta/function-erasure.hpp index 0696b6a42..664e49e20 100644 --- a/src/lib/meta/function-erasure.hpp +++ b/src/lib/meta/function-erasure.hpp @@ -93,7 +93,24 @@ namespace typelist{ /* ====== Policy classes ====== */ - + + template + struct BoolCheckable + { + typedef bool (T::*ValidityCheck)() const; + typedef ValidityCheck _unspecified_bool_type; + ValidityCheck isValid; + + BoolCheckable() : isValid (&T::isValid) {} + + /** implicit conversion to "bool" */ + operator _unspecified_bool_type() const { T const& obj = *this; + return (obj.*isValid)()? isValid : 0; } // never throws + bool operator! () const { T const& obj = *this; + return !(obj.*isValid)(); } // ditto + + }; + /** * Policy for FunErasure: store an embedded tr1::function * Using this policy allows to store arbitrary complex functor objects @@ -101,6 +118,7 @@ namespace typelist{ * The price to pay is vtable access and heap storage of function arguments. */ class StoreFunction +// : public BoolCheckable { /** Helper: type erasure */ struct Holder @@ -155,6 +173,12 @@ namespace typelist{ REQUIRE (INSTANCEOF (FunctionHolder, &holder_)); return static_cast&> (holder_).get(); } + + bool + isValid() const + { + return reinterpret_cast (holder_.storage_[0]); + } }; diff --git a/src/tool/try.cpp b/src/tool/try.cpp index d6b3a95b9..78ba1d0aa 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -12,16 +12,20 @@ // 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible // 7/08 - combining partial specialisation and subclasses // 10/8 - abusing the STL containers to hold noncopyable values +// 6/09 - investigating how to build a mixin template providing an operator bool() #include //#include "include/nobugcfg.h" +#include "lib/meta/function-erasure.hpp" #include //#include #include -//#include +#include + +using std::rand; using std::string; using std::cout; using boost::format; @@ -32,6 +36,24 @@ using boost::format; long checksum = 0; } + struct TestIt1 + : lumiera::typelist::BoolCheckable + { + + int val_; + + TestIt1 (int v = (rand() % 10)) + : val_(v) + { } + + bool + isValid() const + { + return true; + } + + }; + int @@ -39,13 +61,15 @@ main (int argc, char* argv[]) { NOBUG_INIT; + + TestIt1 testrosteron (22); + + bool boo = true; //testrosteron; + if (!boo) + return -1; cout << "\n.gulp.\n"; - - int * p = 0; - - int oh = *p; - + return 0; }