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
 |