Skip to content

Instantly share code, notes, and snippets.

@haseeb-heaven
Created June 16, 2022 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haseeb-heaven/d6093f68d160b92ba1c69ccd9df7ec80 to your computer and use it in GitHub Desktop.
Save haseeb-heaven/d6093f68d160b92ba1c69ccd9df7ec80 to your computer and use it in GitHub Desktop.
C++ Data type resolve in Compile-Time using T-Template and Runtime using TypeId.
/*
Info: C++ Data type resolve in Compile-Time using T-Template and RunTime using TypeId.
Author: Haseeb Mir @2022.
*/
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <typeinfo>
#include <string_view>
#include <array> // std::array
#include <utility> // std::index_sequence
using std::string;
template <std::size_t...Idxs>
constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>)
{
return std::array{str[Idxs]..., '\n'};
}
template <typename T>
constexpr auto type_name_array()
{
#if defined(__clang__)
constexpr auto prefix = std::string_view{"[T = "};
constexpr auto suffix = std::string_view{"]"};
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
#elif defined(__GNUC__)
constexpr auto prefix = std::string_view{"with T = "};
constexpr auto suffix = std::string_view{"]"};
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
#elif defined(_MSC_VER)
constexpr auto prefix = std::string_view{"type_name_array<"};
constexpr auto suffix = std::string_view{">(void)"};
constexpr auto function = std::string_view{__FUNCSIG__};
#else
# error Unsupported compiler
#endif
constexpr auto start = function.find(prefix) + prefix.size();
constexpr auto end = function.rfind(suffix);
static_assert(start < end);
constexpr auto name = function.substr(start, (end - start));
return substring_as_array(name, std::make_index_sequence<name.size()>{});
}
template <typename T>
struct type_name_holder {
static inline constexpr auto value = type_name_array<T>();
};
template <typename T>
constexpr auto type_name() -> std::string_view
{
constexpr auto& value = type_name_holder<T>::value;
return std::string_view{value.data(), value.size()};
}
template <typename T>
void PrintDataType(T type)
{
auto name = typeid(type).name();
string cmd_str = "echo '" + string(name) + "' | c++filt -t";
system(cmd_str.c_str());
}
// Main Code
int main()
{
//Dynamic resolution.
std::map<int, int> iMap;
PrintDataType(iMap);
//Compile type resolution.
std::cout << type_name<std::list<int>>() << std::endl;
return 0;
}
@haseeb-heaven
Copy link
Author

Output

std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >
std::__cxx11::list<int>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment