#ifndef TMP_DEBUG_H #define TMP_DEBUG_H /** * @file tmp/debug.h * @brief compile-time typename to string resolution * * see: https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c * see: https://stackoverflow.com/a/20170989 * * Adapted, minimal C++ version supported is C++14 */ #include #include "stringview.h" namespace tmp { namespace detail { constexpr unsigned strlen(char const*str) { unsigned l = 0; while(*str++) ++l; return l; } } /** * @brief compile-time typename to string resolution * * @param[in] T type to resolve * * @return constexpr string_view containing the typename * * TODO this function has not been tested for Windows */ template constexpr string_view typeName() { #if defined(__clang__) string_view p = __PRETTY_FUNCTION__; constexpr auto leftDummy = detail::strlen("tmp::string_view tmp::typeName() [T = "); constexpr auto rightDummy = detail::strlen("]"); #elif defined(__GNUC__) string_view p = __PRETTY_FUNCTION__; constexpr auto leftDummy = detail::strlen("constexpr tmp::string_view tmp::typeName() [with T = "); constexpr auto rightDummy = detail::strlen("]"); #elif defined(_MSC_VER) string_view p = __FUNCSIG__; constexpr auto leftDummy = detail::strlen(""); constexpr auto rightDummy = detail::strlen(""); #else return {"[err: tmp::typeNameF is not implemented for your compiler]"}; #endif #if defined(__clang__) || defined(__GNUC__) || defined(__MSC_VER) return string_view(p.data() + leftDummy, p.size() - leftDummy - rightDummy); #endif } template std::string strTypes(Ts...) { using Fold = int[]; std::string result; static_cast(Fold{(result += std::string{typeName()} + ", ", 0)...}); static_cast(Fold{(result += std::string{typeName()} + ", ", 0)...}); if(result.empty()) return ""; else return result.substr(0, result.size()-2); } template void printTypes(Ts...) { std::puts(strTypes().c_str()); } } #endif