use runtime function to pretty print type name
This commit is contained in:
		
							parent
							
								
									492a0f3c55
								
							
						
					
					
						commit
						daeda942ad
					
				|  | @ -15,5 +15,7 @@ signed main() { | |||
|   dbg(vector<pair<int, vector<string>>>{{3,{"hi"}},{4,{"hello", "world"}}}); | ||||
|   dbg(set<int>{3,1,4}); | ||||
|   dbg(map<int, string>{{3,"three"},{1,"one"}}); | ||||
|   dbg(unordered_map<int, string>{{3,"three"},{1,"one"}}); | ||||
|   dbg(unordered_set<int>{3,1,4}); | ||||
|   cout << "hi\n"; | ||||
| } | ||||
|  |  | |||
|  | @ -17,6 +17,12 @@ | |||
| #include <sstream> | ||||
| #include <stdexcept> | ||||
| 
 | ||||
| #ifdef __GNUG__ | ||||
| #include <cstdlib> | ||||
| #include <memory> | ||||
| #include <cxxabi.h> | ||||
| #endif | ||||
| 
 | ||||
| #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) | ||||
| #include <unistd.h> | ||||
| #endif | ||||
|  | @ -28,102 +34,63 @@ namespace soi { | |||
| namespace detail { | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| // detecting the type name: https://stackoverflow.com/a/20170989
 | ||||
| // pretty printing the type name
 | ||||
| 
 | ||||
| #ifndef _MSC_VER | ||||
| #if __cplusplus < 201103 | ||||
| #define CONSTEXPR11_TN | ||||
| #define CONSTEXPR14_TN | ||||
| #define NOEXCEPT_TN | ||||
| #elif __cplusplus < 201402 | ||||
| #define CONSTEXPR11_TN constexpr | ||||
| #define CONSTEXPR14_TN | ||||
| #define NOEXCEPT_TN noexcept | ||||
| #else | ||||
| #define CONSTEXPR11_TN constexpr | ||||
| #define CONSTEXPR14_TN constexpr | ||||
| #define NOEXCEPT_TN noexcept | ||||
| #endif | ||||
| #else // _MSC_VER
 | ||||
| #if _MSC_VER < 1900 | ||||
| #define CONSTEXPR11_TN | ||||
| #define CONSTEXPR14_TN | ||||
| #define NOEXCEPT_TN | ||||
| #elif _MSC_VER < 2000 | ||||
| #define CONSTEXPR11_TN constexpr | ||||
| #define CONSTEXPR14_TN | ||||
| #define NOEXCEPT_TN noexcept | ||||
| #else | ||||
| #define CONSTEXPR11_TN constexpr | ||||
| #define CONSTEXPR14_TN constexpr | ||||
| #define NOEXCEPT_TN noexcept | ||||
| #endif | ||||
| #endif // _MSC_VER
 | ||||
| 
 | ||||
| class static_string { | ||||
|   const char *const p_; | ||||
|   const std::size_t sz_; | ||||
| 
 | ||||
| public: | ||||
|   typedef const char *const_iterator; | ||||
| 
 | ||||
|   template <std::size_t N> | ||||
|   CONSTEXPR11_TN static_string(const char (&a)[N]) NOEXCEPT_TN : p_(a), | ||||
|                                                                  sz_(N - 1) {} | ||||
| 
 | ||||
|   CONSTEXPR11_TN static_string(const char *p, std::size_t N) NOEXCEPT_TN | ||||
|       : p_(p), | ||||
|         sz_(N) {} | ||||
| 
 | ||||
|   CONSTEXPR11_TN const char *data() const NOEXCEPT_TN { return p_; } | ||||
|   CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN { return sz_; } | ||||
| 
 | ||||
|   CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN { return p_; } | ||||
|   CONSTEXPR11_TN const_iterator end() const NOEXCEPT_TN { return p_ + sz_; } | ||||
| 
 | ||||
|   CONSTEXPR11_TN char operator[](std::size_t n) const { | ||||
|     return n < sz_ ? p_[n] : throw std::out_of_range("static_string"); | ||||
|   } | ||||
| struct string_view | ||||
| { | ||||
|     char const* data; | ||||
|     std::size_t size; | ||||
| }; | ||||
| 
 | ||||
| inline std::ostream &operator<<(std::ostream &os, static_string const &s) { | ||||
|   return os.write(s.data(), s.size()); | ||||
| template<class T> | ||||
| constexpr string_view get_name() | ||||
| { | ||||
|     char const* p = __PRETTY_FUNCTION__; | ||||
|     while (*p++ != '='); | ||||
|     for (; *p == ' '; ++p); | ||||
|     char const* p2 = p; | ||||
|     int count = 1; | ||||
|     for (;;++p2) | ||||
|     { | ||||
|         switch (*p2) | ||||
|         { | ||||
|         case '[': | ||||
|             ++count; | ||||
|             break; | ||||
|         case ']': | ||||
|             --count; | ||||
|             if (!count) | ||||
|                 return {p, std::size_t(p2 - p)}; | ||||
|         } | ||||
|     } | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| template <class T> CONSTEXPR14_TN static_string type_name() { | ||||
|   const int k = sizeof("constexpr soi::detail:: T") / sizeof(char); | ||||
| #ifdef __clang__ | ||||
|   static_string p = __PRETTY_FUNCTION__; | ||||
|   return static_string(p.data() + 31 + k, p.size() - 31 - k - 1); | ||||
| #elif defined(__GNUC__) | ||||
|   static_string p = __PRETTY_FUNCTION__; | ||||
| #if __cplusplus < 201402 | ||||
|   return static_string(p.data() + 36 + k, p.size() - 36 - k - 1); | ||||
| #else | ||||
|   return static_string(p.data() + 46 + k, p.size() - 46 - k - 1); | ||||
| #endif | ||||
| #elif defined(_MSC_VER) | ||||
|   static_string p = __FUNCSIG__; | ||||
|   return static_string(p.data() + 38 + k, p.size() - 38 - k - 7); | ||||
| #endif | ||||
| std::string replace_all(std::string str, const std::string& from, const std::string& to) { | ||||
|     size_t start_pos = 0; | ||||
|     while((start_pos = str.find(from, start_pos)) != std::string::npos) { | ||||
|         str.replace(start_pos, from.length(), to); | ||||
|         start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
 | ||||
|     } | ||||
|     return str; | ||||
| } | ||||
| 
 | ||||
| constexpr bool is_prefix_of(char const *suffix, char const *s) { | ||||
|   return suffix[0] == '\0' || | ||||
|          (suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1)); | ||||
| std::string sanitize_type(std::string s) { | ||||
|   auto f = [&](const char *a, const char *b) { | ||||
|              s = replace_all(std::move(s), a, b); | ||||
|            }; | ||||
|   f("std::", ""); | ||||
|   f("__debug::", ""); | ||||
|   f("__cxx11::", ""); | ||||
|   f("basic_string<char>", "string"); | ||||
|   f("long int", "int"); | ||||
|   return s; | ||||
| } | ||||
| 
 | ||||
| static char const *const type_string = "string"; | ||||
| 
 | ||||
| template <class T> CONSTEXPR14_TN static_string sanitized_type_name() { | ||||
|   CONSTEXPR14_TN static_string t = type_name<T>(); | ||||
|   CONSTEXPR14_TN std::size_t offset = | ||||
|       is_prefix_of("std::__debug::", t.data()) | ||||
|           ? sizeof("std::__debug::") - 1 | ||||
|           : is_prefix_of("std::", t.data()) ? sizeof("std::") - 1 : 0; | ||||
|   return is_prefix_of("std::__cxx11::basic_string<char>", t.data()) | ||||
|              ? static_string(type_string, sizeof(type_string) - 2) | ||||
|              : static_string(t.data() + offset, t.size() - offset); | ||||
| template <class T> std::string sanitized_type_name() { | ||||
|   auto t = get_name<T>(); | ||||
|   return sanitize_type(std::string(t.data, t.size)); | ||||
| } | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
|  | @ -191,7 +158,7 @@ void dbg_init() { dbg_init(are_colors_enabled()); } | |||
| // printer
 | ||||
| 
 | ||||
| template <typename T> | ||||
| T &&dbg_print(T &&value, static_string const &type, char const *file, int line, | ||||
| T &&dbg_print(T &&value, std::string const &type, char const *file, int line, | ||||
|               char const *function_name, char const *expression) { | ||||
|   const T &ref = value; | ||||
|   std::stringstream | ||||
|  | @ -208,7 +175,7 @@ T &&dbg_print(T &&value, static_string const &type, char const *file, int line, | |||
| } | ||||
| 
 | ||||
| template <unsigned int N> | ||||
| auto dbg_print(const char (&msg)[N], static_string const &, char const *file, | ||||
| auto dbg_print(const char (&msg)[N], std::string const &, char const *file, | ||||
|                int line, char const *function_name, char const *expression) | ||||
|     -> decltype(msg) { | ||||
|   std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue