y3c-stl 0.3.3
Friendly C++ STL wrapper with automatic stacktrace
Loading...
Searching...
No Matches
typename.h
Go to the documentation of this file.
1#pragma once
2#include "y3c/terminate.h"
3#include <string>
4
5// based on
6// https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c/58331141#58331141
7
8namespace y3c {
9namespace internal {
10namespace type_name {
11template <typename T>
12const char *wrapped_type_name() {
13#if defined(__clang__) || defined(__GNUC__)
14 return __PRETTY_FUNCTION__;
15#elif defined(_MSC_VER)
16 return __FUNCSIG__;
17#else
18 return __func__;
19#endif
20}
21template <typename T>
22const std::string &wrapped_type_name_s() {
23 static const std::string name = wrapped_type_name<T>();
24 return name;
25}
26
27class probe_type;
28const char *const probe_type_name_candidates[] = {
29 "class y3c::internal::type_name::probe_type",
30 "y3c::internal::type_name::probe_type",
31 "probe_type",
32};
33inline const std::string &probe_type_name_used() {
34 static std::string name;
35 if (name.empty()) {
36 for (const char *probe_type_name : probe_type_name_candidates) {
37 if (wrapped_type_name_s<probe_type>().find(probe_type_name) !=
38 std::string::npos) {
39 name = probe_type_name;
40 break;
41 }
42 }
43 if (name.empty()) {
45 "y3c::internal::type_name::probe_type_name_used()",
46 "probe_type_name not found from signature: " +
47 wrapped_type_name_s<probe_type>());
48 }
49 }
50 return name;
51}
52
53inline size_t prefix_size() {
54 return wrapped_type_name_s<probe_type>().find(probe_type_name_used());
55}
56inline size_t suffix_size() {
57 return wrapped_type_name_s<probe_type>().length() - prefix_size() -
58 probe_type_name_used().length();
59}
60} // namespace type_name
61
62template <typename T>
63const std::string &get_type_name() {
64 static std::string name;
65 if (name.empty()) {
66 const std::string &t_name = type_name::wrapped_type_name_s<T>();
69 name = t_name.substr(type_name::prefix_size(),
70 t_name.length() - type_name::prefix_size() -
72 for (std::size_t i = 0;
73 (i = name.find("class ", i)) != std::string::npos; i++) {
74 if (i == 0 || (!std::isalnum(name[i - 1]) && name[i - 1] != '_')) {
75 name = name.replace(i, 6, "");
76 }
77 }
78 for (std::size_t i = 0;
79 (i = name.find("struct ", i)) != std::string::npos; i++) {
80 if (i == 0 || (!std::isalnum(name[i - 1]) && name[i - 1] != '_')) {
81 name = name.replace(i, 7, "");
82 }
83 }
84 }
85 return name;
86}
87} // namespace internal
88} // namespace y3c
const std::string & wrapped_type_name_s()
Definition typename.h:22
const std::string & probe_type_name_used()
Definition typename.h:33
size_t suffix_size()
Definition typename.h:56
size_t prefix_size()
Definition typename.h:53
const char *const probe_type_name_candidates[]
Definition typename.h:28
const char * wrapped_type_name()
Definition typename.h:12
const std::string & get_type_name()
Definition typename.h:63
void terminate_internal(std::string func, std::string what, skip_trace_tag={})
Definition terminate.h:142
Definition array.h:8
#define y3c_assert_internal(cond)
Definition terminate.h:148