Created
October 30, 2025 09:12
-
-
Save varqox/cf37e7a314130881fb7580d52f29641a to your computer and use it in GitHub Desktop.
C++: type to ptr and name mapping that is unambiguous
This file contains hidden or 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 <type_traits> | |
| #include <vector> | |
| #include <utility> | |
| #include <array> | |
| #include <string_view> | |
| #include <cstddef> | |
| #include <unistd.h> | |
| #include <cstdio> | |
| using namespace std; | |
| static bool x = []{ | |
| string s = "athausioethunaohesuaot"; | |
| dprintf(STDERR_FILENO, "initializing x\n"); | |
| // std::cerr << "initializing x" << std::endl; | |
| return false; | |
| }(); | |
| #pragma GCC diagnostic push | |
| #pragma clang diagnostic ignored "-Wunknown-warning-option" | |
| #pragma GCC diagnostic ignored "-Wprio-ctor-dtor" | |
| __attribute__((constructor(0))) int foo(int argc, char** argv) { | |
| string s = "athausioethunaohesuaot"; | |
| dprintf(STDERR_FILENO, "initializing foo\n"); | |
| try { | |
| throw 42; | |
| } catch (int) { | |
| } | |
| dprintf(STDERR_FILENO, "%i: %s\n", argc, argv[0]); | |
| // std::cerr << "some message" << std::endl; | |
| return 42; | |
| } | |
| #pragma GCC diagnostic pop | |
| template<class T> | |
| constexpr std::string_view name_of_type = [](auto*){ | |
| auto str = std::string_view{__PRETTY_FUNCTION__}; | |
| auto pos = str.find('='); | |
| if (pos == decltype(str)::npos) { | |
| throw; | |
| } | |
| if (str.size() < pos + 3) { | |
| throw; | |
| } | |
| return str.substr(pos + 2, str.size() - pos - 3); | |
| }(static_cast<T*>(nullptr)); | |
| template<class T> | |
| inline const void* type_ident = [] { | |
| static constexpr const T* val = nullptr; | |
| return &val; | |
| }(); | |
| template<class T> | |
| struct XXX { | |
| constexpr static bool b = false; | |
| }; | |
| template<class T> | |
| constexpr inline const void* type_ident_2 = &XXX<T>::b; | |
| namespace { | |
| struct A {}; | |
| } // namespace | |
| namespace X { | |
| namespace { | |
| struct B{}; | |
| } // namespace | |
| } // namespace X | |
| static_assert(name_of_type<void> == "void"); | |
| static_assert(name_of_type<vector<int>> == "std::vector<int>"); | |
| template <class T> | |
| [[nodiscard]] __attribute__((visibility("hidden"))) constexpr auto safe_to_cstr(T x) noexcept { | |
| static_assert(std::is_integral_v<T>); | |
| auto res = std::array<char, std::is_signed_v<T> + sizeof(x) * 3 + 1>{}; | |
| unsigned i = 0; | |
| unsigned rev = res.size(); | |
| if (std::is_signed_v<T> && x < 0) { | |
| res[i++] = '-'; | |
| res[--rev] = '0' - static_cast<char>(x % 10); | |
| x /= -10; | |
| if (x == 0) { | |
| res[1] = res[rev]; | |
| res[2] = '\0'; | |
| return res; | |
| } | |
| } | |
| do { | |
| res[--rev] = static_cast<char>(x % 10) + '0'; | |
| x /= 10; | |
| } while (x != 0); | |
| while (rev < res.size()) { | |
| res[i++] = res[rev++]; | |
| } | |
| res[i] = '\0'; | |
| return res; | |
| } | |
| static_assert(-30 / -10 == 3); | |
| static_assert(-3 % 10 == -3); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<unsigned char>(0)).data()} == "0"); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<unsigned char>(7)).data()} == "7"); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<unsigned char>(12)).data()} == "12"); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<unsigned char>(123)).data()} == "123"); | |
| static_assert(safe_to_cstr(static_cast<char>(-42))[0] == '-'); | |
| static_assert(safe_to_cstr(static_cast<char>(-42))[1] == '4'); | |
| static_assert(safe_to_cstr(static_cast<char>(-42))[2] == '2'); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<char>(-42)).data()} == "-42"); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<int>(-4)).data()} == "-4"); | |
| static_assert(std::string_view{safe_to_cstr(static_cast<int>(-0)).data()} == "0"); | |
| template<size_t N> | |
| struct Bar { | |
| Bar() { | |
| cerr << "Bar::Bar()" << endl; | |
| } | |
| template<size_t M> | |
| Bar(const Bar<M>& other) { | |
| cerr << "Bar::Bar(Bar<M>)" << endl; | |
| } | |
| Bar(const Bar& other) { | |
| cerr << "Bar::Bar(const Bar&)" << endl; | |
| } | |
| Bar(Bar&&) = delete; | |
| }; | |
| struct NNN : private std::string {}; | |
| int main(int argc, char** argv) { | |
| std::cerr << name_of_type<std::vector<int>> << endl; | |
| cerr << name_of_type<vector<int>> << endl; | |
| cerr << name_of_type<int> << endl; | |
| cerr << name_of_type<void> << endl; | |
| cerr << name_of_type<int*> << endl; | |
| cerr << name_of_type<vector<int const&>> << endl; | |
| cerr << name_of_type<A> << endl; | |
| cerr << name_of_type<X::B> << endl; | |
| cerr << type_ident<int> << std::endl; | |
| cerr << type_ident<void> << std::endl; | |
| cerr << type_ident<vector<int>*> << std::endl; | |
| cerr << sizeof(void*) << endl; | |
| const void* x = type_ident<int>; | |
| const void* pp = &x; | |
| const char* p = static_cast<const char*>(pp); | |
| cerr << type_ident_2<void> << endl; | |
| cerr << type_ident_2<int> << endl; | |
| cerr << type_ident_2<vector<int>> << endl; | |
| auto f = [&](int, auto...) {}; | |
| cerr << name_of_type<decltype(f)> << endl; | |
| cerr << std::string(1000, 'x').capacity() << endl; | |
| Bar<2> bx; | |
| Bar<2> by = bx; | |
| } | |
| struct Custom { | |
| explicit Custom(size_t n) {} | |
| }; | |
| template<size_t... Idx> | |
| auto bar(const std::index_sequence<Idx...>&) { | |
| return std::array{Custom{Idx}...}; | |
| } | |
| template<size_t N> | |
| void oooo() { | |
| auto arr = bar(std::make_index_sequence<5>{}); | |
| } | |
| struct Foo { | |
| Foo(std::string_view a) noexcept {} | |
| template<size_t M> | |
| Foo(const char (&)[M]) noexcept {} | |
| }; | |
| void fffooo() { | |
| Foo{""}; | |
| Foo{std::string{"abc"}}; | |
| Foo{static_cast<const char*>("xxxx")}; | |
| Foo{"yyyyyyy"}; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment