type_name.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_TYPE_NAME_HPP_INCLUDED
5 #define LEXY_DETAIL_TYPE_NAME_HPP_INCLUDED
6 
11 
12 namespace lexy::_detail
13 {
14 template <typename T>
15 using _detect_name_f = std::enable_if_t<std::is_convertible_v<decltype(T::name()), string_view>>;
16 template <typename T>
17 using _detect_name_v = decltype(T::name);
18 
19 template <typename T>
20 constexpr auto _full_type_name()
21 {
22 #if defined(__clang__)
23 # define LEXY_HAS_AUTOMATIC_TYPE_NAME 1
24 # define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME 1
25 
26  constexpr auto prefix = string_view("auto lexy::_detail::_full_type_name() [T = ");
27  constexpr auto suffix = string_view("]");
28 
29  auto function = string_view(__PRETTY_FUNCTION__);
30  function.remove_prefix(prefix.length());
31  function.remove_suffix(suffix.length());
32  return function;
33 
34 #elif defined(__GNUC__)
35 # define LEXY_HAS_AUTOMATIC_TYPE_NAME 1
36 # if __GNUC__ > 8
37 # define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME 1
38 # else
39 # define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME 0
40 # endif
41 
42  constexpr auto prefix
43  = string_view("constexpr auto lexy::_detail::_full_type_name() [with T = ");
44  constexpr auto suffix = string_view("]");
45 
46  auto function = string_view(__PRETTY_FUNCTION__);
47  function.remove_prefix(prefix.length());
48  function.remove_suffix(suffix.length());
49  return function;
50 
51 #elif defined(_MSC_VER)
52 # define LEXY_HAS_AUTOMATIC_TYPE_NAME 1
53 # define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME 1
54 
55  constexpr auto prefix = string_view("auto __cdecl lexy::_detail::_full_type_name<");
56  constexpr auto suffix = string_view(">(void)");
57 
58  auto function = string_view(__FUNCSIG__);
59  function.remove_prefix(prefix.length());
60  function.remove_suffix(suffix.length());
61 
62  if (auto s = string_view("struct "); function.starts_with(s))
63  function.remove_prefix(s.length());
64  else if (auto c = string_view("class "); function.starts_with(c))
65  function.remove_prefix(c.length());
66 
67  return function;
68 
69 #else
70 # define LEXY_HAS_AUTOMATIC_TYPE_NAME 0
71 # define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME 0
72 
73  return string_view("unknown-type");
74 
75 #endif
76 }
77 
78 template <typename T, int NsCount>
80 {
81  auto name = _full_type_name<T>();
82  if (name.find('<') != string_view::npos && NsCount != 0)
83  return name;
84 
85  for (auto namespace_count = NsCount; namespace_count > 0; --namespace_count)
86  {
87  auto pos = name.find("::");
88  if (pos == string_view::npos)
89  break;
90  name.remove_prefix(pos + 2);
91  }
92  return name;
93 }
94 
95 template <typename T, int NsCount = 1>
96 constexpr const char* type_name()
97 {
98  if constexpr (_detail::is_detected<_detect_name_f, T>)
99  return T::name();
100  else if constexpr (_detail::is_detected<_detect_name_v, T>)
101  return T::name;
102  else if constexpr (LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME)
103  return make_cstr<_type_name<T, NsCount>>;
104  else
105  return "unknown-type";
106 }
107 
108 template <typename T, int NsCount>
109 inline constexpr const char* _type_id_holder = type_name<T, NsCount>();
110 
111 // Returns a unique address for each type.
112 // For implementation reasons, it also doubles as the pointer to the name.
113 template <typename T, int NsCount = 1>
114 constexpr const char* const* type_id()
115 {
116  if constexpr (_detail::is_detected<_detect_name_v, T> //
117  && !_detail::is_detected<_detect_name_f, T>)
118  {
119  // We can use the address of the static constexpr directly.
120  return &T::name;
121  }
122  else
123  {
124  // We instantiate a variable template with a function unique by type.
125  // As the variable is inline, there should be a single address only.
126  return &_type_id_holder<T, NsCount>;
127  }
128 }
129 } // namespace lexy::_detail
130 
131 #endif // LEXY_DETAIL_TYPE_NAME_HPP_INCLUDED
132 
lexy::_detail::_detect_name_v
decltype(T::name) _detect_name_v
Definition: type_name.hpp:17
detect.hpp
string_view.hpp
config.hpp
lexy::_detail::_full_type_name
constexpr auto _full_type_name()
Definition: type_name.hpp:20
lexy::_detail::_detect_name_f
std::enable_if_t< std::is_convertible_v< decltype(T::name()), string_view > > _detect_name_f
Definition: type_name.hpp:15
lexy::_detail::basic_string_view
Definition: string_view.hpp:17
lexy::_detail::_type_name
constexpr string_view _type_name()
Definition: type_name.hpp:79
LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME
#define LEXY_HAS_CONSTEXPR_AUTOMATIC_TYPE_NAME
lexy::_detail::type_id
constexpr const char *const * type_id()
Definition: type_name.hpp:114
lexy::_detail::_type_id_holder
constexpr const char * _type_id_holder
Definition: type_name.hpp:109
integer_sequence.hpp
lexy::_detail
Definition: any_ref.hpp:12
lexy::_detail::basic_string_view::npos
static constexpr std::size_t npos
Definition: string_view.hpp:108
lexy::_detail::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:184
detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3095
lexy::_detail::type_name
constexpr const char * type_name()
Definition: type_name.hpp:96


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08