// extern "C" not handled #include #include #include template struct Printtype; template<> struct Printtype<> { std::string name() { return ""; } }; template struct Printtype { std::string name(std::string append="") { return typeid(T).name()+append; } }; template struct Printtype { std::string name() { return Printtype().name()+","+Printtype().name(); } }; #define BASIC_TYPE(X) \ template<> struct Printtype { \ std::string name(std::string append="") { \ return std::string( #X )+append; \ } \ } BASIC_TYPE(void); BASIC_TYPE(bool); BASIC_TYPE(char); BASIC_TYPE(signed char); BASIC_TYPE(unsigned char); BASIC_TYPE(short); BASIC_TYPE(unsigned short); BASIC_TYPE(int); BASIC_TYPE(unsigned); BASIC_TYPE(long); BASIC_TYPE(unsigned long); BASIC_TYPE(long long); BASIC_TYPE(unsigned long long); BASIC_TYPE(float); BASIC_TYPE(double); BASIC_TYPE(long double); BASIC_TYPE(wchar_t); BASIC_TYPE(char16_t); BASIC_TYPE(char32_t); #undef BASIC_TYPE #define SUFFIX(X,Y) \ template struct Printtype { \ std::string name(std::string append="") { \ return Printtype().name( Y +append); \ } \ } #define SUFFIX1(X) SUFFIX(X, #X ) #define SUFFIX2(X) SUFFIX(X, " " #X ) SUFFIX1(*); SUFFIX1(&); SUFFIX1(&&); SUFFIX2(const); SUFFIX2(volatile); SUFFIX2(const volatile); #undef SUFFIX #undef SUFFIX1 #undef SUFFIX2 std::string eatspace(std::string s){ if(!s.empty() && s[0]==' ') s.erase(0,1); return s; } template struct Printtype { std::string name(std::string append="") { return Printtype().name( (append.empty()?append:("("+eatspace(append)+")"))+ "("+Printtype().name()+")"); } }; template struct Printtype { std::string name(std::string append="") { std::string args=Printtype().name(); if(!args.empty()) args+=","; args+="..."; return Printtype().name( (append.empty()?append:("("+eatspace(append)+")"))+ "("+args+")"); } }; template struct Printtype { std::string name(std::string append="") { return Printtype().name(" "+ Printtype().name()+"::*"+append); } }; namespace { template::value> struct Print_from_array:Printtype{}; template struct Print_from_array{ std::string name(std::string append="") { return Printtype().name(append,true); } }; template struct Printarraytype { std::string name(std::string append,bool fromarray,std::string dim) { return Print_from_array().name( ((append.empty()||fromarray)?append:("("+eatspace(append)+")"))+ "[" + dim + "]"); } }; } template struct Printtype { std::string name(std::string append="",bool fromarray=false) { return Printarraytype().name(append,fromarray,""); } }; template struct Printtype { std::string name(std::string append="",bool fromarray=false) { return Printarraytype().name(append,fromarray,std::to_string(d)); } }; #include struct Perso{}; typedef int (*fun)(double); typedef Perso Tab[3][5][7]; typedef fun fun2(Tab*&); typedef fun2** T2[9]; typedef Tab Perso::*U; int main(){ std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; std::cout << Printtype().name() << std::endl; } // FIXME: const char[] is ambiguous!