diff --git a/test_has_method.cpp b/test_has_method.cpp new file mode 100644 index 0000000..7c050e4 --- /dev/null +++ b/test_has_method.cpp @@ -0,0 +1,222 @@ +/* Check cf5-opt.vim defs. +VIM: let g:lcppflags="-std=c++11 -O2 -pthread" +VIM: let g:wcppflags="/O2 /EHsc /DWIN32" +VIM: let g:cppflags=g:Iboost.g:Itbb +VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy +VIM: let g:ldlibpath=g:Bboost.g:Btbb +VIM: let g:argv="" +VIM-: let g:cf5output=0 +*/ +#include +#include +#include +#include +#include + +struct A +{ + void touch( const char * ) + { + std::cout << "A::touch"; + } +}; + +struct B +{ +}; + +struct C : public A +{ +}; + +struct D +{ + void touch( int ) + { + std::cout << "D::touch"; + } +}; + + +struct call_touch +{ + template + struct has_touch + { + template + class helper{}; + template + static int test(T*, helper* = 0); + template + static char test(...); + + static const bool value = sizeof(test(0))!=sizeof(char); + }; + + template + static + typename std::enable_if::value,void>::type + touch( S * s, const char * p) + { + std::cout << "call_touch: calling -> "; + return s->touch(p); + } + + static void touch(...) + { + std::cout << "call_touch: no method to call"; + } +}; + +struct call_touch2 +{ + template + static void touch( S * s, const char * p, decltype(&S::touch)* =0) + { + std::cout << "call_touch2: calling -> "; + return s->touch(p); + } + + static void touch(...) + { + std::cout << "call_touch2: no method to call"; + } +}; + +struct call_touch3 +{ + template + class helper{}; + + template + static void touch( S * s, const char * p, helper* =0) + { + std::cout << "call_touch3: calling -> "; + return s->touch(p); + } + + static void touch(...) + { + std::cout << "call_touch3: no method to call"; + } +}; + +struct call_touch4 +{ + template + static decltype( ((S*)0)->touch((const char *)(0)) ) + touch( S * s, const char * p ) + { + std::cout << "call_touch4: calling -> "; + return s->touch(p); + } + + static void touch(...) + { + std::cout << "call_touch4: no method to call"; + } +}; + +int main ( void ) +{try{ + + A a; + B b; + C c; + D d; + + std::cout << std::endl; + std::cout << "test a: "; + call_touch::touch( &a, 0 ); + std::cout << std::endl; + + std::cout << "test b: "; + call_touch::touch( &b, 0 ); + std::cout << std::endl; + + std::cout << "test c: "; + call_touch::touch( &c, 0 ); + std::cout << std::endl; + + std::cout << "test d: "; + call_touch::touch( &d, 0 ); + std::cout << std::endl; + + + + std::cout << std::endl; + std::cout << "test a: "; + call_touch2::touch( &a, 0 ); + std::cout << std::endl; + + std::cout << "test b: "; + call_touch2::touch( &b, 0 ); + std::cout << std::endl; + + std::cout << "test c: "; + call_touch2::touch( &c, 0 ); + std::cout << std::endl; + +// Compiler error is generated. +// +// std::cout << "test d: "; +// call_touch2::touch( &d, 0 ); +// std::cout << std::endl; + + + + + std::cout << std::endl; + std::cout << "test a: "; + call_touch3::touch( &a, 0 ); + std::cout << std::endl; + + std::cout << "test b: "; + call_touch3::touch( &b, 0 ); + std::cout << std::endl; + + std::cout << "test c: "; + call_touch3::touch( &c, 0 ); + std::cout << std::endl; + + std::cout << "test d: "; + call_touch3::touch( &d, 0 ); + std::cout << std::endl; + + + + std::cout << std::endl; + std::cout << "test a: "; + call_touch4::touch( &a, 0 ); + std::cout << std::endl; + + std::cout << "test b: "; + call_touch4::touch( &b, 0 ); + std::cout << std::endl; + + std::cout << "test c: "; + call_touch4::touch( &c, 0 ); + std::cout << std::endl; + + std::cout << "test d: "; + call_touch4::touch( &d, 0 ); + std::cout << std::endl; + + + + + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; +}} +