-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtext_function_detail.h
More file actions
70 lines (56 loc) · 2.01 KB
/
text_function_detail.h
File metadata and controls
70 lines (56 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma once
#include <regex>
#include <stdexcept>
#include <string>
#include <cxxabi.h>
namespace txtfn {
namespace detail {
template <typename T> struct remove_class { };
template <typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...)> { using type = R(A...); };
template <typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const> { using type = R(A...); };
template <typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) volatile> { using type = R(A...); };
template <typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const volatile> { using type = R(A...); };
template <typename T>
struct get_signature_impl { using type = typename remove_class<
decltype(&std::remove_reference<T>::type::operator())>::type; };
template <typename R, typename... A>
struct get_signature_impl<R(A...)> { using type = R(A...); };
template <typename R, typename... A>
struct get_signature_impl<R(&)(A...)> { using type = R(A...); };
template <typename R, typename... A>
struct get_signature_impl<R(*)(A...)> { using type = R(A...); };
template <typename T> using get_signature = typename get_signature_impl<T>::type;
template <class T>
const std::string& demangle_i() {
const static std::string name = [] {
int status = 0;
const char* name = typeid(T).name();
char* good_name = abi::__cxa_demangle(name, nullptr, nullptr, &status);
if (status != 0 || good_name == nullptr) {
if (good_name != nullptr) {
free(good_name);
}
throw std::runtime_error(std::string("Unable to demangle: ") + name);
}
const std::string str_name(good_name);
free(good_name);
return str_name;
}();
return name;
}
template <class T>
const std::string& demangle() {
const static std::string name = [] {
const auto& demangled = demangle_i<T>();
const auto& str = demangle_i<std::string>();
// Cleans up std::string output
return std::regex_replace(demangled, std::regex(str), "std::string");
}();
return name;
}
}
}