LeviLamina
Loading...
Searching...
No Matches
TypeName.h
1#pragma once
2
3#include <string_view>
4#include <typeinfo>
5
6namespace ll::reflection {
7
8template <class T>
9inline std::string_view getDynamicRawName(T const& value) noexcept {
10 return typeid(value).name();
11}
12
13template <auto f>
14consteval std::string_view getRawName() noexcept {
15#if defined(_MSC_VER)
16 constexpr std::string_view n{__FUNCSIG__};
17 constexpr std::string_view k{"getRawName<"};
18 constexpr std::string_view l{">(void) noexcept"};
19#else
20 constexpr std::string_view n{__PRETTY_FUNCTION__};
21 constexpr std::string_view k{"[T = "};
22 constexpr std::string_view l{"]"};
23#endif
24 constexpr auto p = n.find(k) + k.size();
25
26 return n.substr(p, n.size() - p - l.size());
27}
28
29template <class f>
30consteval std::string_view getRawName() noexcept {
31#if defined(_MSC_VER)
32 constexpr std::string_view n{__FUNCSIG__};
33 constexpr std::string_view k{"getRawName<"};
34 constexpr std::string_view l{">(void) noexcept"};
35#else
36 constexpr std::string_view n{__PRETTY_FUNCTION__};
37 constexpr std::string_view k{"[T = "};
38 constexpr std::string_view l{"]"};
39#endif
40 constexpr auto p = n.find(k) + k.size();
41
42 return n.substr(p, n.size() - p - l.size());
43}
44
45constexpr std::string_view removeTypePrefix(std::string_view s) noexcept {
46 if (s.starts_with("enum ")) {
47 s.remove_prefix(sizeof("enum"));
48 }
49 if (s.starts_with("class ")) {
50 s.remove_prefix(sizeof("class"));
51 }
52 if (s.starts_with("union ")) {
53 s.remove_prefix(sizeof("union"));
54 }
55 if (s.starts_with("struct ")) {
56 s.remove_prefix(sizeof("struct"));
57 }
58 return s;
59}
60
61constexpr std::string_view removeTypeSuffix(std::string_view s) noexcept {
62 auto k = s.find('<');
63 if (k != std::string_view::npos) {
64 return s.substr(0, k);
65 }
66 return s;
67}
68
69constexpr std::string_view removeTypeNamespace(std::string_view s) noexcept {
70 auto k = s.rfind("::", s.find('<'));
71 if (k != std::string_view::npos) {
72 return s.substr(k + 2);
73 }
74 return s;
75}
76
77constexpr std::string_view typeNameStem(std::string_view s) noexcept {
78 return removeTypeNamespace(removeTypeSuffix(removeTypePrefix(s)));
79}
80
81
82template <class T>
83constexpr std::string_view type_raw_name_v = getRawName<T>();
84
85template <class T>
86constexpr std::string_view type_unprefix_name_v = removeTypePrefix(type_raw_name_v<T>);
87
88template <class T>
89constexpr std::string_view type_name_v = removeTypeSuffix(type_unprefix_name_v<T>);
90
91template <class T>
92constexpr std::string_view type_stem_name_v = removeTypeNamespace(type_name_v<T>);
93
94template <class T>
95constexpr bool is_template_v = type_raw_name_v<T>.find("<") != std::string_view::npos;
96
97template <class T>
98constexpr bool is_class_v = std::is_class_v<T> && type_raw_name_v<T>.starts_with("class ");
99
100template <class T>
101constexpr bool is_struct_v = std::is_class_v<T> && type_raw_name_v<T>.starts_with("struct ");
102} // namespace ll::reflection