-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpretty_name.h
100 lines (84 loc) · 3.55 KB
/
pretty_name.h
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef COOL_PRETTY_NAME_H_
#define COOL_PRETTY_NAME_H_
#include <string_view>
namespace cool
{
///////////////////////////////////////////////////////////////////////////
// pretty_name
//
// template<typename T> pretty_name(T&&)
// pretty_name is a function template that encapsulates the human readable
// name of the (static) type deduced, after the top level const/volatile
// and reference qualifiers are removed.
//
// pretty_type
//
// template<typename T> pretty_type()
// pretty_type is a function template that encapsulates the human readable
// name of the type specified.
//
// pretty_ref
//
// template<typename T> pretty_ref(T&&)
// pretty_lref is a function template that encapsulates the human readable
// name of the (static) type deduced. The result is always
// reference-qualified.
//
// This shows the reference type that forward<T> returns.
//
// pretty_lref
//
// template<typename T> pretty_lref(T&&)
// pretty_lref is a function template that encapsulates the human readable
// name of the (static) type deduced. The result is reference-qualified
// if and only if an l-value reference is passed in.
//
// This is primarily used to show how forwarding references are deduced.
//
///////////////////////////////////////////////////////////////////////////
namespace detail
{
///////////////////////////////////////////////////////////////////////
// pretty_fn<T>
//
// Helper function to return __PRETTY_FUNCTION__ containing
// "T = type". This is necessary because starting with gcc10 template
// aliases are also expanded in __PRETTY_FUNCTION__, so it would
// be more complicated to return a string_view (which is really
// basic_string_view<char, char_traits<char>>) than a const char*
///////////////////////////////////////////////////////////////////////
template<typename T>
constexpr const char* pretty_fn() noexcept
{ return __PRETTY_FUNCTION__; }
///////////////////////////////////////////////////////////////////////
// pretty_type_sv
//
// Helper function to parse the result of pretty_fn<T>() for the human
// readable name for T.
///////////////////////////////////////////////////////////////////////
inline constexpr std::string_view pretty_type_sv(const char*&& pf) noexcept
{
std::string_view pt(pf);
constexpr std::string_view pattern{"T = "};
pt.remove_prefix(pt.find(pattern) + pattern.size());
pt.remove_suffix(sizeof ']');
return pt;
}
} // detail namespace
template<typename T>
constexpr std::string_view pretty_type() noexcept
{ return detail::pretty_type_sv(detail::pretty_fn<T>()); }
template<typename T>
constexpr std::string_view pretty_lref(T&&) noexcept
{ return detail::pretty_type_sv(detail::pretty_fn<T>()); }
template<typename T>
constexpr std::string_view pretty_ref(T&&) noexcept
{ return detail::pretty_type_sv(detail::pretty_fn<T&&>()); }
template<typename T>
constexpr std::string_view pretty_name(const volatile T&) noexcept
{ return detail::pretty_type_sv(detail::pretty_fn<T>()); }
template<typename T>
constexpr std::string_view pretty_name(const volatile T&&) noexcept
{ return detail::pretty_type_sv(detail::pretty_fn<T>()); }
} // cool namespace
#endif /* COOL_PRETTY_NAME_H_ */