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(vector<pair<int, vector<string>>>{{3,{"hi"}},{4,{"hello", "world"}}});
|
||||||
dbg(set<int>{3,1,4});
|
dbg(set<int>{3,1,4});
|
||||||
dbg(map<int, string>{{3,"three"},{1,"one"}});
|
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";
|
cout << "hi\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,102 +34,63 @@ namespace soi {
|
||||||
namespace detail {
|
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 {
|
struct string_view
|
||||||
const char *const p_;
|
{
|
||||||
const std::size_t sz_;
|
char const* data;
|
||||||
|
std::size_t size;
|
||||||
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");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, static_string const &s) {
|
template<class T>
|
||||||
return os.write(s.data(), s.size());
|
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() {
|
std::string replace_all(std::string str, const std::string& from, const std::string& to) {
|
||||||
const int k = sizeof("constexpr soi::detail:: T") / sizeof(char);
|
size_t start_pos = 0;
|
||||||
#ifdef __clang__
|
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||||
static_string p = __PRETTY_FUNCTION__;
|
str.replace(start_pos, from.length(), to);
|
||||||
return static_string(p.data() + 31 + k, p.size() - 31 - k - 1);
|
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
|
||||||
#elif defined(__GNUC__)
|
}
|
||||||
static_string p = __PRETTY_FUNCTION__;
|
return str;
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool is_prefix_of(char const *suffix, char const *s) {
|
std::string sanitize_type(std::string s) {
|
||||||
return suffix[0] == '\0' ||
|
auto f = [&](const char *a, const char *b) {
|
||||||
(suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1));
|
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> std::string sanitized_type_name() {
|
||||||
|
auto t = get_name<T>();
|
||||||
template <class T> CONSTEXPR14_TN static_string sanitized_type_name() {
|
return sanitize_type(std::string(t.data, t.size));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -191,7 +158,7 @@ void dbg_init() { dbg_init(are_colors_enabled()); }
|
||||||
// printer
|
// printer
|
||||||
|
|
||||||
template <typename T>
|
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) {
|
char const *function_name, char const *expression) {
|
||||||
const T &ref = value;
|
const T &ref = value;
|
||||||
std::stringstream
|
std::stringstream
|
||||||
|
@ -208,7 +175,7 @@ T &&dbg_print(T &&value, static_string const &type, char const *file, int line,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned int N>
|
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)
|
int line, char const *function_name, char const *expression)
|
||||||
-> decltype(msg) {
|
-> decltype(msg) {
|
||||||
std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name
|
std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name
|
||||||
|
|
Loading…
Reference in New Issue