#include <cxxabi.h>
#include <string>
#include <typeinfo>
#include <cassert>
#include <cstdlib>
#include <iostream>

const std::string demangle(const char* const mangledTypeName) {
   int resultStatus = -4;
   const char* const result = abi::__cxa_demangle( mangledTypeName, 0, 0, &resultStatus );
   std::string demangledTypeName;
   const bool noError = (0 == resultStatus);
   const bool demangledSuccess = (noError && result != 0);
   assert(demangledSuccess);
   demangledTypeName = (demangledSuccess ? result : "Unknown type.");
   free(const_cast<char*>(result));
   return demangledTypeName;
}

const std::string demangle(const std::string& mangledTypeName) {
   return demangle(mangledTypeName.c_str());
}

const std::string demangledNameOfType(const std::type_info& type_id) {
   return demangle(type_id.name());
}

#define DEMANGLED_NAME_OF_TYPE(TypeOrValue) (demangledNameOfType(typeid(TypeOrValue)))
#define PRINT_NAME_OF_TYPE(TypeOrValue) {std::cout<<DEMANGLED_NAME_OF_TYPE(TypeOrValue)<<std::endl;}


int main()
{
	PRINT_NAME_OF_TYPE(1)
	PRINT_NAME_OF_TYPE(1.)
	PRINT_NAME_OF_TYPE(1.f)
	PRINT_NAME_OF_TYPE(1L)
	PRINT_NAME_OF_TYPE(1LL)
	PRINT_NAME_OF_TYPE(1U)
	PRINT_NAME_OF_TYPE("1")
}
