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