codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <string> #include <iostream> #include <boost/function.hpp> namespace detail { template<typename T> struct IsClassType { template<typename U> static char (& is(U *U::*) )[1]; template<typename U> static char (& is(...) )[2]; static bool const value = (sizeof is<T>(0) == 1); }; struct Marker { }; struct Detector { }; template<typename U> struct Detected { }; template<typename U> Detected<U> operator,(Detector, U const&); template<typename U> char (& operator,(Detected<U>, char(&)[2]) )[2]; char (& operator,(Detected<Marker>, char(&)[2]) )[1]; } #define IS_CALLABLE(N, ARGS, TNAME) \ template<typename T, \ bool IsClassType = detail::IsClassType<T>::value> \ struct TNAME##_hasN { \ struct D1 { void N(); }; \ struct D : D1, T { }; \ \ template<typename U, U> struct ChT; \ \ template<typename U> \ static char (& has(ChT<void (D1::*)(), &U::N>*) )[1]; \ \ template<typename U> \ static char (& has(...) )[2]; \ \ static bool const value = (sizeof has<D>(0) == 2); \ }; \ \ template<typename T> struct TNAME##_hasN<T, false> \ { static bool const value = false; }; \ \ template<typename T, bool HasIt = TNAME##_hasN<T>::value> \ struct TNAME { \ struct Fallback { detail::Marker N(...) const volatile; }; \ struct Derived : T, Fallback { \ using T::N; using Fallback::N; \ }; \ \ static bool const value = \ sizeof (detail::Detector(), \ (*(Derived*)0) ARGS, *(char(*)[2])0) \ == 2; \ }; \ \ template<typename T> struct TNAME<T, false> \ { static bool const value = false; } IS_CALLABLE(f, .f(""), CanCallF); // callable with .f("") IS_CALLABLE(f, .f(true), CanCallFb); // callable with .f(true) IS_CALLABLE(g, .g(""), CanCallG); // callable with .g("") IS_CALLABLE(c_str, .c_str(), CanCallCStr); // callable with .c_str() IS_CALLABLE(operator(), (true), CanCallB); // callable with (true) struct A { void f(std::string); }; struct B : A { }; int main() { std::cout << CanCallF<B>::value << std::endl << CanCallFb<B>::value << std::endl << CanCallG<B>::value << std::endl << CanCallCStr<const std::string>::value << std::endl << CanCallB< boost::function<void(bool)> >::value << std::endl << CanCallB< boost::function<void(bool*)> >::value << std::endl; }
Private
[
?
]
Run code
Submit