79 lines
2.0 KiB
C++
79 lines
2.0 KiB
C++
#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 <cstdio>
|
|
#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<typename T>
|
|
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<typename... As, typename... Ts>
|
|
std::string strTypes(Ts...) {
|
|
using Fold = int[];
|
|
std::string result;
|
|
static_cast<void>(Fold{(result += std::string{typeName<As>()} + ", ", 0)...});
|
|
static_cast<void>(Fold{(result += std::string{typeName<Ts>()} + ", ", 0)...});
|
|
if(result.empty()) return "";
|
|
else return result.substr(0, result.size()-2);
|
|
}
|
|
|
|
template<typename... As, typename... Ts>
|
|
void printTypes(Ts...) {
|
|
std::puts(strTypes<As..., Ts...>().c_str());
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|