Last active
December 25, 2022 08:49
-
-
Save niXman/febe1fe53c7d98693f284a0e1a9ba063 to your computer and use it in GitHub Desktop.
constexpr type_name()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <array> | |
#include <utility> | |
#include <string_view> | |
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 double_colon = std::string_view{"::"}; | |
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)); | |
constexpr auto double_colon_pos = name.find(double_colon); | |
if constexpr ( double_colon_pos != std::string_view::npos ) { | |
constexpr auto name2 = name.substr(double_colon_pos + double_colon.size() | |
,end - (double_colon_pos + double_colon.size())); | |
return substring_as_array(name2, std::make_index_sequence<name2.size()>{}); | |
} | |
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()}; | |
} | |
int main() | |
{ | |
std::cout << type_name<int>() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment