#include <iostream>
#include <string>

#include <typeinfo>
#include <cstdlib>
#include <memory>
#include <cxxabi.h>

template <typename T> std::string TypeName(const T &)
{
	auto name = typeid(T).name();
	int status = -4;
	std::unique_ptr<char, void(*)(void*)> res {
		abi::__cxa_demangle(name, NULL, NULL, &status),
		std::free
	};
    return (status==0) ? res.get() : name ;
}

template <typename char_type, size_t LENGTH>
std::basic_string<char_type> literal(const char (&value)[LENGTH])
{
	using string = std::basic_string<char_type>;

	string result{};
	result.reserve(LENGTH);

	std::copy(std::begin(value), std::end(value), std::back_inserter(result));

	return result;
}

int main()
{
	std::cout << TypeName(literal<char>("test")) << '\n';
	std::cout << TypeName(literal<char32_t>("test")) << '\n';
	std::cout << TypeName(literal<char16_t>("test")) << '\n';

	return 0;
}